ÿØÿàJFIFÿþ ÿÛC       ÿÛC ÿÀÿÄÿÄ"#QrÿÄÿÄ&1!A"2qQaáÿÚ ?Øy,æ/3JæÝ¹È߲؋5êXw²±ÉyˆR”¾I0ó2—PI¾IÌÚiMö¯–þrìN&"KgX:Šíµ•nTJnLK„…@!‰-ý ùúmë;ºgµŒ&ó±hw’¯Õ@”Ü— 9ñ-ë.²1<yà‚¹ïQÐU„ہ?.’¦èûbß±©Ö«Âw*VŒ) `$‰bØÔŸ’ëXÖ-ËTÜíGÚ3ð«g Ÿ§¯—Jx„–’U/ÂÅv_s(Hÿ@TñJÑãõçn­‚!ÈgfbÓc­:él[ðQe 9ÀPLbÃãCµm[5¿ç'ªjglå‡Ûí_§Úõl-;"PkÞÞÁQâ¼_Ñ^¢SŸx?"¸¦ùY騐ÒOÈ q’`~~ÚtËU¹CڒêV  I1Áß_ÿÙ#!/usr/bin/env php '/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_comparator' => '/phpunit/Framework/Comparator.php', 'phpunit_framework_comparator_array' => '/phpunit/Framework/Comparator/Array.php', 'phpunit_framework_comparator_datetime' => '/phpunit/Framework/Comparator/DateTime.php', 'phpunit_framework_comparator_domnode' => '/phpunit/Framework/Comparator/DOMNode.php', 'phpunit_framework_comparator_double' => '/phpunit/Framework/Comparator/Double.php', 'phpunit_framework_comparator_exception' => '/phpunit/Framework/Comparator/Exception.php', 'phpunit_framework_comparator_mockobject' => '/phpunit/Framework/Comparator/MockObject.php', 'phpunit_framework_comparator_numeric' => '/phpunit/Framework/Comparator/Numeric.php', 'phpunit_framework_comparator_object' => '/phpunit/Framework/Comparator/Object.php', 'phpunit_framework_comparator_resource' => '/phpunit/Framework/Comparator/Resource.php', 'phpunit_framework_comparator_scalar' => '/phpunit/Framework/Comparator/Scalar.php', 'phpunit_framework_comparator_splobjectstorage' => '/phpunit/Framework/Comparator/SplObjectStorage.php', 'phpunit_framework_comparator_type' => '/phpunit/Framework/Comparator/Type.php', 'phpunit_framework_comparatorfactory' => '/phpunit/Framework/ComparatorFactory.php', 'phpunit_framework_comparisonfailure' => '/phpunit/Framework/ComparisonFailure.php', 'phpunit_framework_constraint' => '/phpunit/Framework/Constraint.php', 'phpunit_framework_constraint_and' => '/phpunit/Framework/Constraint/And.php', 'phpunit_framework_constraint_arrayhaskey' => '/phpunit/Framework/Constraint/ArrayHasKey.php', 'phpunit_framework_constraint_attribute' => '/phpunit/Framework/Constraint/Attribute.php', 'phpunit_framework_constraint_callback' => '/phpunit/Framework/Constraint/Callback.php', 'phpunit_framework_constraint_classhasattribute' => '/phpunit/Framework/Constraint/ClassHasAttribute.php', 'phpunit_framework_constraint_classhasstaticattribute' => '/phpunit/Framework/Constraint/ClassHasStaticAttribute.php', 'phpunit_framework_constraint_composite' => '/phpunit/Framework/Constraint/Composite.php', 'phpunit_framework_constraint_count' => '/phpunit/Framework/Constraint/Count.php', 'phpunit_framework_constraint_exception' => '/phpunit/Framework/Constraint/Exception.php', 'phpunit_framework_constraint_exceptioncode' => '/phpunit/Framework/Constraint/ExceptionCode.php', 'phpunit_framework_constraint_exceptionmessage' => '/phpunit/Framework/Constraint/ExceptionMessage.php', 'phpunit_framework_constraint_fileexists' => '/phpunit/Framework/Constraint/FileExists.php', 'phpunit_framework_constraint_greaterthan' => '/phpunit/Framework/Constraint/GreaterThan.php', 'phpunit_framework_constraint_isanything' => '/phpunit/Framework/Constraint/IsAnything.php', 'phpunit_framework_constraint_isempty' => '/phpunit/Framework/Constraint/IsEmpty.php', 'phpunit_framework_constraint_isequal' => '/phpunit/Framework/Constraint/IsEqual.php', 'phpunit_framework_constraint_isfalse' => '/phpunit/Framework/Constraint/IsFalse.php', 'phpunit_framework_constraint_isidentical' => '/phpunit/Framework/Constraint/IsIdentical.php', 'phpunit_framework_constraint_isinstanceof' => '/phpunit/Framework/Constraint/IsInstanceOf.php', 'phpunit_framework_constraint_isjson' => '/phpunit/Framework/Constraint/IsJson.php', 'phpunit_framework_constraint_isnull' => '/phpunit/Framework/Constraint/IsNull.php', 'phpunit_framework_constraint_istrue' => '/phpunit/Framework/Constraint/IsTrue.php', 'phpunit_framework_constraint_istype' => '/phpunit/Framework/Constraint/IsType.php', 'phpunit_framework_constraint_jsonmatches' => '/phpunit/Framework/Constraint/JsonMatches.php', 'phpunit_framework_constraint_jsonmatches_errormessageprovider' => '/phpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php', 'phpunit_framework_constraint_lessthan' => '/phpunit/Framework/Constraint/LessThan.php', 'phpunit_framework_constraint_not' => '/phpunit/Framework/Constraint/Not.php', 'phpunit_framework_constraint_objecthasattribute' => '/phpunit/Framework/Constraint/ObjectHasAttribute.php', 'phpunit_framework_constraint_or' => '/phpunit/Framework/Constraint/Or.php', 'phpunit_framework_constraint_pcrematch' => '/phpunit/Framework/Constraint/PCREMatch.php', 'phpunit_framework_constraint_samesize' => '/phpunit/Framework/Constraint/SameSize.php', 'phpunit_framework_constraint_stringcontains' => '/phpunit/Framework/Constraint/StringContains.php', 'phpunit_framework_constraint_stringendswith' => '/phpunit/Framework/Constraint/StringEndsWith.php', 'phpunit_framework_constraint_stringmatches' => '/phpunit/Framework/Constraint/StringMatches.php', 'phpunit_framework_constraint_stringstartswith' => '/phpunit/Framework/Constraint/StringStartsWith.php', 'phpunit_framework_constraint_traversablecontains' => '/phpunit/Framework/Constraint/TraversableContains.php', 'phpunit_framework_constraint_traversablecontainsonly' => '/phpunit/Framework/Constraint/TraversableContainsOnly.php', 'phpunit_framework_constraint_xor' => '/phpunit/Framework/Constraint/Xor.php', 'phpunit_framework_error' => '/phpunit/Framework/Error.php', 'phpunit_framework_error_deprecated' => '/phpunit/Framework/Error/Deprecated.php', 'phpunit_framework_error_notice' => '/phpunit/Framework/Error/Notice.php', 'phpunit_framework_error_warning' => '/phpunit/Framework/Error/Warning.php', 'phpunit_framework_exception' => '/phpunit/Framework/Exception.php', 'phpunit_framework_expectationfailedexception' => '/phpunit/Framework/ExpectationFailedException.php', 'phpunit_framework_incompletetest' => '/phpunit/Framework/IncompleteTest.php', 'phpunit_framework_incompletetesterror' => '/phpunit/Framework/IncompleteTestError.php', 'phpunit_framework_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_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\\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.0.17.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(); ?> Cphpunit-4.0.17.pharAphpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.php TS #j{5Aphpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.phpe TSe M#=phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php TS Á<phpunit-mock-objects/Framework/MockObject/Stub/Exception.phpX TSX ȝ>nAphpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.php TS '޶Dphpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php TS  9phpunit-mock-objects/Framework/MockObject/Stub/Return.php TS Cphpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.php TS #|?phpunit-mock-objects/Framework/MockObject/Invocation/Object.php TS a|¶?phpunit-mock-objects/Framework/MockObject/Invocation/Static.phptTSt>gHphpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php/ TS/ mrَIphpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.phpTS7gBphpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.phpTS92Ephpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.phpA TSA tM8@phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.phpeTSe̸Cphpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.php TS e@phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.phpTS>~@phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.phpBTSB`5hDphpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.phpuTSua Ephpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.phpTS; =P8phpunit-mock-objects/Framework/MockObject/Verifiable.php TS &nEphpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.phpaTSa#$ >phpunit-mock-objects/Framework/MockObject/Builder/Identity.php TS Nts;phpunit-mock-objects/Framework/MockObject/Builder/Match.php TS ڂ:phpunit-mock-objects/Framework/MockObject/Builder/Stub.php TS t Fphpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.php#TS#@5?phpunit-mock-objects/Framework/MockObject/Builder/Namespace.phpTScaEphpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php TS 7phpunit-mock-objects/Framework/MockObject/Exception.php TS ͚5phpunit-mock-objects/Framework/MockObject/Matcher.php(TS(L9phpunit-mock-objects/Framework/MockObject/MockBuilder.php%TS% d8phpunit-mock-objects/Framework/MockObject/Invocation.php TS a?7phpunit-mock-objects/Framework/MockObject/Generator.phpTS(t8phpunit-mock-objects/Framework/MockObject/MockObject.php>TS>A2phpunit-mock-objects/Framework/MockObject/Stub.php TS Y>phpunit-mock-objects/Framework/MockObject/InvocationMocker.php{TS{h7phpunit-mock-objects/Framework/MockObject/Invokable.php TS ]Jphpunit-mock-objects/Framework/MockObject/Generator/mocked_method.tpl.distTSbVHphpunit-mock-objects/Framework/MockObject/Generator/trait_class.tpl.dist7TS7[$~Gphpunit-mock-objects/Framework/MockObject/Generator/wsdl_class.tpl.distTSw&SKphpunit-mock-objects/Framework/MockObject/Generator/proxied_method.tpl.distTSHKphpunit-mock-objects/Framework/MockObject/Generator/unmocked_clone.tpl.distTS8W}ضPphpunit-mock-objects/Framework/MockObject/Generator/mocked_class_method.tpl.distTS4޶Iphpunit-mock-objects/Framework/MockObject/Generator/mocked_class.tpl.dist TS FZIphpunit-mock-objects/Framework/MockObject/Generator/mocked_clone.tpl.distTSaTHphpunit-mock-objects/Framework/MockObject/Generator/wsdl_method.tpl.dist<TS<i!sebastian-environment/Runtime.phpTSjca.pem TS s sebastian-exporter/Exception.php] TS] #1sebastian-exporter/Exporter.php&TS&sebastian-exporter/Context.php(TS(`Ssebastian-version/Version.php TS Y phpunit/Exception.php TS *phpunit/Framework/Constraint/Composite.phpTS[Lm(phpunit/Framework/Constraint/IsFalse.php% TS% +phpunit/Framework/Constraint/FileExists.php[TS[yF?8phpunit/Framework/Constraint/ClassHasStaticAttribute.php*TS*F*8Aphpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.phpTS 'phpunit/Framework/Constraint/IsType.phpTSF)phpunit/Framework/Constraint/LessThan.phpn TSn `*phpunit/Framework/Constraint/PCREMatch.phpjTSj1#׶,phpunit/Framework/Constraint/JsonMatches.php<TS<t#phpunit/Framework/Constraint/Or.php{TS{oc2phpunit/Framework/Constraint/ClassHasAttribute.phpdTSdX,2phpunit/Framework/InvalidCoversTargetException.php TS ں&phpunit/Framework/SkippedTestError.php/ TS/ &ֳ phpunit/Framework/Constraint.php TS &Ophpunit/Framework/Assert.phpqTSqԔ"phpunit/Framework/TestListener.phpsTSsB.phpunit/Framework/InvalidCoversTargetError.phph TSh ޶phpunit/Framework/Exception.php TS |$phpunit/Framework/RiskyTestError.php) TS) y+phpunit/Framework/CodeCoverageException.php TS 5&^$phpunit/Framework/IncompleteTest.php TS 8&phpunit/Framework/Assert/Functions.phpdTSdhdc$phpunit/Framework/SelfDescribing.php< TS< l!phpunit/Framework/TestFailure.phpTSr,phpunit/Framework/TestSuite/DataProvider.php TS T`!phpunit/Framework/SkippedTest.php TS K9$phpunit/Framework/SyntheticError.phpATSA/3'phpunit/Framework/ComparisonFailure.phpHTSHHN&phpunit/Framework/Error/Deprecated.phpx TSx 9*#phpunit/Framework/Error/Warning.phpe TSe 0fl"phpunit/Framework/Error/Notice.phpb TSb ֶ)phpunit/Framework/IncompleteTestError.php9 TS9 #Y0phpunit/Framework/ExpectationFailedException.php TS 6 phpunit/Framework/TestResult.phptTSt{zphpunit/Framework/RiskyTest.php TS 7phpunit/Framework/Error.php8 TS8 nV phpunit/Framework/Comparator.phpTS8Kphpunit/Framework/TestSuite.phpiTSiaphpunit/Framework/TestCase.phpqTSq8Vphp-invoker/Invoker.php&TS&-顶(php-invoker/Invoker/TimeoutException.php TS n)dbunit/Extensions/Database/DB/DataSet.phpTS`Wk/dbunit/Extensions/Database/DB/TableMetaData.php TS K/dbunit/Extensions/Database/DB/TableIterator.phpTSl<dbunit/Extensions/Database/DB/MetaData/InformationSchema.phptTStö0dbunit/Extensions/Database/DB/MetaData/Dblib.php TS {ڧ1dbunit/Extensions/Database/DB/MetaData/Sqlite.php>TS>=^ف0dbunit/Extensions/Database/DB/MetaData/MySQL.phpTS01dbunit/Extensions/Database/DB/MetaData/SqlSrv.phpTS0 3dbunit/Extensions/Database/DB/MetaData/Firebird.phpTSBp0dbunit/Extensions/Database/DB/MetaData/PgSQL.phpTSgĶ.dbunit/Extensions/Database/DB/MetaData/Oci.phpVTSV+ E0dbunit/Extensions/Database/DB/ResultSetTable.php TS [1dbunit/Extensions/Database/DB/FilteredDataSet.phpM TSM *dbunit/Extensions/Database/DB/MetaData.phpL TSL !!;dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php TS ʉ1'dbunit/Extensions/Database/DB/Table.php TS s55dbunit/Extensions/Database/DB/IDatabaseConnection.phpTSD+dbunit/Extensions/Database/DB/IMetaData.php6TS6vi4dbunit/Extensions/Database/IDatabaseListConsumer.phpA TSA SӶ8dbunit/Extensions/Database/Constraint/DataSetIsEqual.phprTSrT(7dbunit/Extensions/Database/Constraint/TableRowCount.phpc TSc +/6dbunit/Extensions/Database/Constraint/TableIsEqual.phpdTSdNjǶ-dbunit/Extensions/Database/AbstractTester.php$TS$Q(dbunit/Extensions/Database/Exception.php TS x !5dbunit/Extensions/Database/DataSet/FlatXmlDataSet.phpVTSVN@Զ9dbunit/Extensions/Database/DataSet/Persistors/Factory.phpTS[̶:dbunit/Extensions/Database/DataSet/Persistors/Abstract.phpTS75dbunit/Extensions/Database/DataSet/Persistors/Xml.phpTSw:6dbunit/Extensions/Database/DataSet/Persistors/Yaml.phpTSn:dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.phpTSf]-9dbunit/Extensions/Database/DataSet/Persistors/FlatXml.phpjTSj_2dbunit/Extensions/Database/DataSet/IYamlParser.php TS Cp/dbunit/Extensions/Database/DataSet/IDataSet.php TS -oB:dbunit/Extensions/Database/DataSet/TableMetaDataFilter.php*TS* ۶7dbunit/Extensions/Database/DataSet/CompositeDataSet.phpTSN=<dbunit/Extensions/Database/DataSet/AbstractTableMetaData.phpTS5dbunit/Extensions/Database/DataSet/ITableMetaData.php8 TS8 qjY2dbunit/Extensions/Database/DataSet/YamlDataSet.phpTSL1dbunit/Extensions/Database/DataSet/QueryTable.phpTS!;dbunit/Extensions/Database/DataSet/DefaultTableMetaData.php TS 3dbunit/Extensions/Database/DataSet/QueryDataSet.phpoTSo1Г8dbunit/Extensions/Database/DataSet/SymfonyYamlParser.php TS n| -dbunit/Extensions/Database/DataSet/ITable.php TS 95dbunit/Extensions/Database/DataSet/ITableIterator.php TS "h7dbunit/Extensions/Database/DataSet/ReplacementTable.php3TS3`藶3dbunit/Extensions/Database/DataSet/DefaultTable.phpTS2F6dbunit/Extensions/Database/DataSet/AbstractDataSet.phpTS[96dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.php/TS/8o4dbunit/Extensions/Database/DataSet/AbstractTable.phpW!TSW!|0dbunit/Extensions/Database/DataSet/Specs/Csv.phpaTSa=Kj4dbunit/Extensions/Database/DataSet/Specs/DbTable.phpTSJ4dbunit/Extensions/Database/DataSet/Specs/Factory.php TS >30dbunit/Extensions/Database/DataSet/Specs/Xml.php TS )5T1dbunit/Extensions/Database/DataSet/Specs/Yaml.php TS SD\4dbunit/Extensions/Database/DataSet/Specs/FlatXml.php TS .4dbunit/Extensions/Database/DataSet/Specs/DbQuery.phpTS5v5dbunit/Extensions/Database/DataSet/Specs/IFactory.phpQ TSQ f4dbunit/Extensions/Database/DataSet/DataSetFilter.phpTS_ƴ2dbunit/Extensions/Database/DataSet/TableFilter.phpTS*E1dbunit/Extensions/Database/DataSet/XmlDataSet.phpTSLNȶ?dbunit/Extensions/Database/DataSet/ReplacementTableIterator.phpTSB! 5dbunit/Extensions/Database/DataSet/DefaultDataSet.php TS kr9dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.phptTSt3!;dbunit/Extensions/Database/DataSet/DefaultTableIterator.phpTSr1dbunit/Extensions/Database/DataSet/CsvDataSet.phpTS/0(9dbunit/Extensions/Database/DataSet/ReplacementDataSet.php`TS`ք3dbunit/Extensions/Database/DataSet/IPersistable.php TS ,dbunit/Extensions/Database/DataSet/ISpec.php TS fC&dbunit/Extensions/Database/ITester.phpTSo,dbunit/Extensions/Database/DefaultTester.php TS :1dbunit/Extensions/Database/Operation/Truncate.php TS p0dbunit/Extensions/Database/Operation/Factory.phpTSt¶;dbunit/Extensions/Database/Operation/IDatabaseOperation.php TS f/dbunit/Extensions/Database/Operation/Insert.phpTS-dbunit/Extensions/Database/Operation/Null.php TS I90dbunit/Extensions/Database/Operation/Replace.phpfTSf8w@/dbunit/Extensions/Database/Operation/Update.phpTS2dbunit/Extensions/Database/Operation/Exception.phpTS1dbunit/Extensions/Database/Operation/RowBased.php*TS*+*Ҷ2dbunit/Extensions/Database/Operation/DeleteAll.php TS l+2dbunit/Extensions/Database/Operation/Composite.phpTS9$ /dbunit/Extensions/Database/Operation/Delete.phpTS2_Ͷ.dbunit/Extensions/Database/UI/Mediums/Text.phpTS2Zv)dbunit/Extensions/Database/UI/IMedium.phpY TSY 1)dbunit/Extensions/Database/UI/Command.phpR TSR !B.dbunit/Extensions/Database/UI/IModeFactory.php TS F$-dbunit/Extensions/Database/UI/ModeFactory.php)TS)X'dbunit/Extensions/Database/UI/IMode.php TS 6dbunit/Extensions/Database/UI/InvalidModeException.php TS )dbunit/Extensions/Database/UI/Context.php TS c$'dbunit/Extensions/Database/TestCase.php(%TS(%s0php-token-stream/Token/Stream/CachingFactory.php TS Ӓն!php-token-stream/Token/Stream.phpuDTSuDrSͶphp-token-stream/Token.php\TS\C2}"php-code-coverage/CodeCoverage.phpkjTSkj3Y)php-code-coverage/CodeCoverage/Driver.php TS !MfT0php-code-coverage/CodeCoverage/Driver/Xdebug.phpTSaR.php-code-coverage/CodeCoverage/Driver/HHVM.php TS o4,php-code-coverage/CodeCoverage/Exception.php TS x'1php-code-coverage/CodeCoverage/Report/Factory.phpeTSe.php-code-coverage/CodeCoverage/Report/Text.php)TS)90php-code-coverage/CodeCoverage/Report/Clover.php0TS0sԶ.php-code-coverage/CodeCoverage/Report/Node.phpm%TSm%!z20php-code-coverage/CodeCoverage/Report/Crap4j.phpTSRkAphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Dashboard.php-TS-HAphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Directory.phpTSSUphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist5TS5Z]Kphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file.html.dist TS wcphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.eotoOTSoOqdphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff[TS[\ζcphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.ttf@TS@cphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.svgTSL3APphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.distTSBɲSphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist1TS1itLPphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.distgTSgV PPphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory.html.distYTSYʲrJphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/style.css TS MR#Rphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.cssyTSyFJphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/nv.d3.css#2TS#2 bIphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/holder.js^NTS^N'ULphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/html5shiv.js| TS| 2YnPphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.jsqTSq Nphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/respond.min.jsTS{Iphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/d3.min.jst=TSt=fIphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.js|xTS|xLphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/nv.d3.min.jsTSK&Rphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/method_item.html.distxTSx*<php-code-coverage/CodeCoverage/Report/HTML/Renderer/File.phpnPTSnPK7php-code-coverage/CodeCoverage/Report/HTML/Renderer.php&TS&~v-php-code-coverage/CodeCoverage/Report/XML.php#TS#8php-code-coverage/CodeCoverage/Report/Node/Directory.php0TS0N7php-code-coverage/CodeCoverage/Report/Node/Iterator.phpTS-x3php-code-coverage/CodeCoverage/Report/Node/File.php\PTS\Pv.php-code-coverage/CodeCoverage/Report/HTML.phpTS5php-code-coverage/CodeCoverage/Report/XML/Project.phpuTSu#Ǯ4php-code-coverage/CodeCoverage/Report/XML/Totals.phpTSg7php-code-coverage/CodeCoverage/Report/XML/Directory.php TS Mٶ02php-code-coverage/CodeCoverage/Report/XML/Node.phpzTSz3php-code-coverage/CodeCoverage/Report/XML/Tests.php TS 2php-code-coverage/CodeCoverage/Report/XML/File.php4TS4*G9php-code-coverage/CodeCoverage/Report/XML/File/Method.php TS ֶ;php-code-coverage/CodeCoverage/Report/XML/File/Coverage.php}TS}$7php-code-coverage/CodeCoverage/Report/XML/File/Unit.php:TS:,Kö9php-code-coverage/CodeCoverage/Report/XML/File/Report.php_TS_Ͷ-php-code-coverage/CodeCoverage/Report/PHP.php{ TS{ mr=php-code-coverage/CodeCoverage/Util/InvalidArgumentHelper.php TS Hp)php-code-coverage/CodeCoverage/Filter.php+TS+gj'php-code-coverage/CodeCoverage/Util.php# TS# $ݶGphp-code-coverage/CodeCoverage/Exception/UnintentionallyCoveredCode.php. TS. se~Tphp-text-template/Template.phpTS;$php-timer/Timer.php6TS6#X6%php-file-iterator/Iterator/Facade.phpTSl&php-file-iterator/Iterator/Factory.phphTShڶphp-file-iterator/Iterator.phpcTSc~ԃ,symfony/yaml/Symfony/Component/Yaml/Yaml.php TS 7MӺ.symfony/yaml/Symfony/Component/Yaml/Inline.php?TS?q+3.symfony/yaml/Symfony/Component/Yaml/Parser.php[TS[X/symfony/yaml/Symfony/Component/Yaml/Escaper.phpm TSm )%,.symfony/yaml/Symfony/Component/Yaml/Dumper.php TS 8n1symfony/yaml/Symfony/Component/Yaml/Unescaper.phpTS6H @symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php TS Bsymfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.phpTS|-?symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.phpTSؙ՚Dsymfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.phpTS+l4phpunit-selenium/Extensions/SeleniumBrowserSuite.phpTSD6phpunit-selenium/Extensions/SeleniumCommon/prepend.php? TS? ?phpunit-selenium/Extensions/SeleniumCommon/phpunit_coverage.php TS ow5phpunit-selenium/Extensions/SeleniumCommon/append.php TS :phpunit-selenium/Extensions/SeleniumCommon/ExitHandler.php*TS*϶=phpunit-selenium/Extensions/SeleniumCommon/RemoteCoverage.php>TS>*dBʶ0phpunit-selenium/Extensions/SeleniumTestCase.phpЖTSЖ`ec7phpunit-selenium/Extensions/SeleniumTestCase/Driver.php^TS^7'q߶1phpunit-selenium/Extensions/Selenium2TestCase.phpkCTSkCmf8phpunit-selenium/Extensions/Selenium2TestCase/Driver.php/TS/z}:phpunit-selenium/Extensions/Selenium2TestCase/Response.phpTSTZ9phpunit-selenium/Extensions/Selenium2TestCase/Session.php/TS/ĶAphpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy.php TS ̳rAphpunit-selenium/Extensions/Selenium2TestCase/ElementCriteria.phpN TSN ¶Hphpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie/Builder.phpTSӸqAphpunit-selenium/Extensions/Selenium2TestCase/Session/Storage.php8 TS8 Bphpunit-selenium/Extensions/Selenium2TestCase/Session/Timeouts.php]TS]/X@phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie.phpTS$!Dphpunit-selenium/Extensions/Selenium2TestCase/WebDriverException.phpf TSf K19phpunit-selenium/Extensions/Selenium2TestCase/Element.phpTS5phpunit-selenium/Extensions/Selenium2TestCase/URL.phpTSHFEphpunit-selenium/Extensions/Selenium2TestCase/NoSeleniumException.php TS k6phpunit-selenium/Extensions/Selenium2TestCase/Keys.phpITSIͶJphpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php TS ͶHphpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Shared.phpHTSHVmBphpunit-selenium/Extensions/Selenium2TestCase/Element/Accessor.phpTS\w@phpunit-selenium/Extensions/Selenium2TestCase/Element/Select.phpTSL@"9phpunit-selenium/Extensions/Selenium2TestCase/Command.phpL TSL cyƶDphpunit-selenium/Extensions/Selenium2TestCase/ScreenshotListener.phpTS|a8phpunit-selenium/Extensions/Selenium2TestCase/Window.phpO TSO S;phpunit-selenium/Extensions/Selenium2TestCase/Exception.php TS H"[;phpunit-selenium/Extensions/Selenium2TestCase/WaitUntil.phpTSsXFphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Click.php+ TS+ ĻJphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Attribute.phpt TSt  ˈGphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Equals.php` TS` nնLphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericPost.phpW TSW LqPphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.phpi TSi PeDphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Css.phpi TSi Fphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Value.php TS .$Iphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Location.php TS Dphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Log.php TS "=Fphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Click.php TS ^aEphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Keys.php$TS$wͶFphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Frame.php TS z"Gphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Window.php TS Qphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.php TS BLphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php1 TS1 BHLphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Orientation.php TS @\WIPphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.phpT TST XMphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php6 TS6 vlJphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AlertText.phpC TSC lXimEphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/File.phpTS0ߗDphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Url.php TS KGphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/MoveTo.phpTS- @phpunit-selenium/Extensions/Selenium2TestCase/CommandsHolder.phpTSZew<phpunit-selenium/Extensions/Selenium2TestCase/KeysHolder.phpTS|H>phpunit-selenium/Extensions/Selenium2TestCase/StateCommand.phpw TSw e3Z1phpunit-selenium/Extensions/SeleniumTestSuite.phpTSsebastian-diff/Diff.php TS ̶sebastian-diff/Parser.phpTSH.wsebastian-diff/Line.php TS pBsebastian-diff/Differ.php!TS!ohrŶsebastian-diff/Chunk.php TS % manifest.txtTS(h~ֶ. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Kris Wallsmith * @copyright 2010 Sebastian Bergmann * @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 * @author Kris Wallsmith * @copyright 2010-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Sebastian Bergmann * @copyright 2010-2014 Sebastian Bergmann * @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 * @author Sebastian Bergmann * @copyright 2010-2014 Sebastian Bergmann * @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) ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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'; } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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) ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Sebastian Bergmann * @copyright 2010-2014 Sebastian Bergmann * @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 * @author Sebastian Bergmann * @copyright 2010-2014 Sebastian Bergmann * @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) ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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; } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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.' ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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() { } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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 ) ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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() { } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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; $this->verify(); return count($invocation->parameters) < count($this->parameters); } /** * Checks if the invocation $invocation matches the current rules. If it * does the matcher will get the invoked() method called which should check * if an expectation is met. * * @param PHPUnit_Framework_MockObject_Invocation $invocation * Object containing information on a mocked or stubbed method which * was invoked. * @return bool * @throws PHPUnit_Framework_ExpectationFailedException */ public function verify() { if ($this->invocation === NULL) { throw new PHPUnit_Framework_ExpectationFailedException( 'Mocked method does not exist.' ); } if (count($this->invocation->parameters) < count($this->parameters)) { throw new PHPUnit_Framework_ExpectationFailedException( sprintf( 'Parameter count for invocation %s is too low.', $this->invocation->toString() ) ); } foreach ($this->parameters as $i => $parameter) { $parameter->evaluate( $this->invocation->parameters[$i], sprintf( 'Parameter %s for invocation %s does not match expected ' . 'value.', $i, $this->invocation->toString() ) ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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 ) ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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(); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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: * * // match first parameter with value 2 * $b->with(2); * // match first parameter with value 'smock' and second identical to 42 * $b->with('smock', new PHPUnit_Framework_Constraint_IsEqual(42)); * * * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch */ public function with(); /** * Sets a matcher which allows any kind of parameters. * * Some examples: * * // match any number of parameters * $b->withAnyParamers(); * * * @return PHPUnit_Framework_MockObject_Matcher_AnyParameters */ public function withAnyParameters(); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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; } /** * @param mixed $argument, ... * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker */ public function with() { $args = func_get_args(); if ($this->matcher->methodNameMatcher === NULL) { throw new PHPUnit_Framework_Exception( 'Method name matcher is not defined, cannot define parameter ' . ' matcher without one' ); } if ($this->matcher->parametersMatcher !== NULL) { throw new PHPUnit_Framework_Exception( 'Parameter matcher is already defined, cannot redefine' ); } $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_Parameters($args); return $this; } /** * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker */ public function withAnyParameters() { if ($this->matcher->methodNameMatcher === NULL) { throw new PHPUnit_Framework_Exception( 'Method name matcher is not defined, cannot define parameter ' . 'matcher without one' ); } if ($this->matcher->parametersMatcher !== NULL) { throw new PHPUnit_Framework_Exception( 'Parameter matcher is already defined, cannot redefine' ); } $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters; return $this; } /** * @param PHPUnit_Framework_Constraint|string $constraint * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker */ public function method($constraint) { if ($this->matcher->methodNameMatcher !== NULL) { throw new PHPUnit_Framework_Exception( 'Method name matcher is already defined, cannot redefine' ); } $this->matcher->methodNameMatcher = new PHPUnit_Framework_MockObject_Matcher_MethodName($constraint); return $this; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2012 Sebastian Bergmann * @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 * @copyright 2010-2012 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Sebastian Bergmann * @copyright 2010-2014 Sebastian Bergmann * @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 * @author Sebastian Bergmann * @copyright 2010-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); $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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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(); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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(); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2010-2014 Sebastian Bergmann * @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 * @copyright 2010-2014 Sebastian Bergmann * @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); } {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 {class_name} { use {trait_name}; } {namespace}class {class_name} extends \SoapClient { public function __construct($wsdl, array $options) { parent::__construct('{wsdl}', $options); } {methods}} {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 $this->__phpunit_originalObject->{method_name}({arguments_call}); } public function __clone() { $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker(); parent::__clone(); } 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()); } {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 __clone() { $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker(); } public function {method_name}({arguments}) { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2014 Sebastian Bergmann * @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 * @copyright 2014 Sebastian Bergmann * @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(); } } -----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----- . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link https://github.com/sebastianbergmann/exporter */ class Exception extends \RuntimeException { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2001-2014 Sebastian Bergmann * @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. * * * export(new Exception); * * * @package Exporter * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @author Adam Harvey * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Adam Harvey * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2013-2014 Sebastian Bergmann * @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 * @copyright 2013-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 2.1.0 */ class PHPUnit_Util_TestDox_NamePrettifier { /** * @var string */ protected $prefix = 'Test'; /** * @var string */ protected $suffix = 'Test'; /** * @var array */ protected $strings = array(); /** * Prettifies the name of a test class. * * @param string $name * @return string */ public function prettifyTestClass($name) { $title = $name; if ($this->suffix !== null && $this->suffix == substr($name, -1 * strlen($this->suffix))) { $title = substr($title, 0, strripos($title, $this->suffix)); } if ($this->prefix !== null && $this->prefix == substr($name, 0, strlen($this->prefix))) { $title = substr($title, strlen($this->prefix)); } return str_replace('\\', '', $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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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"); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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(''); } /** * Handler for 'start class' event. * * @param string $name */ protected function startClass($name) { $this->write( '

' . $this->currentTestClassPrettified . '

    ' ); } /** * Handler for 'on test' event. * * @param string $name * @param boolean $success */ protected function onTest($name, $success = true) { if (!$success) { $strikeOpen = ''; $strikeClose = ''; } else { $strikeOpen = ''; $strikeClose = ''; } $this->write('
  • ' . $strikeOpen . $name . $strikeClose . '
  • '); } /** * Handler for 'end class' event. * * @param string $name */ protected function endClass($name) { $this->write('
'); } /** * Handler for 'end run' event. * */ protected function endRun() { $this->write(''); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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() { } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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+(?PPHP(?:Unit)?)\s+(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m'; const REGEX_REQUIRES_OS = '/@requires\s+OS\s+(?P.+?)[ \t]*\r?$/m'; const REGEX_REQUIRES = '/@requires\s+(?Pfunction|extension)\s+(?P([^ ]+?))[ \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[^\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[^\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[A-Za-z_-]+)(?:[ \t]+(?P.*?))?[ \t]*\r?$/m', $docblock, $matches)) { $numMatches = count($matches[0]); for ($i = 0; $i < $numMatches; ++$i) { $annotations[$matches['name'][$i]][] = $matches['value'][$i]; } } return $annotations; } /** * Returns the backup settings for a test. * * @param string $className * @param string $methodName * @return array * @since Method available since Release 3.4.0 */ public static function getBackupSettings($className, $methodName) { return array( 'backupGlobals' => self::getBooleanAnnotationSetting( $className, $methodName, 'backupGlobals' ), 'backupStaticAttributes' => self::getBooleanAnnotationSetting( $className, $methodName, 'backupStaticAttributes' ) ); } /** * Returns the dependencies for a test class or method. * * @param string $className * @param string $methodName * @return array * @since Method available since Release 3.4.0 */ public static function getDependencies($className, $methodName) { $annotations = self::parseTestMethodAnnotations( $className, $methodName ); $dependencies = array(); if (isset($annotations['class']['depends'])) { $dependencies = $annotations['class']['depends']; } if (isset($annotations['method']['depends'])) { $dependencies = array_merge( $dependencies, $annotations['method']['depends'] ); } return array_unique($dependencies); } /** * Returns the error handler settings for a test. * * @param string $className * @param string $methodName * @return boolean * @since Method available since Release 3.4.0 */ public static function getErrorHandlerSettings($className, $methodName) { return self::getBooleanAnnotationSetting( $className, $methodName, 'errorHandler' ); } /** * Returns the groups for a test class or method. * * @param string $className * @param string $methodName * @return array * @since Method available since Release 3.2.0 */ public static function getGroups($className, $methodName = '') { $annotations = self::parseTestMethodAnnotations( $className, $methodName ); $groups = array(); if (isset($annotations['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, '') !== false) { $element = str_replace( '', '', $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()); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @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 * @author Derek DeVries * @author Tobias Schlitt */ 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 */ 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 * @author Derek DeVries */ public static function assertValidKeys(array $hash, array $validKeys) { $valids = array(); // Normalize validation keys so that we can use both indexed and // associative arrays. foreach ($validKeys as $key => $val) { is_int($key) ? $valids[$val] = null : $valids[$key] = $val; } $validKeys = array_keys($valids); // Check for invalid keys. foreach ($hash as $key => $value) { if (!in_array($key, $validKeys)) { $unknown[] = $key; } } if (!empty($unknown)) { throw new 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 * @author Derek DeVries */ public static function convertSelectToTag($selector, $content = true) { $selector = trim(preg_replace("/\s+/", " ", $selector)); // substitute spaces within attribute value while (preg_match('/\[[^\]]+"[^"]+\s[^"]+"\]/', $selector)) { $selector = preg_replace( '/(\[[^\]]+"[^"]+)\s([^"]+"\])/', "$1__SPACE__$2", $selector ); } if (strstr($selector, ' ')) { $elements = explode(' ', $selector); } else { $elements = array($selector); } $previousTag = array(); foreach (array_reverse($elements) as $element) { $element = str_replace('__SPACE__', ' ', $element); // child selector if ($element == '>') { $previousTag = array('child' => $previousTag['descendant']); continue; } // 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 * @author Derek DeVries * @author Tobias Schlitt */ 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 * @author Derek DeVries * @author Tobias Schlitt */ 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 * @author Derek DeVries */ protected static function getDescendants(DOMNode $node) { $allChildren = array(); $childNodes = $node->childNodes ? $node->childNodes : array(); foreach ($childNodes as $child) { if ($child->nodeType === XML_CDATA_SECTION_NODE || $child->nodeType === XML_TEXT_NODE) { continue; } $children = self::getDescendants($child); $allChildren = array_merge($allChildren, $children, array($child)); } return isset($allChildren) ? $allChildren : array(); } /** * Gets elements by case insensitive tagname. * * @param DOMDocument $dom * @param string $tag * @return DOMNodeList * @since Method available since Release 3.4.0 */ protected static function getElementsByCaseInsensitiveTagName(DOMDocument $dom, $tag) { $elements = $dom->getElementsByTagName(strtolower($tag)); if ($elements->length == 0) { $elements = $dom->getElementsByTagName(strtoupper($tag)); } return $elements; } /** * Get the text value of this node's child text node. * * @param DOMNode $node * @return string * @since Method available since Release 3.3.0 * @author Mike Naberezny * @author Derek DeVries */ protected static function getNodeText(DOMNode $node) { if (!$node->childNodes instanceof DOMNodeList) { return ''; } $result = ''; foreach ($node->childNodes as $childNode) { if ($childNode->nodeType === XML_TEXT_NODE || $childNode->nodeType === XML_CDATA_SECTION_NODE) { $result .= trim($childNode->data) . ' '; } else { $result .= self::getNodeText($childNode); } } return str_replace(' ', ' ', $result); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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)); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 && !$declaredClasses[$i] instanceof PHPUnit_Framework_Test) { $class = new ReflectionClass($declaredClasses[$i]); if (!$class->isUserDefined()) { break; } $backup = array(); foreach ($class->getProperties() as $attribute) { if ($attribute->isStatic()) { $name = $attribute->getName(); if (!isset($blacklist[$declaredClasses[$i]]) || !in_array($name, $blacklist[$declaredClasses[$i]])) { $attribute->setAccessible(true); $value = $attribute->getValue(); if (!$value instanceof Closure) { $backup[$name] = serialize($value); } } } } if (!empty($backup)) { self::$staticAttributes[$declaredClasses[$i]] = $backup; } } } } public static function restoreStaticAttributes() { foreach (self::$staticAttributes as $className => $staticAttributes) { foreach ($staticAttributes as $name => $value) { $reflector = new ReflectionProperty($className, $name); $reflector->setAccessible(true); $reflector->setValue(unserialize($value)); } } self::$staticAttributes = array(); } protected static function exportVariable($variable) { if (is_scalar($variable) || is_null($variable) || (is_array($variable) && self::arrayOnlyContainsScalars($variable))) { return var_export($variable, true); } return 'unserialize(\'' . str_replace("'", "\'", serialize($variable)) . '\')'; } protected static function arrayOnlyContainsScalars(array $array) { $result = true; foreach ($array as $element) { if (is_array($element)) { $result = self::arrayOnlyContainsScalars($element); } elseif (!is_scalar($element) && !is_null($element)) { $result = false; } if ($result === false) { break; } } return $result; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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: * * * * * * * /path/to/files * /path/to/MyTest.php * /path/to/files/exclude * * * * * * name * * * name * * * * * * /path/to/files * /path/to/file * * /path/to/files * /path/to/file * * * * /path/to/files * /path/to/file * * /path/to/files * /path/to/file * * * * * * * * * * Sebastian * * * 22 * April * 19.78 * * * MyRelativeFile.php * MyRelativeDir * * * * * * * * * * * * * * * * * * . * * * * * * * * * * * * * * * * * * * @package PHPUnit * @subpackage Util * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) { // See https://github.com/sebastianbergmann/phpunit/issues/277 switch ($array) { case 'var': $target = &$GLOBALS; break; case 'env': $target = &$_ENV; break; case 'server': $target = &$_SERVER; break; default: $target = &$GLOBALS['_' . strtoupper($array)]; break; } foreach ($configuration[$array] as $name => $value) { $target[$name] = $value; } } foreach ($configuration['env'] as $name => $value) { putenv("$name=$value"); } } /** * Returns the PHPUnit configuration. * * @return array * @since Method available since Release 3.2.14 */ public function getPHPUnitConfiguration() { $result = array(); $root = $this->document->documentElement; if ($root->hasAttribute('cacheTokens')) { $result['cacheTokens'] = $this->getBoolean( (string) $root->getAttribute('cacheTokens'), false ); } if ($root->hasAttribute('colors')) { $result['colors'] = $this->getBoolean( (string) $root->getAttribute('colors'), false ); } if ($root->hasAttribute('backupGlobals')) { $result['backupGlobals'] = $this->getBoolean( (string) $root->getAttribute('backupGlobals'), true ); } if ($root->hasAttribute('backupStaticAttributes')) { $result['backupStaticAttributes'] = $this->getBoolean( (string) $root->getAttribute('backupStaticAttributes'), false ); } if ($root->hasAttribute('bootstrap')) { $result['bootstrap'] = $this->toAbsolutePath( (string) $root->getAttribute('bootstrap') ); } if ($root->hasAttribute('convertErrorsToExceptions')) { $result['convertErrorsToExceptions'] = $this->getBoolean( (string) $root->getAttribute('convertErrorsToExceptions'), true ); } if ($root->hasAttribute('convertNoticesToExceptions')) { $result['convertNoticesToExceptions'] = $this->getBoolean( (string) $root->getAttribute('convertNoticesToExceptions'), true ); } if ($root->hasAttribute('convertWarningsToExceptions')) { $result['convertWarningsToExceptions'] = $this->getBoolean( (string) $root->getAttribute('convertWarningsToExceptions'), true ); } if ($root->hasAttribute('forceCoversAnnotation')) { $result['forceCoversAnnotation'] = $this->getBoolean( (string) $root->getAttribute('forceCoversAnnotation'), false ); } if ($root->hasAttribute('mapTestClassNameToCoveredClassName')) { $result['mapTestClassNameToCoveredClassName'] = $this->getBoolean( (string) $root->getAttribute('mapTestClassNameToCoveredClassName'), false ); } if ($root->hasAttribute('processIsolation')) { $result['processIsolation'] = $this->getBoolean( (string) $root->getAttribute('processIsolation'), false ); } if ($root->hasAttribute('stopOnError')) { $result['stopOnError'] = $this->getBoolean( (string) $root->getAttribute('stopOnError'), false ); } if ($root->hasAttribute('stopOnFailure')) { $result['stopOnFailure'] = $this->getBoolean( (string) $root->getAttribute('stopOnFailure'), false ); } if ($root->hasAttribute('stopOnIncomplete')) { $result['stopOnIncomplete'] = $this->getBoolean( (string) $root->getAttribute('stopOnIncomplete'), false ); } if ($root->hasAttribute('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; } } 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(); . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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() { } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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, "tempFile, true) . "; ?>" ); } /** * @since Method available since Release 3.5.12 */ protected function cleanup() { unlink($this->tempFile); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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'); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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' ) ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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"); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 ) ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 */ private static $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 (PHP_CodeCoverage_Filter::$blacklistClassNames 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; } } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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.0.17"; 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.0.17', 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 ''; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 mixed $test * @param array $arguments * @throws PHPUnit_Framework_Exception */ public static function run($test, array $arguments = array()) { if ($test instanceof ReflectionClass) { $test = new PHPUnit_Framework_TestSuite($test); } if ($test instanceof PHPUnit_Framework_Test) { $aTestRunner = new PHPUnit_TextUI_TestRunner; return $aTestRunner->doRun( $test, $arguments ); } else { throw new PHPUnit_Framework_Exception( 'No test case or test suite found.' ); } } /** * @return PHPUnit_Framework_TestResult */ protected function createTestResult() { return new PHPUnit_Framework_TestResult; } 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->printVersionString(); 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 PHPUnit %s', 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"); if (strpos('4.0.17', '@version') !== 0) { self::write( "You have installed PHPUnit via PEAR. This installation method is no longer\n" . "supported and http://pear.phpunit.de/ will be shut down no later than\n" . "December, 31 2014.\n\n" . "Please read http://phpunit.de/manual/current/en/installation.html and\n" . "learn how to use PHPUnit from a PHAR or install it via Composer.\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']; 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); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 * * * 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); * } * * } * * * @param array $argv */ protected function handleArguments(array $argv) { if (defined('__PHPUNIT_PHAR__')) { $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 '--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']); } 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 = $_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 ... '; file_put_contents( $tempFilename, file_get_contents( $remoteFilename, false, stream_context_create( array( 'ssl' => array( 'CN_match' => 'phar.phpunit.de', 'allow_self_signed' => false, 'cafile' => $caFile, 'verify_peer' => true ) ) ) ) ); 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 << Code Coverage Options: --coverage-clover Generate code coverage report in Clover XML format. --coverage-crap4j Generate code coverage report in Crap4J XML format. --coverage-html Generate code coverage report in HTML format. --coverage-php Export PHP_CodeCoverage object to file. --coverage-text= Generate code coverage report in text format. Default: Standard output. --coverage-xml Generate code coverage report in PHPUnit XML format. Logging Options: --log-junit Log test execution in JUnit XML format to file. --log-tap Log test execution in TAP format to file. --log-json Log test execution in JSON format. --testdox-html Write agile documentation in HTML format to file. --testdox-text Write agile documentation in Text format to file. Test Selection Options: --filter Filter which tests to run. --testsuite 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 TestSuiteLoader implementation to use. --repeat Runs the test(s) repeatedly. --tap Report test execution progress in TAP format. --testdox Report test execution progress in TestDox format. --printer TestSuiteListener implementation to use. Configuration Options: --bootstrap A "bootstrap" PHP file that is run before the tests. -c|--configuration Read configuration from XML file. --no-configuration Ignore default configuration file (phpunit.xml). --include-path Prepend PHP's include_path with given path(s). -d key[=value] Sets a php.ini value. 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() { } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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'); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 . * * * $suite = new PHPUnit_Extensions_GroupTestSuite($A, array('C', 'D')); * * * @package PHPUnit * @subpackage Extensions * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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); } } } } } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Raphael Stolt * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Factory for comparators which compare values for equality. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_ComparatorFactory { /** * @var array */ protected $comparators = array(); /** * @var PHPUnit_Framework_ComparatorFactory */ private static $defaultInstance = null; /** * Constructs a new factory. */ public function __construct() { $this->register(new PHPUnit_Framework_Comparator_Type); $this->register(new PHPUnit_Framework_Comparator_Scalar); $this->register(new PHPUnit_Framework_Comparator_Numeric); $this->register(new PHPUnit_Framework_Comparator_Double); $this->register(new PHPUnit_Framework_Comparator_Array); $this->register(new PHPUnit_Framework_Comparator_Resource); $this->register(new PHPUnit_Framework_Comparator_Object); $this->register(new PHPUnit_Framework_Comparator_Exception); $this->register(new PHPUnit_Framework_Comparator_SplObjectStorage); $this->register(new PHPUnit_Framework_Comparator_DOMNode); $this->register(new PHPUnit_Framework_Comparator_MockObject); $this->register(new PHPUnit_Framework_Comparator_DateTime); } /** * Returns the default instance. * * @return PHPUnit_Framework_ComparatorFactory */ public static function getDefaultInstance() { if (self::$defaultInstance === null) { self::$defaultInstance = new PHPUnit_Framework_ComparatorFactory; } return self::$defaultInstance; } /** * Returns the correct comparator for comparing two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return PHPUnit_Framework_Comparator * @throws PHPUnit_Framework_Exception */ public function getComparatorFor($expected, $actual) { foreach ($this->comparators as $comparator) { if ($comparator->accepts($expected, $actual)) { return $comparator; } } throw new PHPUnit_Framework_Exception( sprintf( 'No comparator is registered for comparing the types "%s" and "%s"', gettype($expected), gettype($actual) ) ); } /** * Registers a new comparator. * * This comparator will be returned by getInstance() if its accept() method * returns true for the compared values. It has higher priority than the * existing comparators, meaning that its accept() method will be tested * before those of the other comparators. * * @param PHPUnit_Framework_Comparator $comparator The registered comparator */ public function register(PHPUnit_Framework_Comparator $comparator) { array_unshift($this->comparators, $comparator); $comparator->setFactory($this); } /** * Unregisters a comparator. * * This comparator will no longer be returned by getInstance(). * * @param PHPUnit_Framework_Comparator $comparator The unregistered comparator */ public function unregister(PHPUnit_Framework_Comparator $comparator) { foreach ($this->comparators as $key => $_comparator) { if ($comparator === $_comparator) { unset($this->comparators[$key]); } } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares resources for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_Resource extends PHPUnit_Framework_Comparator { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return is_resource($expected) && is_resource($actual); } /** * Asserts that two values are equal. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @param float $delta The allowed numerical distance between two values to * consider them equal * @param bool $canonicalize If set to true, arrays are sorted before * comparison * @param bool $ignoreCase If set to true, upper- and lowercasing is * ignored when comparing string values * @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false) { if ($actual != $expected) { throw new PHPUnit_Framework_ComparisonFailure( $expected, $actual, $this->exporter->export($expected), $this->exporter->export($actual) ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares objects for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_Object extends PHPUnit_Framework_Comparator_Array { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return is_object($expected) && is_object($actual); } /** * Asserts that two values are equal. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @param float $delta The allowed numerical distance between two values to * consider them equal * @param bool $canonicalize If set to true, arrays are sorted before * comparison * @param bool $ignoreCase If set to true, upper- and lowercasing is * ignored when comparing string values * @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false, array &$processed = array()) { if (get_class($actual) !== get_class($expected)) { throw new PHPUnit_Framework_ComparisonFailure( $expected, $actual, $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 (PHPUnit_Framework_ComparisonFailure $e) { throw new PHPUnit_Framework_ComparisonFailure( $expected, $actual, // replace "Array" with "MyClass object" substr_replace($e->getExpectedAsString(), get_class($expected) . ' Object', 0, 5), substr_replace($e->getActualAsString(), get_class($actual) . ' Object', 0, 5), false, 'Failed asserting that two objects are equal.' ); } } } /** * Converts an object to an array containing all of its private, protected * and public properties. * * @param object $object * @return array */ protected function toArray($object) { return $this->exporter->toArray($object); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares numerical values for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @author Alexander * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_Numeric extends PHPUnit_Framework_Comparator_Scalar { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { // all numerical values, but not if one of them is a double // 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 PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false) { if (is_infinite($actual) && is_infinite($expected)) { return; } if ((is_infinite($actual) XOR is_infinite($expected)) || (is_nan($actual) OR is_nan($expected)) || abs($actual - $expected) > $delta) { throw new PHPUnit_Framework_ComparisonFailure( $expected, $actual, '', '', false, sprintf( 'Failed asserting that %s matches expected %s.', $this->exporter->export($actual), $this->exporter->export($expected) ) ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares SplObjectStorage instances for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_SplObjectStorage extends PHPUnit_Framework_Comparator { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return $expected instanceof SplObjectStorage && $actual instanceof SplObjectStorage; } /** * Asserts that two values are equal. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @param float $delta The allowed numerical distance between two values to * consider them equal * @param bool $canonicalize If set to true, arrays are sorted before * comparison * @param bool $ignoreCase If set to true, upper- and lowercasing is * ignored when comparing string values * @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false) { foreach ($actual as $object) { if (!$expected->contains($object)) { throw new PHPUnit_Framework_ComparisonFailure( $expected, $actual, $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 PHPUnit_Framework_ComparisonFailure( $expected, $actual, $this->exporter->export($expected), $this->exporter->export($actual), false, 'Failed asserting that two objects are equal.' ); } } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares doubles for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_Double extends PHPUnit_Framework_Comparator_Numeric { /** * Smallest value available in PHP. * * @var float */ const EPSILON = 0.0000000001; /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return (is_double($expected) || is_double($actual)) && is_numeric($expected) && is_numeric($actual); } /** * Asserts that two values are equal. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @param float $delta The allowed numerical distance between two values to * consider them equal * @param bool $canonicalize If set to true, arrays are sorted before * comparison * @param bool $ignoreCase If set to true, upper- and lowercasing is * ignored when comparing string values * @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false) { if ($delta == 0) { $delta = self::EPSILON; } parent::assertEquals($expected, $actual, $delta, $canonicalize, $ignoreCase); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares Exception instances for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_Exception extends PHPUnit_Framework_Comparator_Object { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return $expected instanceof Exception && $actual instanceof Exception; } /** * Converts an object to an array containing all of its private, protected * and public properties. * * @param object $object * @return array */ protected function toArray($object) { $array = parent::toArray($object); unset( $array['file'], $array['line'], $array['trace'], $array['string'], // some internal property of Exception $array['xdebug_message'] // some internal property added by XDebug ); return $array; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares PHPUnit_Framework_MockObject_MockObject instances for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_MockObject extends PHPUnit_Framework_Comparator_Object { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return $expected instanceof PHPUnit_Framework_MockObject_MockObject && $actual instanceof PHPUnit_Framework_MockObject_MockObject; } /** * Converts an object to an array containing all of its private, protected * and public properties. * * @param object $object * @return array */ protected function toArray($object) { $array = parent::toArray($object); unset($array['__phpunit_invocationMocker']); return $array; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 Jeff Welch * @copyright 2001-2014 Sebastian Bergmann * @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 */ /** * Compares DateTime instances for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Jeff Welch * @copyright 2001-2014 Sebastian Bergmann * @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_Comparator_DateTime extends PHPUnit_Framework_Comparator_Object { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return $expected instanceof 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 PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false) { $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 PHPUnit_Framework_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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares scalar or null values for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_Scalar extends PHPUnit_Framework_Comparator { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean * @since Method available since Release 3.6.0 */ public function accepts($expected, $actual) { return ((is_scalar($expected) XOR null === $expected) && (is_scalar($actual) XOR null === $actual)) // allow comparison between strings and objects featuring __toString() || (is_string($expected) && is_object($actual) && method_exists($actual, '__toString')) || (is_object($expected) && method_exists($expected, '__toString') && is_string($actual)); } /** * Asserts that two values are equal. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @param float $delta The allowed numerical distance between two values to * consider them equal * @param bool $canonicalize If set to true, arrays are sorted before * comparison * @param bool $ignoreCase If set to true, upper- and lowercasing is * ignored when comparing string values * @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false) { $expectedToCompare = $expected; $actualToCompare = $actual; // always compare as strings to avoid strange behaviour // otherwise 0 == 'Foobar' if (is_string($expected) || is_string($actual)) { $expectedToCompare = (string) $expectedToCompare; $actualToCompare = (string) $actualToCompare; if ($ignoreCase) { $expectedToCompare = strtolower($expectedToCompare); $actualToCompare = strtolower($actualToCompare); } } if ($expectedToCompare != $actualToCompare) { if (is_string($expected) && is_string($actual)) { throw new PHPUnit_Framework_ComparisonFailure( $expected, $actual, $this->exporter->export($expected), $this->exporter->export($actual), false, 'Failed asserting that two strings are equal.' ); } throw new PHPUnit_Framework_ComparisonFailure( $expected, $actual, // no diff is required '', '', false, sprintf( 'Failed asserting that %s matches expected %s.', $this->exporter->export($actual), $this->exporter->export($expected) ) ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares arrays for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_Array extends PHPUnit_Framework_Comparator { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return is_array($expected) && is_array($actual); } /** * Asserts that two values are equal. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @param float $delta The allowed numerical distance between two values to * consider them equal * @param bool $canonicalize If set to true, arrays are sorted before * comparison * @param bool $ignoreCase If set to true, upper- and lowercasing is * ignored when comparing string values * @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false, array &$processed = array()) { if ($canonicalize) { sort($expected); sort($actual); } $remaining = $actual; $expString = $actString = "Array (\n"; $equal = true; foreach ($expected as $key => $value) { unset($remaining[$key]); if (!array_key_exists($key, $actual)) { $expString .= sprintf( " %s => %s\n", $this->exporter->export($key), $this->exporter->shortenedExport($value) ); $equal = false; continue; } try { $this->factory->getComparatorFor($value, $actual[$key])->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed); $expString .= sprintf( " %s => %s\n", $this->exporter->export($key), $this->exporter->shortenedExport($value) ); $actString .= sprintf( " %s => %s\n", $this->exporter->export($key), $this->exporter->shortenedExport($actual[$key]) ); } catch (PHPUnit_Framework_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 PHPUnit_Framework_ComparisonFailure( $expected, $actual, $expString, $actString, false, 'Failed asserting that two arrays are equal.' ); } } protected function indent($lines) { return trim(str_replace("\n", "\n ", $lines)); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares values for type equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ class PHPUnit_Framework_Comparator_Type extends PHPUnit_Framework_Comparator { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return true; } /** * Asserts that two values are equal. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @param float $delta The allowed numerical distance between two values to * consider them equal * @param bool $canonicalize If set to true, arrays are sorted before * comparison * @param bool $ignoreCase If set to true, upper- and lowercasing is * ignored when comparing string values * @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false) { if (gettype($expected) != gettype($actual)) { throw new PHPUnit_Framework_ComparisonFailure( $expected, $actual, // we don't need a diff '', '', false, sprintf( '%s does not match expected type "%s".', $this->exporter->shortenedExport($actual), gettype($expected) ) ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.6.0 */ /** * Compares DOMNodes instances for equality. * * @package PHPUnit * @subpackage Framework_Comparator * @author Bernhard Schussek * @author Arne Blankerts * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ */ class PHPUnit_Framework_Comparator_DOMNode extends PHPUnit_Framework_Comparator_Object { /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return $expected instanceof 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 PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false) { $expectedXML = $expected->C14N(); $actualXML = $actual->C14N(); if ($ignoreCase === true) { $expectedXML = strtolower($expectedXML); $actualXML = strtolower($actualXML); } if ($expectedXML !== $actualXML) { if ($expected instanceof DOMDocument) { $type = 'documents'; } else { $type = 'nodes'; } throw new PHPUnit_Framework_ComparisonFailure( $expected, $actual, $this->domToText($expected), $this->domToText($actual), false, sprintf('Failed asserting that two DOM %s are equal.', $type) ); } } /** * Returns the normalized, whitespace-cleaned, and indented textual * representation of a DOMNode. * * @param DOMNode $node * @return string */ protected function domToText(DOMNode $node) { if ($node instanceof DOMDocument) { $document = $node; } else { $document = $node->ownerDocument; } $document->formatOutput = true; $document->normalizeDocument(); if ($node instanceof DOMDocument) { return $node->saveXML(); } return $document->saveXML($node); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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) {} } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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() ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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() ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 PHPUnit_Framework_ComparisonFailure( $this->value, $other, $this->value, $other ); } $this->fail($other, $description, $f); } } /** * Returns the description of the failure * * The beginning of failure messages is "Failed asserting that" in most * cases. This method should return the second part of that sentence. * * @param mixed $other Evaluated value or object. * @return string */ protected function failureDescription($other) { if (is_object($this->value) && is_object($other)) { return 'two variables reference the same object'; } if (is_string($this->value) && is_string($other)) { return 'two strings are identical'; } return parent::failureDescription($other); } /** * Returns a string representation of the constraint. * * @return string */ public function toString() { if (is_object($this->value)) { return 'is identical to an object of class "' . get_class($this->value) . '"'; } else { return 'is identical to ' . $this->exporter->export($this->value); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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)); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 . '"'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 . '"'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Sebastian Bergmann * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Sebastian Bergmann * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.0.0 */ class PHPUnit_Framework_Constraint_IsEqual extends PHPUnit_Framework_Constraint { /** * @var mixed */ protected $value; /** * @var float */ protected $delta = 0; /** * @var integer */ protected $maxDepth = 10; /** * @var boolean */ protected $canonicalize = false; /** * @var boolean */ protected $ignoreCase = false; /** * @var PHPUnit_Framework_ComparisonFailure */ protected $lastFailure; /** * @param mixed $value * @param float $delta * @param integer $maxDepth * @param boolean $canonicalize * @param boolean $ignoreCase * @throws PHPUnit_Framework_Exception */ public function __construct($value, $delta = 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 = PHPUnit_Framework_ComparatorFactory::getDefaultInstance(); try { $comparator = $comparatorFactory->getComparatorFor( $other, $this->value ); $comparator->assertEquals( $this->value, $other, $this->delta, $this->canonicalize, $this->ignoreCase ); } catch (PHPUnit_Framework_ComparisonFailure $f) { if ($returnResult) { return false; } throw new PHPUnit_Framework_ExpectationFailedException( trim($description . "\n" . $f->getMessage()), $f ); } return true; } /** * Returns a string representation of the constraint. * * @return string */ public function toString() { $delta = ''; if (is_string($this->value)) { if (strpos($this->value, "\n") !== false) { return 'is equal to '; } else { return sprintf( 'is equal to ', $this->value ); } } else { if ($this->delta != 0) { $delta = sprintf( ' with delta <%F>', $this->delta ); } return sprintf( 'is equal to %s%s', $this->exporter->export($this->value), $delta ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 '; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 '; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 '; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Timon Rapp * @copyright 2001-2014 Sebastian Bergmann * @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]; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 . '"'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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'; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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() ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 PHPUnit_Framework_ComparisonFailure $comparisonFailure * @throws PHPUnit_Framework_ExpectationFailedException */ protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = null) { $failureDescription = sprintf( 'Failed asserting that %s.', $this->failureDescription($other) ); $additionalFailureDescription = $this->additionalFailureDescription($other); if ($additionalFailureDescription) { $failureDescription .= "\n" . $additionalFailureDescription; } if (!empty($description)) { $failureDescription = $description . "\n" . $failureDescription; } throw new PHPUnit_Framework_ExpectationFailedException( $failureDescription, $comparisonFailure ); } /** * Return additional failure description where needed * * The function can be overridden to provide additional failure * information like a diff * * @param mixed $other Evaluated value or object. * @return string */ protected function additionalFailureDescription($other) { return ''; } /** * Returns the description of the failure * * The beginning of failure messages is "Failed asserting that" in most * cases. This method should return the second part of that sentence. * * To provide additional failure information additionalFailureDescription * can be used. * * @param mixed $other Evaluated value or object. * @return string */ protected function failureDescription($other) { return $this->exporter->export($other) . ' ' . $this->toString(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) { $constraint = new PHPUnit_Framework_Constraint_IsEqual( $expected, $delta, $maxDepth, $canonicalize, $ignoreCase ); self::assertThat($actual, $constraint, $message); } /** * Asserts that a variable is equal to an attribute of an object. * * @param mixed $expected * @param string $actualAttributeName * @param string $actualClassOrObject * @param string $message * @param float $delta * @param integer $maxDepth * @param boolean $canonicalize * @param boolean $ignoreCase */ public static function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) { self::assertEquals( $expected, self::readAttribute($actualClassOrObject, $actualAttributeName), $message, $delta, $maxDepth, $canonicalize, $ignoreCase ); } /** * Asserts that two variables are not equal. * * @param mixed $expected * @param mixed $actual * @param string $message * @param float $delta * @param integer $maxDepth * @param boolean $canonicalize * @param boolean $ignoreCase * @since Method available since Release 2.3.0 */ public static function assertNotEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) { $constraint = new PHPUnit_Framework_Constraint_Not( new PHPUnit_Framework_Constraint_IsEqual( $expected, $delta, $maxDepth, $canonicalize, $ignoreCase ) ); self::assertThat($actual, $constraint, $message); } /** * Asserts that a variable is not equal to an attribute of an object. * * @param mixed $expected * @param string $actualAttributeName * @param string $actualClassOrObject * @param string $message * @param float $delta * @param integer $maxDepth * @param boolean $canonicalize * @param boolean $ignoreCase */ public static function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) { self::assertNotEquals( $expected, self::readAttribute($actualClassOrObject, $actualAttributeName), $message, $delta, $maxDepth, $canonicalize, $ignoreCase ); } /** * Asserts that a variable is empty. * * @param mixed $actual * @param string $message * @throws PHPUnit_Framework_AssertionFailedError */ public static function assertEmpty($actual, $message = '') { self::assertThat($actual, self::isEmpty(), $message); } /** * Asserts that a static attribute of a class or an attribute of an object * is empty. * * @param string $haystackAttributeName * @param mixed $haystackClassOrObject * @param string $message * @since Method available since Release 3.5.0 */ public static function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '') { self::assertEmpty( self::readAttribute($haystackClassOrObject, $haystackAttributeName), $message ); } /** * Asserts that a variable is not empty. * * @param mixed $actual * @param string $message * @throws PHPUnit_Framework_AssertionFailedError */ public static function assertNotEmpty($actual, $message = '') { self::assertThat($actual, self::logicalNot(self::isEmpty()), $message); } /** * Asserts that a static attribute of a class or an attribute of an object * is not empty. * * @param string $haystackAttributeName * @param mixed $haystackClassOrObject * @param string $message * @since Method available since Release 3.5.0 */ public static function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '') { self::assertNotEmpty( self::readAttribute($haystackClassOrObject, $haystackAttributeName), $message ); } /** * Asserts that a value is greater than another value. * * @param mixed $expected * @param mixed $actual * @param string $message * @since Method available since Release 3.1.0 */ public static function assertGreaterThan($expected, $actual, $message = '') { self::assertThat($actual, self::greaterThan($expected), $message); } /** * Asserts that an attribute is greater than another value. * * @param mixed $expected * @param string $actualAttributeName * @param string $actualClassOrObject * @param string $message * @since Method available since Release 3.1.0 */ public static function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '') { self::assertGreaterThan( $expected, self::readAttribute($actualClassOrObject, $actualAttributeName), $message ); } /** * Asserts that a value is greater than or equal to another value. * * @param mixed $expected * @param mixed $actual * @param string $message * @since Method available since Release 3.1.0 */ public static function assertGreaterThanOrEqual($expected, $actual, $message = '') { self::assertThat( $actual, self::greaterThanOrEqual($expected), $message ); } /** * Asserts that an attribute is greater than or equal to another value. * * @param mixed $expected * @param string $actualAttributeName * @param string $actualClassOrObject * @param string $message * @since Method available since Release 3.1.0 */ public static function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '') { self::assertGreaterThanOrEqual( $expected, self::readAttribute($actualClassOrObject, $actualAttributeName), $message ); } /** * Asserts that a value is smaller than another value. * * @param mixed $expected * @param mixed $actual * @param string $message * @since Method available since Release 3.1.0 */ public static function assertLessThan($expected, $actual, $message = '') { self::assertThat($actual, self::lessThan($expected), $message); } /** * Asserts that an attribute is smaller than another value. * * @param mixed $expected * @param string $actualAttributeName * @param string $actualClassOrObject * @param string $message * @since Method available since Release 3.1.0 */ public static function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '') { self::assertLessThan( $expected, self::readAttribute($actualClassOrObject, $actualAttributeName), $message ); } /** * Asserts that a value is smaller than or equal to another value. * * @param mixed $expected * @param mixed $actual * @param string $message * @since Method available since Release 3.1.0 */ public static function assertLessThanOrEqual($expected, $actual, $message = '') { self::assertThat($actual, self::lessThanOrEqual($expected), $message); } /** * Asserts that an attribute is smaller than or equal to another value. * * @param mixed $expected * @param string $actualAttributeName * @param string $actualClassOrObject * @param string $message * @since Method available since Release 3.1.0 */ public static function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '') { self::assertLessThanOrEqual( $expected, self::readAttribute($actualClassOrObject, $actualAttributeName), $message ); } /** * Asserts that the contents of one file is equal to the contents of another * file. * * @param string $expected * @param string $actual * @param string $message * @param boolean $canonicalize * @param boolean $ignoreCase * @since Method available since Release 3.2.14 */ public static function assertFileEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false) { self::assertFileExists($expected, $message); self::assertFileExists($actual, $message); self::assertEquals( file_get_contents($expected), file_get_contents($actual), $message, 0, 10, $canonicalize, $ignoreCase ); } /** * Asserts that the contents of one file is not equal to the contents of * another file. * * @param string $expected * @param string $actual * @param string $message * @param boolean $canonicalize * @param boolean $ignoreCase * @since Method available since Release 3.2.14 */ public static function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false) { self::assertFileExists($expected, $message); self::assertFileExists($actual, $message); self::assertNotEquals( file_get_contents($expected), file_get_contents($actual), $message, 0, 10, $canonicalize, $ignoreCase ); } /** * Asserts that the contents of a string is equal * to the contents of a file. * * @param string $expectedFile * @param string $actualString * @param string $message * @param boolean $canonicalize * @param boolean $ignoreCase * @since Method available since Release 3.3.0 */ public static function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false) { self::assertFileExists($expectedFile, $message); self::assertEquals( file_get_contents($expectedFile), $actualString, $message, 0, 10, $canonicalize, $ignoreCase ); } /** * Asserts that the contents of a string is not equal * to the contents of a file. * * @param string $expectedFile * @param string $actualString * @param string $message * @param boolean $canonicalize * @param boolean $ignoreCase * @since Method available since Release 3.3.0 */ public static function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false) { self::assertFileExists($expectedFile, $message); self::assertNotEquals( file_get_contents($expectedFile), $actualString, $message, 0, 10, $canonicalize, $ignoreCase ); } /** * Asserts that a file exists. * * @param string $filename * @param string $message * @since Method available since Release 3.0.0 */ public static function assertFileExists($filename, $message = '') { if (!is_string($filename)) { throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); } $constraint = new PHPUnit_Framework_Constraint_FileExists; self::assertThat($filename, $constraint, $message); } /** * Asserts that a file does not exist. * * @param string $filename * @param string $message * @since Method available since Release 3.0.0 */ public static function assertFileNotExists($filename, $message = '') { if (!is_string($filename)) { throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); } $constraint = new PHPUnit_Framework_Constraint_Not( new PHPUnit_Framework_Constraint_FileExists ); self::assertThat($filename, $constraint, $message); } /** * Asserts that a condition is true. * * @param boolean $condition * @param string $message * @throws PHPUnit_Framework_AssertionFailedError */ public static function assertTrue($condition, $message = '') { self::assertThat($condition, self::isTrue(), $message); } /** * Asserts that a condition is 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 * @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 * @author Derek DeVries */ public static function assertSelectCount($selector, $count, $actual, $message = '', $isHtml = true) { self::assertSelectEquals( $selector, true, $count, $actual, $message, $isHtml ); } /** * assertSelectRegExp("#binder .name", "/Mike|Derek/", true, $xml); // any? * assertSelectRegExp("#binder .name", "/Mike|Derek/", 3, $xml); // 3? * * @param array $selector * @param string $pattern * @param integer $count * @param mixed $actual * @param string $message * @param boolean $isHtml * @since Method available since Release 3.3.0 * @author Mike Naberezny * @author Derek DeVries */ public static function assertSelectRegExp($selector, $pattern, $count, $actual, $message = '', $isHtml = true) { self::assertSelectEquals( $selector, "regexp:$pattern", $count, $actual, $message, $isHtml ); } /** * assertSelectEquals("#binder .name", "Chuck", true, $xml); // any? * assertSelectEquals("#binder .name", "Chuck", false, $xml); // none? * * @param array $selector * @param string $content * @param integer $count * @param mixed $actual * @param string $message * @param boolean $isHtml * @since Method available since Release 3.3.0 * @author Mike Naberezny * @author Derek DeVries */ public static function assertSelectEquals($selector, $content, $count, $actual, $message = '', $isHtml = true) { $tags = PHPUnit_Util_XML::cssSelect( $selector, $content, $actual, $isHtml ); // assert specific number of elements if (is_numeric($count)) { $counted = $tags ? count($tags) : 0; self::assertEquals($count, $counted, $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 * * * // 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); * * * The second argument ($actual) is a string containing either HTML or * XML text to be tested. * * The third argument ($message) is an optional message that will be * used if the assertion fails. * * The fourth argument ($html) is an optional flag specifying whether * to load the $actual string into a DOMDocument using the HTML or * XML load strategy. It is true by default, which assumes the HTML * load strategy. In many cases, this will be acceptable for XML as well. * * @param array $matcher * @param string $actual * @param string $message * @param boolean $isHtml * @since Method available since Release 3.3.0 * @author Mike Naberezny * @author Derek DeVries */ public static function assertTag($matcher, $actual, $message = '', $isHtml = true) { $dom = PHPUnit_Util_XML::load($actual, $isHtml); $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml); $matched = count($tags) > 0 && $tags[0] instanceof DOMNode; self::assertTrue($matched, $message); } /** * This assertion is the exact opposite of assertTag(). * * Rather than asserting that $matcher results in a match, it asserts that * $matcher does not match. * * @param array $matcher * @param string $actual * @param string $message * @param boolean $isHtml * @since Method available since Release 3.3.0 * @author Mike Naberezny * @author Derek DeVries */ public static function assertNotTag($matcher, $actual, $message = '', $isHtml = true) { $dom = PHPUnit_Util_XML::load($actual, $isHtml); $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml); $matched = count($tags) > 0 && $tags[0] instanceof DOMNode; self::assertFalse($matched, $message); } /** * Evaluates a PHPUnit_Framework_Constraint matcher object. * * @param mixed $value * @param PHPUnit_Framework_Constraint $constraint * @param string $message * @since Method available since Release 3.0.0 */ public static function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '') { self::$count += count($constraint); $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, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) { return new PHPUnit_Framework_Constraint_IsEqual( $value, $delta, $maxDepth, $canonicalize, $ignoreCase ); } /** * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher * object. * * @param string $attributeName * @param mixed $value * @param float $delta * @param integer $maxDepth * @param boolean $canonicalize * @param boolean $ignoreCase * @return PHPUnit_Framework_Constraint_Attribute * @since Method available since Release 3.1.0 */ public static function attributeEqualTo($attributeName, $value, $delta = 0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) { return self::attribute( self::equalTo( $value, $delta, $maxDepth, $canonicalize, $ignoreCase ), $attributeName ); } /** * Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object. * * @return PHPUnit_Framework_Constraint_IsEmpty * @since Method available since Release 3.5.0 */ public static function isEmpty() { return new PHPUnit_Framework_Constraint_IsEmpty; } /** * Returns a PHPUnit_Framework_Constraint_FileExists matcher object. * * @return PHPUnit_Framework_Constraint_FileExists * @since Method available since Release 3.0.0 */ public static function fileExists() { return new PHPUnit_Framework_Constraint_FileExists; } /** * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object. * * @param mixed $value * @return PHPUnit_Framework_Constraint_GreaterThan * @since Method available since Release 3.0.0 */ public static function greaterThan($value) { return new PHPUnit_Framework_Constraint_GreaterThan($value); } /** * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps * a PHPUnit_Framework_Constraint_IsEqual and a * PHPUnit_Framework_Constraint_GreaterThan matcher object. * * @param mixed $value * @return PHPUnit_Framework_Constraint_Or * @since Method available since Release 3.1.0 */ public static function greaterThanOrEqual($value) { return self::logicalOr( new PHPUnit_Framework_Constraint_IsEqual($value), new PHPUnit_Framework_Constraint_GreaterThan($value) ); } /** * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object. * * @param string $attributeName * @return PHPUnit_Framework_Constraint_ClassHasAttribute * @since Method available since Release 3.1.0 */ public static function classHasAttribute($attributeName) { return new PHPUnit_Framework_Constraint_ClassHasAttribute( $attributeName ); } /** * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher * object. * * @param string $attributeName * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute * @since Method available since Release 3.1.0 */ public static function classHasStaticAttribute($attributeName) { return new PHPUnit_Framework_Constraint_ClassHasStaticAttribute( $attributeName ); } /** * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object. * * @param string $attributeName * @return PHPUnit_Framework_Constraint_ObjectHasAttribute * @since Method available since Release 3.0.0 */ public static function objectHasAttribute($attributeName) { return new PHPUnit_Framework_Constraint_ObjectHasAttribute( $attributeName ); } /** * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object. * * @param mixed $value * @return PHPUnit_Framework_Constraint_IsIdentical * @since Method available since Release 3.0.0 */ public static function identicalTo($value) { return new PHPUnit_Framework_Constraint_IsIdentical($value); } /** * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object. * * @param string $className * @return PHPUnit_Framework_Constraint_IsInstanceOf * @since Method available since Release 3.0.0 */ public static function isInstanceOf($className) { return new PHPUnit_Framework_Constraint_IsInstanceOf($className); } /** * Returns a PHPUnit_Framework_Constraint_IsType matcher object. * * @param string $type * @return PHPUnit_Framework_Constraint_IsType * @since Method available since Release 3.0.0 */ public static function isType($type) { return new PHPUnit_Framework_Constraint_IsType($type); } /** * Returns a PHPUnit_Framework_Constraint_LessThan matcher object. * * @param mixed $value * @return PHPUnit_Framework_Constraint_LessThan * @since Method available since Release 3.0.0 */ public static function lessThan($value) { return new PHPUnit_Framework_Constraint_LessThan($value); } /** * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps * a PHPUnit_Framework_Constraint_IsEqual and a * PHPUnit_Framework_Constraint_LessThan matcher object. * * @param mixed $value * @return PHPUnit_Framework_Constraint_Or * @since Method available since Release 3.1.0 */ public static function lessThanOrEqual($value) { return self::logicalOr( new PHPUnit_Framework_Constraint_IsEqual($value), new PHPUnit_Framework_Constraint_LessThan($value) ); } /** * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object. * * @param string $pattern * @return PHPUnit_Framework_Constraint_PCREMatch * @since Method available since Release 3.0.0 */ public static function matchesRegularExpression($pattern) { return new PHPUnit_Framework_Constraint_PCREMatch($pattern); } /** * Returns a PHPUnit_Framework_Constraint_StringMatches matcher object. * * @param string $string * @return PHPUnit_Framework_Constraint_StringMatches * @since Method available since Release 3.5.0 */ public static function matches($string) { return new PHPUnit_Framework_Constraint_StringMatches($string); } /** * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object. * * @param mixed $prefix * @return PHPUnit_Framework_Constraint_StringStartsWith * @since Method available since Release 3.4.0 */ public static function stringStartsWith($prefix) { return new PHPUnit_Framework_Constraint_StringStartsWith($prefix); } /** * Returns a PHPUnit_Framework_Constraint_StringContains matcher object. * * @param string $string * @param boolean $case * @return PHPUnit_Framework_Constraint_StringContains * @since Method available since Release 3.0.0 */ public static function stringContains($string, $case = true) { return new PHPUnit_Framework_Constraint_StringContains($string, $case); } /** * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object. * * @param mixed $suffix * @return PHPUnit_Framework_Constraint_StringEndsWith * @since Method available since Release 3.4.0 */ public static function stringEndsWith($suffix) { return new PHPUnit_Framework_Constraint_StringEndsWith($suffix); } /** * 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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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, $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, $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 * @since Method available since Release 3.3.0 */ function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = false, $message = '') { return call_user_func_array( 'PHPUnit_Framework_Assert::assertEqualXMLStructure', func_get_args() ); } /** * Asserts that two variables are equal. * * @param mixed $expected * @param mixed $actual * @param string $message * @param float $delta * @param integer $maxDepth * @param boolean $canonicalize * @param boolean $ignoreCase */ function assertEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) { return call_user_func_array( 'PHPUnit_Framework_Assert::assertEquals', func_get_args() ); } /** * Asserts that a condition is 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, $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 * @author Derek DeVries */ 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 * @author Derek DeVries */ 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 * @author Derek DeVries */ 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 * @author Derek DeVries */ 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 * * * // 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); * * * The second argument ($actual) is a string containing either HTML or * XML text to be tested. * * The third argument ($message) is an optional message that will be * used if the assertion fails. * * The fourth argument ($html) is an optional flag specifying whether * to load the $actual string into a DOMDocument using the HTML or * XML load strategy. It is true by default, which assumes the HTML * load strategy. In many cases, this will be acceptable for XML as well. * * @param array $matcher * @param string $actual * @param string $message * @param boolean $isHtml * @since Method available since Release 3.3.0 * @author Mike Naberezny * @author Derek DeVries */ function assertTag($matcher, $actual, $message = '', $isHtml = true) { return call_user_func_array( 'PHPUnit_Framework_Assert::assertTag', func_get_args() ); } /** * Evaluates a PHPUnit_Framework_Constraint matcher object. * * @param mixed$value * @param PHPUnit_Framework_Constraint $constraint * @param string $message * @since Method available since Release 3.0.0 */ function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '') { return call_user_func_array( 'PHPUnit_Framework_Assert::assertThat', func_get_args() ); } /** * Asserts that a condition is true. * * @param boolean $condition * @param string $message * @throws PHPUnit_Framework_AssertionFailedError */ function assertTrue($condition, $message = '') { return call_user_func_array( 'PHPUnit_Framework_Assert::assertTrue', func_get_args() ); } /** * Asserts that two XML files are equal. * * @param string $expectedFile * @param string $actualFile * @param string $message * @since Method available since Release 3.1.0 */ function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '') { return call_user_func_array( 'PHPUnit_Framework_Assert::assertXmlFileEqualsXmlFile', func_get_args() ); } /** * Asserts that two XML files are not equal. * * @param string $expectedFile * @param string $actualFile * @param string $message * @since Method available since Release 3.1.0 */ function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '') { return call_user_func_array( 'PHPUnit_Framework_Assert::assertXmlFileNotEqualsXmlFile', func_get_args() ); } /** * Asserts that two XML documents are equal. * * @param string $expectedFile * @param string $actualXml * @param string $message * @since Method available since Release 3.3.0 */ function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '') { return call_user_func_array( 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlFile', func_get_args() ); } /** * Asserts that two XML documents are equal. * * @param string $expectedXml * @param string $actualXml * @param string $message * @since Method available since Release 3.1.0 */ function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '') { return call_user_func_array( 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString', func_get_args() ); } /** * Asserts that two XML documents are not equal. * * @param string $expectedFile * @param string $actualXml * @param string $message * @since Method available since Release 3.3.0 */ function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '') { return call_user_func_array( 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlFile', func_get_args() ); } /** * Asserts that two XML documents are not equal. * * @param string $expectedXml * @param string $actualXml * @param string $message * @since Method available since Release 3.1.0 */ function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '') { return call_user_func_array( 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlString', func_get_args() ); } /** * Returns a matcher that matches when the method it is evaluated for * is invoked at the given $index. * * @param integer $index * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex * @since Method available since Release 3.0.0 */ function at($index) { return call_user_func_array( 'PHPUnit_Framework_TestCase::at', func_get_args() ); } /** * Returns a matcher that matches when the method it is evaluated for * is executed at least once. * * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce * @since Method available since Release 3.0.0 */ function atLeastOnce() { return call_user_func_array( 'PHPUnit_Framework_TestCase::atLeastOnce', func_get_args() ); } /** * Returns a PHPUnit_Framework_Constraint_Attribute matcher object. * * @param PHPUnit_Framework_Constraint $constraint * @param string $attributeName * @return PHPUnit_Framework_Constraint_Attribute * @since Method available since Release 3.1.0 */ function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName) { return call_user_func_array( 'PHPUnit_Framework_Assert::attribute', func_get_args() ); } /** * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher * object. * * @param string $attributeName * @param mixed $value * @param float $delta * @param integer $maxDepth * @param boolean $canonicalize * @param boolean $ignoreCase * @return PHPUnit_Framework_Constraint_Attribute * @since Method available since Release 3.1.0 */ function attributeEqualTo($attributeName, $value, $delta = 0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) { return call_user_func_array( 'PHPUnit_Framework_Assert::attributeEqualTo', func_get_args() ); } /** * Returns a PHPUnit_Framework_Constraint_Callback matcher object. * * @param callable $callback * @return PHPUnit_Framework_Constraint_Callback */ function callback($callback) { return call_user_func_array( 'PHPUnit_Framework_Assert::callback', func_get_args() ); } /** * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object. * * @param string $attributeName * @return PHPUnit_Framework_Constraint_ClassHasAttribute * @since Method available since Release 3.1.0 */ function classHasAttribute($attributeName) { return call_user_func_array( 'PHPUnit_Framework_Assert::classHasAttribute', func_get_args() ); } /** * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher * object. * * @param string $attributeName * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute * @since Method available since Release 3.1.0 */ function classHasStaticAttribute($attributeName) { return call_user_func_array( 'PHPUnit_Framework_Assert::classHasStaticAttribute', func_get_args() ); } /** * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher * object. * * @param mixed $value * @param boolean $checkForObjectIdentity * @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, $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() ); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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(); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 2.0.0 */ class PHPUnit_Framework_TestFailure { /** * @var PHPUnit_Framework_Test */ protected $failedTest; /** * @var Exception */ protected $thrownException; /** * Constructs a TestFailure with the given test and exception. * * @param PHPUnit_Framework_Test $failedTest * @param Exception $thrownException */ public function __construct(PHPUnit_Framework_Test $failedTest, Exception $thrownException) { $this->failedTest = $failedTest; $this->thrownException = $thrownException; } /** * Returns a short description of the failure. * * @return string */ public function toString() { return sprintf( '%s: %s', $this->failedTest->toString(), $this->thrownException->getMessage() ); } /** * Returns a description for the thrown exception. * * @return string * @since Method available since Release 3.4.0 */ public function getExceptionAsString() { return self::exceptionToString($this->thrownException); } /** * Returns a description for an exception. * * @param Exception $e * @return string * @since Method available since Release 3.2.0 */ public static function exceptionToString(Exception $e) { if ($e instanceof PHPUnit_Framework_SelfDescribing) { $buffer = $e->toString(); if ($e instanceof PHPUnit_Framework_ExpectationFailedException && $e->getComparisonFailure()) { $buffer = $buffer . "\n" . $e->getComparisonFailure()->getDiff(); } if (!empty($buffer)) { $buffer = trim($buffer) . "\n"; } } 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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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\Diff\Differ; /** * Thrown when an assertion for string equality failed. * * @package PHPUnit * @subpackage Framework * @author Sebastian Bergmann * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 2.0.0 */ class PHPUnit_Framework_ComparisonFailure extends PHPUnit_Framework_AssertionFailedError { /** * Expected value of the retrieval which does not match $actual. * @var mixed */ protected $expected; /** * Actually retrieved value which does not match $expected. * @var mixed */ protected $actual; /** * The string representation of the expected value * @var string */ protected $expectedAsString; /** * The string representation of the actual value * @var string */ protected $actualAsString; /** * @var boolean */ protected $identical; /** * Optional message which is placed in front of the first line * returned by toString(). * @var string */ protected $message; /** * Initialises with the expected value and the actual value. * * @param mixed $expected Expected value retrieved. * @param mixed $actual Actual value retrieved. * @param string $expectedAsString * @param string $actualAsString * @param boolean $identical * @param string $message A string which is prefixed on all returned lines * in the difference output. */ public function __construct($expected, $actual, $expectedAsString, $actualAsString, $identical = false, $message = '') { $this->expected = $expected; $this->actual = $actual; $this->expectedAsString = $expectedAsString; $this->actualAsString = $actualAsString; $this->message = $message; } /** * @return mixed */ public function getActual() { return $this->actual; } /** * @return mixed */ public function getExpected() { return $this->expected; } /** * @return string */ public function getActualAsString() { return $this->actualAsString; } /** * @return string */ public function getExpectedAsString() { return $this->expectedAsString; } /** * @return string */ public function getDiff() { if (!$this->actualAsString && !$this->expectedAsString) { return ''; } $differ = new Differ("--- Expected\n+++ Actual\n"); return $differ->diff($this->expectedAsString, $this->actualAsString); } /** * @return string */ public function toString() { return $this->message . $this->getDiff(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * * * PHPUnit_Framework_Error_Deprecated::$enabled = false; * * * @package PHPUnit * @subpackage Framework_Error * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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; } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * * * PHPUnit_Framework_Error_Warning::$enabled = false; * * * @package PHPUnit * @subpackage Framework_Error * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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; } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * * * PHPUnit_Framework_Error_Notice::$enabled = false; * * * @package PHPUnit * @subpackage Framework_Error * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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; } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since File available since Release 3.0.0 */ /** * Exception for expectations which failed their check. * * The exception contains the error message and optionally a * PHPUnit_Framework_ComparisonFailure which is used to * generate diff output of the failed expectations. * * @package PHPUnit * @subpackage Framework * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.0.0 */ class PHPUnit_Framework_ExpectationFailedException extends PHPUnit_Framework_AssertionFailedError { /** * @var PHPUnit_Framework_ComparisonFailure */ protected $comparisonFailure; public function __construct($message, PHPUnit_Framework_ComparisonFailure $comparisonFailure = null, Exception $previous = null) { $this->comparisonFailure = $comparisonFailure; parent::__construct($message, 0, $previous); } /** * @return PHPUnit_Framework_ComparisonFailure */ public function getComparisonFailure() { return $this->comparisonFailure; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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 * @copyright 2001-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @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 */ use SebastianBergmann\Exporter\Exporter; /** * Abstract base class for comparators which compare values for equality. * * @package PHPUnit * @subpackage Framework * @author Bernhard Schussek * @copyright 2001-2014 Sebastian Bergmann * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License * @link http://www.phpunit.de/ * @since Class available since Release 3.6.0 */ abstract class PHPUnit_Framework_Comparator { /** * @var PHPUnit_Framework_ComparatorFactory */ protected $factory; protected $exporter; public function __construct() { $this->exporter = new Exporter; } /** * @param PHPUnit_Framework_ComparatorFactory $factory */ public function setFactory(PHPUnit_Framework_ComparatorFactory $factory) { $this->factory = $factory; } /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ abstract public function accepts($expected, $actual); /** * Asserts that two values are equal. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @param float $delta The allowed numerical distance between two values to * consider them equal * @param bool $canonicalize If set to true, arrays are sorted before * comparison * @param bool $ignoreCase If set to true, upper- and lowercasing is * ignored when comparing string values * @throws PHPUnit_Framework_ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ abstract public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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. * * * addTest(new MathTest('testPass')); * ?> * * * Alternatively, a TestSuite can extract the tests to be run automatically. * To do so you pass a ReflectionClass instance for your * PHPUnit_Framework_TestCase class to the PHPUnit_Framework_TestSuite * constructor. * * * * * * This constructor creates a suite with all the methods starting with * "test" that take no arguments. * * @package PHPUnit * @subpackage Framework * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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 addTest() and addTestSuite * as well as the separate import statements for the user's convenience. * * If the named file cannot be read or there are no new tests that can be * added, a PHPUnit_Framework_Warning will be created instead, * leaving the current test run untouched. * * @param string $filename * @param 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 */ 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() { } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE 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 * @copyright 2001-2014 Sebastian Bergmann * @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: * * * value1 = 2; * $this->value2 = 3; * } * } * ?> * * * For each test implement a method which interacts with the fixture. * Verify the expected results with assertions specified by calling * assert with a boolean. * * * assertTrue($this->value1 + $this->value2 == 5); * } * ?> * * * @package PHPUnit * @subpackage Framework * @author Sebastian Bergmann * @copyright 2001-2014 Sebastian Bergmann * @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; /** * @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; $this->mockObjectGenerator = new PHPUnit_Framework_MockObject_Generator; } /** * 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->mockObjectGenerator->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->mockObjectGenerator->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->mockObjectGenerator->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->mockObjectGenerator->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->mockObjectGenerator->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[] = ''; } 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) { } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2011-2013 Sebastian Bergmann * @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 * @copyright 2011-2013 Sebastian Bergmann * @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) ) ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2011-2013 Sebastian Bergmann * @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 * @copyright 2011-2013 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2002-2014 Sebastian Bergmann * @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; } } } * @copyright 2002-2014 Sebastian Bergmann * @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; } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2002-2014 Sebastian Bergmann * @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]; } } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2002-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2002-2014 Sebastian Bergmann * @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 } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @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 } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2002-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @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 * @copyright 2002-2014 Sebastian Bergmann * @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; } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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)); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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() ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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() ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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 "); } 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.'); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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"); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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, "\n"); fwrite($this->fh, "\n"); } /** * Override to save the end of a dataset. * * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset */ protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) { fwrite($this->fh, "\n"); } /** * Override to save the start of a table. * * @param PHPUnit_Extensions_Database_DataSet_ITable $table */ protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table) { fwrite($this->fh, "\tgetTableMetaData()->getTableName()}\">\n"); foreach ($table->getTableMetaData()->getColumns() as $columnName) { fwrite($this->fh, "\t\t{$columnName}\n"); } } /** * Override to save the end of a table. * * @param PHPUnit_Extensions_Database_DataSet_ITable $table */ protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table) { fwrite($this->fh, "\t
\n"); } /** * Override to save a table row. * * @param array $row * @param PHPUnit_Extensions_Database_DataSet_ITable $table */ protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table) { fwrite($this->fh, "\t\t\n"); foreach ($table->getTableMetaData()->getColumns() as $columnName) { if (isset($row[$columnName])) { fwrite($this->fh, "\t\t\t" . htmlspecialchars($row[$columnName]) . "\n"); } else { fwrite($this->fh, "\t\t\t\n"); } } fwrite($this->fh, "\t\t\n"); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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 ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Matthew Turland * @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, '' . "\n"); fwrite($this->fh, '' . "\n"); fwrite($this->fh, '' . "\n"); } /** * Override to save the end of a dataset. * * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset */ protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) { fwrite($this->fh, '' . "\n"); fwrite($this->fh, '' . "\n"); } /** * Override to save the start of a table. * * @param PHPUnit_Extensions_Database_DataSet_ITable $table */ protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table) { fwrite($this->fh, "\t" . '' . "\n"); } /** * Override to save the end of a table. * * @param PHPUnit_Extensions_Database_DataSet_ITable $table */ protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table) { fwrite($this->fh, "\t" . '' . "\n"); } /** * Override to save a table row. * * @param array $row * @param PHPUnit_Extensions_Database_DataSet_ITable $table */ protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table) { fwrite($this->fh, "\t" . '' . "\n"); foreach ($table->getTableMetaData()->getColumns() as $columnName) { fwrite($this->fh, "\t\t" . 'fh, '>' . htmlspecialchars($row[$columnName]) . '' . "\n"); } else { fwrite($this->fh, ' xsi:nil="true" />' . "\n"); } } fwrite($this->fh, "\t" . '' . "\n"); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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, "\n"); fwrite($this->fh, "\n"); } /** * Override to save the end of a dataset. * * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset */ protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) { fwrite($this->fh, "\n"); } /** * Override to save the start of a table. * * @param PHPUnit_Extensions_Database_DataSet_ITable $table */ protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table) { if ($table->getRowCount() == 0) { fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()} />\n"); } } /** * Override to save the end of a table. * * @param PHPUnit_Extensions_Database_DataSet_ITable $table */ protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table) { //do nothing } /** * Override to save a table row. * * @param array $row * @param PHPUnit_Extensions_Database_DataSet_ITable $table */ protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table) { fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()}\n"); foreach ($table->getTableMetaData()->getColumns() as $columnName) { if (isset($row[$columnName])) { fwrite($this->fh, "\t\t{$columnName}=\"". htmlspecialchars($row[$columnName]) . "\"\n"); } } fwrite($this->fh, "\t/>\n"); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2013 Sebastian Bergmann * @license 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 * @copyright 2013 Sebastian Bergmann * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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.' ); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2013 Sebastian Bergmann * @license 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 * @copyright 2013 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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(); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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."); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Matthew Turland * @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 '); } foreach ($this->xmlFileContents->xpath('./database/table_data') as $tableElement) { if (empty($tableElement['name'])) { throw new PHPUnit_Extensions_Database_Exception(' 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(' 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(' 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(' 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.'); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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"; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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: * * |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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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: * * :: * * 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 * @copyright 2010-2014 Mike Lively * @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(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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."); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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: * * * * The filename should be the location of a xml file relative to the * current working directory. * * @package DbUnit * @author Mike Lively * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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: * * * * The filename should be the location of a yaml file relative to the * current working directory. * * @package DbUnit * @author Mike Lively * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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: * * * * The filename should be the location of a flat xml file relative to the * current working directory. * * @package DbUnit * @author Mike Lively * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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: * * ::: * * 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 * @copyright 2010-2014 Mike Lively * @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)); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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 "); } 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.'); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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()); } } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2002-2014 Sebastian Bergmann * @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 */ } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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() ); } } } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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()); } } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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()); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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(); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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(); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2002-2014 Sebastian Bergmann * @license 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 * @copyright 2010-2014 Mike Lively * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2013 Sebastian Bergmann * @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 * @copyright 2009-2013 Sebastian Bergmann * @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(); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2013 Sebastian Bergmann * @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 * @copyright 2009-2013 Sebastian Bergmann * @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; } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2013 Sebastian Bergmann * @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 * @copyright 2009-2013 Sebastian Bergmann * @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 {} . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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. * * @return array * @since Method available since Release 1.1.0 */ public function getData() { if ($this->addUncoveredFilesFromWhitelist) { $this->addUncoveredFilesFromWhitelist(); } // We need to apply the blacklist filter a second time // when no whitelist is used. if (!$this->filter->hasWhitelist()) { $this->applyListsFilter($this->data); } return $this->data; } /** * 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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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(); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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 { } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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, * * * Array * ( * [Money.php] => Array * ( * ... * ) * * [MoneyBag.php] => Array * ( * ... * ) * ) * * * is transformed into * * * Array * ( * [.] => Array * ( * [Money.php] => Array * ( * ... * ) * * [MoneyBag.php] => Array * ( * ... * ) * ) * ) * * * @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, * * * Array * ( * [/home/sb/Money/Money.php] => Array * ( * ... * ) * * [/home/sb/Money/MoneyBag.php] => Array * ( * ... * ) * ) * * * is reduced to * * * Array * ( * [Money.php] => Array * ( * ... * ) * * [MoneyBag.php] => Array * ( * ... * ) * ) * * * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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; } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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(); } } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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(); } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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'], 'backlink' => basename(str_replace('.dashboard', '', $file)) ) ); $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( '%s', $method['link'], $methodName ) ); } $result['class'][] = array( $class['coverage'], $class['ccn'], sprintf( '%s', $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( ' ' . "\n", $classes[$className]['link'], $className, $coverage ); } foreach ($leastTestedMethods as $methodName => $coverage) { list($class, $method) = explode('::', $methodName); $result['method'] .= sprintf( ' ' . "\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( ' ' . "\n", $classes[$className]['link'], $className, $crap ); } foreach ($methodRisks as $methodName => $crap) { list($class, $method) = explode('::', $methodName); $result['method'] .= sprintf( ' ' . "\n", $classes[$class]['methods'][$method]['link'], $methodName, $crap ); } return $result; } protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node) { return sprintf( '
  • %s
  • ' . "\n" . '
  • (Dashboard)
  • ' . "\n", $node->getId(), $node->getName() ); } } . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING 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 * @copyright 2009-2014 Sebastian Bergmann * @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 * @copyright 2009-2014 Sebastian Bergmann * @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( '%s', $item->getName(), $item->getName() ); $data['icon'] = ' '; } else { $data['name'] = sprintf( '%s', $item->getName(), $item->getName() ); $data['icon'] = ' '; } } return $this->renderItemTemplate( new Text_Template($this->templatePath . 'directory_item.html', '{{', '}}'), $data ); } } Code Coverage for {{full_path}}
    %s
    %d%%
    %s
    %d%%
    %s
    %d
    %s
    %d
    {{icon}}{{name}} {{lines_bar}}
    {{lines_executed_percent}}
    {{lines_number}}
    {{methods_bar}}
    {{methods_tested_percent}}
    {{methods_number}}
    {{classes_bar}}
    {{classes_tested_percent}}
    {{classes_number}}
    {{items}}
     
    Code Coverage
     
    Classes and Traits
    Functions and Methods
    Lines
    {{lines}}
    oONLP(GLYPHICONS HalflingsRegularxVersion 1.001;PS 001.001;hotconv 1.0.70;makeotf.lib2.5.583298GLYPHICONS Halflings RegularBSGPv5v5|-\`WhKqJx"U:r,/4\ liʚELFMƀV(gW\+rK0 Q3-O>Cdge}\4[DdpWQ@J[MUAНj.p`k*CI4ثo\ wfvXDlBg1[/a 2lE2g29MÊ zGDUBA$L}Xʕfz;N2_;(k@B[!6P3G E]{JW/s4%ߙ_}}cO-4lPaDX[qv*X,u * z3JL} 0VjUyjn)O0;0!-!r"&bbl,-`Q|/^LVRuzԪIЪ!k&)J{.tS?iSdiVD1w b]D*%qsPDẍp EG`+w:V*X<[lM .ΡShqk" J MT6 ckazԪnqm0pDJv咽Fv(S(MIӶFKm"=-B(>QeYeg䜊7 ._j&LK 9zRuC Rȍ&B0 _C_{4W?N"$#D :J4/횶GJ;]wd:H9®[Ԩ* K #8A$a`]ڞ-TE7 $ :sp†f L$}Zb]b6Hrx-t jViMjN^[8>Cn7L &+3W6G86Xnfi?4 }<4 ζfVGeb} s i{OEn#&QP6D*BLB1SRkDXX><|0;ڈ55C~4?:P}"%ut5I!9l$!yMT>' Otqa?^Em ߲CsS|-nH q#Yt k ¹Ǯs%}NJbCW/|`F\b,ɏ2H2/94# ~ecĩ"Q7:ZI֋]%Y*B;8aFxʩb_͟- *)4?j@5Q'P8Gr)ՠxl֏("c{G݇_xۢƴHE-Bᔡ`\_`TXiCO!;#$QCU(75D Ѥd= >dZ0tjgv2-ēxU  3,7ta,(5¶YE$6sB܉O c: : R.yaHX%1yL7Az5o*n5e)oFaDe`hp"QYoO 4ops0OE Y)b8x.k+8U)+6-]K9pQt&}SnmbtLMwXsSIj>ISj 2`%94}=JAvD j踠ؓT[P#aW0Tt-~zI,6U2)'\v SRP Znq"abErwL1U[n @G[9y3s;! r퐽"04{2 faJ )"P: 63'Z7\H59NTt } 損;wL.tdqwo Ή)"f.dxCz KFNǢhF@ᡰ)1VaP JV,B{&f pphxO2%8 QPL:eϨiN`ߟҒ]Q${3qN% Ot=jxgPΰFK^{f?^/ O\:JD;Q`c^!dvk e3庑aIC d6 IȚ#\},?Hf3cUw+$U[":}]jb(Es)`%\¥U.#]v/)K:Ic4ó.c$C?f `+6cx$#[ߺ f& h,A4-g`?$1 1bB5 }˟ X`h^2*"`PRooפ)jk7L"3|{y@պiw@&}g$su"򩄕_[n 7()D`QŔm>@cgDD~xp }`toHTuҁ)m7$',h XNrlu5_@>[ƍĬ]6ݏS@&ƛ2@4w|{ ߤ9.Fdqr(A1ƴ#ADp#6=rR {xP(Q@"ޥ&Ϡ]a y[J(%;MA ~NdR;>4hYjQ=yæ[`\h :L]}~0Ml0F#뗸S2zB!TC l-c:Tl占bPIS;KΜNWpw}R#;~ -b;} 3@=6]ӦؒAy0h)?(o^2Ri}l[=qĴP418󅷞8@BB8Rjp>ފvP-'KULRCa=r'}ݨkFp6HbI,Fo1r'"չ&&lI{&Qf2a\L)ARہQDX:vaiGGw޶ /0$O0&#H9o(sQƬ"MLjL7L5 y*ɚ Y%wt+55Z()͊BvMK0:$»8!0AbJ#9pB́@E(CuOP<|h sRynx@fr:„i1ZBLnѫrtI-1x,Fޠ1Sb'1CI Y^\UF;=6-T-H2G'8H9&$+d k?K(J'qj s`*L9y2@ a-*PkvW2F0(tTlhш%qA.[_g>9dMx,mw첌-{ 3tw61}Lwf馵G,h jZZ8H5tÉ@wi Ku|AIgn).}88F@*ʠtxV~JUw6A.0n*"1-59dq?5L8v& |֓I4$H]ZMUj/R-l\w׭OU LQ*`r }krmVӛk^vJS ''xQi_᭒d4(Qn \T-VB+ uxdFȘW`q NB \5#3v$O#ȧ,*(w\h;^ʻƪ 'NYmLʿ"TR Cy. >f D kDo9/މ׮=4fQ؀'k5B$rL줁tIL?P!>Mf0+^˪!Ѡ>5Ĩ&y_dA+1f+#X@חč㍊S.r;0~RP72ř|$oVXBa?^ b~*FT@Jƪ3}/SaUȪj1SaB7~& FMsϜ[>+ {1YsȠ@z(=!؆73މfze(<;oe3_'DZs5"b4gdHCoL5.6:5}9$MQ'$¥9DscM |)lIE9#C5LJ`fK%{P,e& 'S7a:np-ąKzHhw%ɹm|lߝʍȝte0q9S_z/L[ P{)x.{hLٷV)kٮq;jz@b2Q` 9~'32jF vQTdM@>ܹPNq޺HіJMrN2Q9}l̀ (6,A; +":(-$V3x6AT\"zn %*bo@oJLBqIziTN9Xj<39'LRB$eYĞa+(n2uCca%˂*w `‹B=Uf{(INq_ zh.3fKH f]N LԩXʍ=zRg}퇍ZUJ"yxqESZDXJN4HOV_X/bYmOt)r!)mFL.P@0cgrTxg=] 3A?)z Ua0@ zd0w"jZpL_T_C e )~oQRNx3Î|T"b, 2& cT6@1# ,@-#z|VcXk58WYP!\-` |)2ooD4}ئ=Lg}Pi9І.xpTsq2yǿa-GuNhXH8uOi% (Ck%b9|B(#U Yt='`҃ >N-'׿ ]69A0&!Ge! mܥ#<*L£U.1=RI2')`> l٦hh%H^YY-aA xq[ '@L^ q=BQGͱ2\K oD9xx۳I 8, OȉC;'2ouPp CR  {|녴p`4tvX @X+6zP?,J*lKh:MѰdC^fhD ]wJү!}7?fYƉA"SEiD2#ե$=4:{pۿs> irrT׎ ; q!u_n&5ҁW%7 _ c59f5r~JDR5e?[T6mf8Or*~$QcڏƁ;B=E_MhhR` >~<@34TGa8vf&G[U%H-XP@ K/қ@^0ݩ'f܍klش\BG]W?sX(Vz$F;]HP{*6Dcb-7|X|o~mssiBJ[0{V \=T%CJ͵m9<?fK]ɒCy{ PƏ뇰G^JH@ \쓚c~Rbʂ@mhVS#4xSkȗ~y*q6&gY? gb Xn!$8[E'()C7"ONhC3V,%(eR39IHC̼_YDb;s~L\ed5 i3sђ9ItrôikXJB5F޾Uu\-*/Usw b OĿmOn,1GG[ՁxeXujz zҳݘ-6`9e$v:]]@/ yB(zÎ / oZm'N;=3%)y 19FL(gRK@ ; \'']̱2ievu# qZ~15I]9, 7Ji)H)j-ju՘ OO/ p:/(;RBU7edINRH?>X0y8Pr#b _8i؍Cf`ȑai2Uyd=2_Db9@:q"ڌSpF~"6TDgtӆ +tHh7 >TLҌ $AQ+ @;;M~oS<:.g&`$"CPbQ,`$`|ʛW18<~$+t >N]-me B5PNcxqE}n B685 }Uf<)SbQRUk)LGS*F:Hp%xسR)s.̀RqWjGi<5) /򈈳2`޲h6`눯LT ɖn QY\;uth26WZafQr`dڭ1t-1a|Ұ g0Ci[[^;`FOpb^ū^nP mJSr4K*X˓ .cnnmEPhJl|c! !ZI>NbTpPu$k[C%- QջQL&B88Jtqic2HšE/'W^yRrnզ*paK#51=̺6 jC#< /I͑2 ;ċ `SXԙ$jjgI\dOX%=grj{yV PsJIfM!]INFn 1Da6-4KX8)>8 )q@PȒR2GI8C@hW TQ];K=_1a ȱ@xZ urd`_1T*Kb{ p-n+W9?.W*m*nԤ'.CACdýDC1n*k]F  ܴOl7i%cXkԺ%i(ε=r$DyU6ʉ;ca k|Gr:9mmW^ÞXeUADQ_«tj$Uh4a| a eB CUMҵhރ8wƤiip`g6ρ#Mtʍ?<8W^%xpf1Sq iXYZKT6 /5QtΦhEzp)HJXC ΐR[S} qT/E:E,2P!ZNĂTs=4阃RNSwy#d8G6<` 3YˤM=9fts4 q9x0šaEgE7 [3n()* l<`T&v}Ou(! `4HAXOе>! +҆5! 0`!WB4`1@ X@( 8 L@M@9zOkU;Xj!I X*^vڥWj:vڡjܪn5ZgjYj V->"^ĵ+J!: ʯ dIdrRZZ$= btȨ΋\rCAt_X'.zbf0^f D V767f/>/IW+ A '6NAڹ‚g"  tTҹDLd@C[1M.yX-'GLB_|־Eg\MƗM!PS=*yU؆\ ;9BGDxj*e˙N-b ^IN۶gW`)N \$x+.0ћ2Q[SC[gX %|;›dDsj|[!8d &y~:<9\H@0wAT)C|%33H>0r=161P.*y4[ŦkD4>0ؘBlab "8>O''FdA7bmInv>)FZS2yb2j/3(7FĬ$G52 f(Ύ94I%*2"vX-Bxp:kԝ\ %("@x/gF T3 )|;oX9R(ogPQ*:pJfuvXص!RzQ#ACqi!PaY2]b3E6PHu~sFxR$HT`w,^[4:)6l~s9_2!. g ?i)eh|Ga #iejDdAo` 9$S)LEvB,/ePa 窀JI??Qg*[99{ Ӧ3{CK%:GJxI|ѳ`NeL輺tr6Ӻ-\jp-Q ¬Sl|ȃ62ʫy8_$*(#+[6 V#iS7u>z&Κq%]Pр6` Fb"2'-HQ{ /Wkc$/sتyn [@7 w 0aVGΙ }' C) -xU"!9[ϳP(pCZ,*BFς!ns#P#Ȣި>|E+ZSndMOH2 L 7ZCCS_#NK2 D<sT)Ĩ xy+YDիKjzoZQ$:^H1d)&II]u20.PUVYzsF;&np*Z8PN`D @?#x"pLB^{Z-ED]v(М` 1 Cm+KJ] 5]Mi h0jxyۛHy:TAuac)ysoܘaSG)$ ux" mTqvN@[Uj43Y n1i {N/Tj5fc絋X̽99@06| = R < vlb28o Q@F;D:l,ecd-Bl mXLL=#+Y$}n£{)pBS 4Jw.dDP#|%Jp+TUY46?qj,sJT`Jb L(7 qyK&M~ ]g7WE8Erty.GxB5Cfr!h{b#zpZِzNd,gMY})$O;- yq}fq7ֵ HS1R&~ZO(]4fFNHPg6y1ÕK*R[A1APȔS$, A'bCp P4>Y!Ov^\s(rЊۨn p) pi5UYZDtY:1Qq7/Rk @"B?Аox4 s(J(qoc^EcѢ4,ГmXh(b imE e&5C1yvI Z&yeQ`ovYIH޸XB{Π 0\#A4$8ЃΨ ZhN}hة%P}@ ?5d19.PŠjcoWHW G!N4K)f>-tnY4*cN aևD' &_0M& ^ژb-9?enב޷ 򂇥E,d!E|KOP :Yj٭O{ Cfm!X w2\~h&;ꍝgPҲxz_9uDy"H ey|ʠ'[qr|#Rr_kR=y8X]8w=Q-^f6,JEC0 G/Iт04Āc9]"9ÄP*R#LɻXz438/߹zeF$1_IVF2QX).TcfgWUv!! 6B"&Şgt9 hdEpj-ہʁ+~^FsR%a4/}0 Q'`EnɸٕtձW}9 _2PS0Ԟ!%RpB q <$ "ъm|BpZ*dğ_~/` %7y+M"fflnYl SyaU乒+NPZ@_ہ;DTYG:ID"i +9IL{Ћ>AD4EEq WJeE|96pX"HMI'$|K'FqB?Yf"%0q?F=O*æ:Cx*hXԠ~UČ>wOFF[@FFTMjUGDEF OS/2C`gKcmaprJ cvt (fpgm$eS/gaspglyfN <3!headR46bXhheaS $ 2hmtxS<locaTP4VNmaxpU nameV|ԯpostW@FiprepZ..+webf[XR=  .xc`d``b `b`[@1  xc`fidt! B3.a0bPp?G  I0(00 a x͑?K`mHPDwZ]E :8 ݺv"isEC]|%"2$c=LZMhcHȷ ӭ@r]5UZRG=hMԖvC*#4BCqGJ])qhA}k%@G:ANF`M̓(R<'ڈfYQ*.eYW_|ŗ.w->S>C+7-6d_)_-wa7Sh(x]QN[A  9{ Սbd;i7rq@D گH!H|B>!3k4;;sΙ3KʑwkS$6NH덌Zlfu є;j=o)M;Z ;4: !qKͺb00.?R4j˰Ѽ34@Skm!qK˦6$tUS]`*́Vy &ҷ$, b 9@HƼIJ;ㆵƑ6O'ӿZxڽ `9ޛf1+DQ0Q0c4I^/ޖX|6-Yϙ!ՃF gТ%g"7=^uF3x ]}EWt:基𪯦1Q~ {Myϔ Q+-Ƕ"9FڿſȟHLQ˜ŗ)%3'KVZپd<&I__`XȸFH{xz3$d鿟z=C8[~vt{^0f&ǔBU`Y2̙s80MJ+F)y;&R{}bM;̗gIIańDzA$8f[o_~ ?kunrX\=s_]rB{@>]fr{ czr(񘉇+, ~{n&u=\ ERgg|>(vT Dr Ou,T!g,}ˎsGʝŽ?|?y%Ho_"^c\"MTG wR/W٪([+Gw18u8wdgRL'0e9- ()ҚU%SlU-83JGNqU(*Ӳ8Cr#_grV]( WJKu_k[4<*ED{wrR )߯8RsT]/JAQrsrt^:0~_x RNǶ֏0|F'0dFוd2HI 1EG?J-8LϖN|$OaLdL'p>\ BǷ':m8^ܰ3‰0 ='㾜9 jJE9CEJl!-JsL/~k,PgSr!әڲB@RZ҂*mco knfKwS\ l$}TAg{mEy|x/KrJsUc0aDhiG>8]4<=}Qf|?v#ǿ)(2<08H*DǾ#z: [?.d.@Nu3D0 IP} A-5VM RP 9%TUrs՜$hs2s6L,(}@z Wi)U@ PCK}N)׏.2`XV˗P`>.gܥΓ='dl3پD+ }Ͱ )$SB* 5:I(Ȃ6 J^c,4:܊[ =d[)43M;ɗ /̭{Q2:^Fr6ϞmO{ Hp?kr'w }Ճ_nNsȜ;ə3dm֟mB)~kŹ ,,L#ۗu *&*.8P!\uZ]ì҆i9F% ByL-Uꁭ[Uro^끋z]gPDu"R_I^nzB<}x,N[VGe}lN@3M$kq{YqdvXGk5 ]LLu{͇PW7Q=L_2@:Y$^s- mۋr]mFdbLN\X- hfI!"):Wda=']~ա872gx)) ΪE![xYqS èJ^@p\$prüG䵃p̬(Îw˔N Oy𔑈6][[x[Zݺ=M=}߇dO{gO|T Aj+=0/UZb 3CNx fdac$9Oɳ?<;Vm=o6=+@95=1e+S $;.*˼Mہ*+K5 _W ES}~ԏ"x"3+2f5HXB d$(-{wT7hp" _5LP_Q{lK$G=G7}YS+vUv! 'eէ>*y6l΢M ,e3b|ҋEEW2bq"&FzYkOēˏubTpL} O.MG\Tg%oGo3r}SB)H lÉ!A'I8'[әU alŌ8CN*Y4^ {r,$"Y[ ãsDbV\@ˈhА{(,g _-l9j$w\ެW'n-\rU}aiT[eS?Tg$3`-fqxi0Fr{\L9չD3Pʉx,)F8< h `/Z-.D 4ZJ0F%!;fG&WU*Juʖϒ;Ļ$\|gUZ*˫y(N`eJ@LT} Xڧck {өلݳ_084k6%~OTݒGљ G/"`TC ]́$(BEMFEF,4Qxvi棇^Klel !w%zQ[Emd x hs4?>Sד͚S8jI e\[iP0leQE}L+KkWQH\&44!<)+ |J?q]" Ž}_9~NMtO 6q ^sJZfm(݉ϔZu-4Lah>JX`9ɓۇ[=V:k6whToU'YatCp .VQX0C"0+DF~C]`>ހK0$B(mAGe;5ߖ1 ۹啯r g>%}k)' gLg˝e껗V6>KWnKR{#AhĀ(t!H売s蓥+LO[u6:#0nL/p'Oo⩄v_{ s_ s`Sn2kcQw[#TPj.Z0[@Q_CO9 r4_kksdZ2P-Ҥ$l`丘яKH?uuqȬODL-:~Kh~Cs:͡YM .,b51+AL܄:B2-K h 9^ ǿeOAcfj`f0`eD=I@445 )J`^MH8Cgs90p[=8>U[ j`Vmo"5lWfʳ?kqFuH]N)qгGhǵW*?: u½M:4sZb兵| u/\&aߏtuEܑ.0=t 5s({>aris=@$+X] ]Mퟚ87R#Fݺ&t=^wWұ$=he6wq g$#< vG !{®倠3֤$ GXCk*&^Ty{uڅ ;+:gx.[qW{dtşE܏:x|MbG׼Zt]hD& b€FюCˉGer̬~`78y F4[fSɾAsW-X/M|i5O/]g~k_yi\}U{x7(xѷm%Kgf& k:Dj8KӢKH _Ԇ԰a8FQH bPB%O.H6^&(:IcD̀b($m4;}yrueIwoh+ow޹0K .[<ϽR3feTU1k٥ ^E"SP+`/FL֧lka.B$3b c`o]sddY_0{~ -k=H41S2 uȹ㵗7xkqS /0* eDƫm^'-3")kh>2-ܡGI.P[:C=?Z~$3sQV=pYD uJ./LB#i> 0YبHFI>$fg 7= |O} +ie/Ճ/W3qE9h Hd-AOS*zrXэ媋OVrk%}YB?݉Y~z5S I2~'F4{`Ԁ~Cxz̅2œog{7$B.-(_V"w ]/# S69r]{%¸+Js6~i. C:p C#7",0;C~ "*)cDc s5(4!Yy<3ws&' k|Gauh|Y֪wݫN>AۨNuThPT ;Oͣd/{H] 'Nh-Fbm[?f׍)&a qs}3~%%Z3 3)Y ٨>vP"cʋұ|4Y144GKj̇3B4Y{9Je\s{g=;CN'b&q"LqDd7MU1׈wR}OEň'&Ȩx `+p1KpZdʎ@4Gʶx7LC\64S- 7zPsb_,sÞ"L +D,ڵ8^>7L fe@A)OTq8Ws TN^WlrO|+R O +έ7KM߰b~4E_"9_ Xϛ%~3Esq4/q Y'JZxm8}W W1SU'Cp| 9vNgwTs?_/${@r^ av4'N&])PӋW>au'?owE- 8OnXW>)La8VnJ1dᱽlD>zIu_֠}v,ҭC`QO2P/@s*P74U# ?$/!yl/|kC دnzt3kSɿR Fq ^u+&԰`[\(kMȔ'K7NI7o&ΌG`~/N{ Ql]Wb$7N8nޮR;׶cm ͩ|qf9ZJCZfit 5/JƵ,8i3.W!?oA|3xǒHߎv3o(%ix{ dN$Lczae)=9 ԆŸvf襝ѽjghaw1'Eir כwTMUN ^zbXBm aR±1P%>Gz?J Y,{is\~Wy 7˵hbX=RQou%Bh׀e-/#}'YZ;ˁ)^MRaC:4|0&1-V 48iz:s_t-eW9qfy7M7*ƿ24uo:{\w?ß^3=U#{3Ϻiuk6+ZZ^!ΙK?fpQR[UJ058gFMq{eX }a.&_cS>ٗJl40#nK y"#39[kECg1;9l=˙||Rjӽ|!g8Qx!VWН! ޙ[#7vKPxԊ.)7zf_2)5X!3EλUަ69-k[җ`ef2 .OUeN R B BTYs hjo@c6lY!U@4Ҋ 046[~Ŗ/~q5fw^yJ+)f{Qs%/Ҷn ׵a6}ˆ3wN,L̝Xt Y/ohmi `  '1_cΚ%:lP/_3REq;͡ؿ8]Ns{l˝-wƍ`+~%د+~v)=t%jFp:H[םMd`PHz-<.lS~u+cLf3w,o[w_sѓԭA}&_ڔ08M6tض"/13g%fh9z| $*waVc(rsGFIP9Î8e͒͝儯VZN%`hðKP| "dH\0bh0&>'ٴ~zŠ7۽=2^~X}ZGGkMiY^ѼlYFp5{'ua(jR9eV1F? 9_va.)T4ľ_0$[TKa¸@>i~YФm/eǍ3Bk|[}M(\`9pz@/)pQR}X OϩO!ˑ(ll1?֖զ:Im25UN3=4oiL2 /Bגu'o6"G-j'4-sW`a&"OZOzWQKCod ;_[k,su `вk eitÈ~ %0L;Hi^rÆqKr3<7X aY 3bsU_Iȼ0 GXAE} %G=SQߵYIDNV˭gh^ ,u6WhFk$2՟-ӜfC9G T,FTА345yWt^mt{3ަ.^2c;HM7:"rz_ JVq6$w+[PSAAԷh)K ;% eov?>z,\5EĘ44vcXk֪w`D ,m-dAGg$D%.eqhH:~h(~y(mpGݎm>\\'#ŮNnk~_ r ڰ%:r3jz{6USglvaaaiMڛh+@԰LEwօ.p^ݭtªFA=I9 ٣OzXM"0S<0> "7Q w2 ȓ鼄h5kt%4Cۋh{h|-9.Zrm7ͨEr݀~I¦V@9OH=3:BhIV*Az2G,MLbA.tXE^՛ MNI1569r]jXy3'!˗%=E}ۖr=ˆ;Uӫ/d8ZfSUp8288̓'43t}E7=iC]6tȺ}VLzM6`AD2=\$XP=%~=zC,H%]_}`r7]` 4lPb%7u-دUKKaWI  <@tm+I=DzT}W^BaFb:Z{_޼>)rRi$#6_\G>sU8ichjI.y25mm"}F)͖LYJ CNi~ G c2> K:i:3ǸZf;QvkVL 4 =+`UQW}M߫`H/8Џch'ٷkW^~/w>,a~wlwVS(,ӾrYIZ )$Qk'vHjpUvѸɂ‚٦NZO~XJ08h[0HR ?03;=|F: k=lg_G0niI8J\,epu>O-lzʹZA' tq$"«'l\Gڎ v΂ #pO>6ﻢ-oÇ;}\noCdo, RU@UWo`J)9ٯ`SRHr9jDaeqU+0,7%~ 6 jf7P@’y3GgDrgl:kNWk)twaT95{6䳶ӎ sYsWm:mʐCV :+*KnM/̌jm y^}#F$ƺϵF ~1ͷǯgԏ#d X5`fl}.8|.D5h~ uGavTL)Xd0mY\cNJ'㊗n_ :/72Có|gl\ym fl<`ٗnϦOh,ϸyI_tjiIþS/=R7zh5O@` mz>`'@. &D/13FH=˝Fl$~&Fvq,#dYvW=lYŸ߲om{rpddD,MWށA%y4VzdZwkU5 ʦPU\Q^_<'\VhڡE[R6ұ 8K?`1Gdo/+W@Ł& TZktt8HhUx'dOvN-'~R GR0=cr7O=.INHwcn9e@f].Y30 NodnJ :澩ZM0WDŌnmWo0 Wܘ1pq4|)q FĢw7M_Iu6=,]}y19w`'oѬB[ywKk{]bY+Ii9NL-=]3/YخVk?a]L\׶ Qmt:k~@ ? *v(aMlղ>i*RilOβ@_U;5Rҏo#bN9k'; KF,u j hIJ>BCK(>I紌}ђ4C&5lc~e7>v5y$I3gK/D fۗ:eSke(YDhfke{ g/_ݻ9$u7C}Vڬw*Z w5Dj?ņD(%+T4.Y|gi eFiI ݂=VF ~Ƙ!mhbZbx`o;͓rFGC2@>K8,m0.-#_,Ԅ]}ndrMiDX5ZH.*"fGii h8QkT}1"9x:[ !hW<8: * 4q:G, (|ލݴ{`X`E>;S8X4DD|qHP5M5@[iġH?ʕDR p&bjD\T;$`Rl;I,f|m58ZK/X핓jփֶ@tڶkx^0 |,t^I\ux+z3[՝w6O-ԂcX=EQ\T+whjЋ9 ThPd h%Sjfx%!tFX&Y!K}#iu#G~kxcFx&,C4#?<" wF96a%hLl fK S_+ZcPdD@Z" cB'_._Z{[Ex0>lB!.^Aw*Ō%F1׬%CcYy)o&"Îg<LT1-^`whP@lCM@ieVp: U$Q9 iiE8V-c5ѠHm"딠{ݴB j@MˮUT?eQwȟ'48{eup2r!%ٯn<&a?j?xdA.PqN+ǚ3Ԅ잱 !uR&{ck2Hq*̥ FH#H|#[6<왲1R!ZJ4'k^!MsdZ1:n,x#w؜])V,< 諛CôbP?B'esxBmD`*u$~Dˣqw٦~!{5dj7w͍` Nn^m垨࠰L>+DCg*Bii(8 NOX?!M_ Iݔv5h破sIctro 3@:]ǖN (`i9%$v2@NJfM)hVFͪ+ 4;z #>RaixLx%$bG BV[CHNFA(-o&(TPh_=؈%:6:g2v@\]+z:2z'kŘ Ɩ΃{F7c 氽IIn,Y9|\dҩ#ZZ+ > S"Y-hU4Շ xc@n$jOP9J 3!at[nz`ֿ_ѣzh iDrL{^Z]6-fjNيK>K6ag՘nRGa&EڛPgbxyIlVOFV n k`jD{`s1 ڏoe#^)΍46^0CF#m9%W-Vڻm9)|Vxk&[hSh!-I~>4pKn9(8@Qɛ ͋-X\;2ݖ$w[Ӊ,9k|Nrgl'?̴fLٯk R@,hZ8J*دnGe)褢$,sN4ZtuEb 0ScPiWk؜b}v86[qq1.!!|F;a.7a'0MRaN"{;_<" xz][v;wht|~}w<{awq{l(><1׷_ 㚡y{'eJ#/Mh_f`YhP a.+Q4+Ik%/v?cI$%Wn^B.vH(d2nŭo;3AoA2YMKV#vxR1)b .EڢVK}bp';FD4=]%=}2}zG7nкWvOsL;ڴvoJ;!MTi zZ\}B~p4&&>KJ漢jlOp힮}>%֡u#d[V9<qa7nr\u);T]xx׮<#S9uR/ ųآ1AY*.o%6i:.$<.vk߾=yiq׮ݾ[fMqZ:y:Bg&̇Xqۉ уp3 hUO)flڦbӮcW 6#D`S5űU|>24  Nf8>L)ZU5 SI0duf Ɛc~^U]4)+)5aQh^8>ydk=N$HKs+)BH*$iirߙVhhRCxc㺇R^_ч)ɻ& VY]Wԯ6NCDλиw;A:-àfMp ϖ[hNK,:@Q,>TwĶxiJuVb.>Xv)AbQ a9ʲ?V@,:Q'B Fxb| ~уI 7]V옩bҪ f6j4>kE_) f`|thO]NI{2 G%36@0$ D`;.['&%_%;̠7yOcտx `slRـ uGf1hV3䬉`h||k'9/(_U/~xS 5蹺} FI`PCÌ fݻ`Vz-N kdLe "7y8t |f]۟/X4 [t9;p)/y#ü@~- d,GZ:S.{Jɳ0.xc`d```dp\SO 9_@ f 5!j`aXjz4#f1Y yI!+VĮl~(zP T;uv43 ' A g {c P<n@ H !‡Q^@,*L@ gE ,G 0  'G(Ƅ&dAg@)` sP!HO?*R|xc``Ђ4% cc *s̘f0azǬ5MͅS8 88pqqpupǎg o*>+.;7|: NJ%,&'#$KTMtX-q6M$u$gH򒪑&uMꉴt6_dddȼ5=$' %FM~G l Z n y >)f)QrR:\NEDe3U9TߩEuS{Χ~NB#Ec<7ڛݧL/Mo/}+ mju8v'O02YdbfL,l9y?[,%,#,Y^jfc]b}&掭 ;;=v g909$8lqTrpùK<QˆxڭRN@4I8 "xFѣT(BTgŃG@ç`]$ivw|S/h+zX1#óQn“jO O!+#Px3g "=!߇ahn]w,囖&<5ب#G4Ha·vp];Ă߀\>Ɛ/wUUΗdn(mzWC}=G۸aEbgRz)WSiyDSy=u2XtX\@ j NUqrX#X-P>&]~6};ʵϪ@B 2W32,2c ɈxmUהeFـ`ݭs(*vwwwwawwǁ?Ÿ^3kf?5k:c: :E?;0333q,x&(8K$R,2,XXXUXX5XXuXX ؘؐMؔ؜-ؒ zT4ٚmؖ؞ؑ2`م]ٍك=ًه}ُ999C99#99c999iLg's 39Yf19yY|\|.B.b.R.rJjZznFnfnVnvNn^~AaQqIiYy^E^e^U^coo __ ?? i3ϙ fvS; pn-ʭmݾ;ypqysgFna_jxx<|xk'vb'k/b/bW+ {^aW+J{^iW+*{^eW٫U*{^mS۩vj;Nc^^ck5{^kkZ{^^^^^^^^؋>­{;GGGGGGGGGGG}tG}tG}tݧ?????????; =]3@KPXYF+X!YKRX!Y+\XY+RXFFTMjUGDEF8 OS/2gKX`cmapJ rcvt (,fpgmS/4egaspglyf3!53#"'.'ddqd%Kup<3LJ9D?{dd 09C3JL3akw$B d/5dZgj7X0,Z>d.6dJtB+0W5ju.xL//+01!!|,1,A/Ͱ /+  99013!264&#".#"qOxx.,,nBUPrawי kdL 57% P,XX,dpX[ ,%'7'7764/&" MZfVc $ pQfV\ '  3+Ͱ2 /ְͲ +@ + +@ + +01!!!5! ,,dd&L &7>5%&7>54&&$OAXX@JOWOFS  @JOn)`*^r67)Q7q  OY+/Ͱ//ְͰ+ͱ+$99 99$901 "'#" 6& N,mwȃȎwm,NldXD/ְͰͱ+014>>.d8Zwwy,0{xuX6Cy>>yC@vS-IDEH-Sv@9yUUyG !3! 7Hߒ p??G  /3Ͱ2/+01!3! 77'7#'HߒCIJMN p??t⌍155"&=462#%??%d3||3d L #'+/3+ͱ 22/"3Ͱ$2 /&3 Ͱ(2/*3Ͱ,2/.3Ͱ02/2334/ְͳ $2+ $2Ͱ2+2 ͳ$(,0$2 !+%)-1$2ͱ5+ 9999011!%35#535#535#535#535#!!5!!35#535#535#535#535#ddddddddddXXddddddddddLdddddddddd|d|dddddddddLL/?B +,3Ͱ$2/<3Ͱ42@/ְ2 Ͱ2  +02)Ͱ82A+015463!2#!"&463!2#!"&463!2#!"&463!2#!"&ppXpp2pmppmp LL/?O_ov +'+/Ͱ/#3Ͱ!2 +@& + +@ +/(/ְͰ&+2%Ͱ 2%& +@%# +&% +@& +%+ͱ)+&999%9$999$999901 "'#" 6& 53533##5N,mwȃFdddȎwm,NlYdddd]+/Ͱ/ /ְͰ+ͱ!+$99 99$901 "'#" 6& !5!N,mwȃFpȍym,NlY+E/ ,/ְͲ +@ + +Ͳ  +@  +-+ #$90147 654&'5".;2654&+"ҧg|b|g[՛[ddX(>7xx7>طv՛[[ d 0+ 33/ְͰ+ Ͱ  +ͱ+0173#33333d,dd,  PGQb/PͰK/6R/ְHͰHM+$ͱS+H =99M39$9$/99P99K!'E$96+A9901732?6?67'76?654/&/7&''&/&#"'462"&P-<-1&("/&./80PP,<-0&("/&2,;.P g~~~~Y!)&1,;.Q  Q,=,1&("-&3*:/QQ/:/.&0X~~XY~~d#'+/37!+$Ͳ(04222'/*26333Ͱ/ͱ,22// 8/ְ$Ͱ$%+2(Ͱ,2%( +@% +()+0Ͱ01+-24Ͱ 241 +@4 +45+ͱ9+015463!5463!2!2#!"&!#!"&73#3#!5!3#3#d ;),);  d;)D);ddddd,dddd2 d);;)d 2 n )<<)D,dD , +3 / ְͰ+ͱ +901 #!!!Y|pXd" +/ְͲ +@ ++017463!!#!"&d  X,~  ] ,  /Ͱ/Ͳ +@ +//ְ Ͱ +Ͳ +@ ++ͱ+  $9 $9 $9 $901$  $ 6& 33DVGdD_Vd .+3 / Ͱ/Ͳ +@ +2/+01#333!#3#d)(1,Pp,L J + Ͱ/ Ͱ2/ְͲ +@ + + ͱ+ 99  99011!3!3!%35#,ᯯ, pdc +Ͱ//ְͰ+Ͱ+ ͱ + $99 $9 $9014>2". 6& 333_ޠ__ޠ\TPȖޠ__ޠ__Td, a /Ͱ//ְ Ͱ +Ͱ+ͱ+  $99 $9$901$  $ 6& ##DVOD_Vb,, ) + Ͱ2//+ 999015!#!"&3!73!  2,2aD%  F /Ͱ//ְ Ͱ +ͱ+  $9$901$  $ 654& DV:)DS/ Ͱ//ְͰ + ͱ+ $9 99  $99012>5# &632!&#"[՛[nv՛՛[[vbQz[!z+/Ͳ +@ + /Ͳ  +@ +"/ְͰ+ͱ#+99 !$9 99!9  999014>327!7&#"!32653#"'[vƝppIp[vƝXv՛[zpPPv՛[z d #'P/3 Ͱ2 /3 Ͱ2/ 3Ͱ!2/$3Ͱ%2(/ֲ 222 Ͳ222)+013!!!%53'53'53'53!5!=!%5!%5!dLddddddddd   |dddddddddddddddddL#J+ / $/ְͲ +@ ++Ͳ +@ +%+ $901546;5463!232#!"&!54&+";)dvR,Rvd);;)|);,dX);RvvR;));;dLL+/ְͱ+0133>>7.ddd3&Ͱ62 /B/ְͰ"++Ͱ+2+;Ͱ;+ͱC+2+ $9&/$9 9901;2654> ;2654."46;2+"&%46;2+"& 2  2 cޣc   X     ,rr  ,tޣcct 4  4 X!!7'77',,GGG GGGp/ְ ͱ+01!!%7'654,,EojCV 956nb<//ְ Ͱ +ͱ+ $9 $901!%%7'65477654/,,EojCV^{wQ57nB !/3?CGKO+0D33Ͳ)1E222/'+L333Ͳ%-M222"/33#Ͱ2/H33!ͱ4I22P/ֱ22ͱ220+ ,223Ͱ523. +*2%Ͱ@2.% +@." + 222%7+DH22;ͱ&J22;L+B2OͲ9=F222Q+04?$97%()8999"89$9#:;999@ 67<=@C$9011!#5##535!535#!!!5335#5!3##5#5355333!5#53!!5!5353dddd d,,dddd,,ddddddd,,,ddddddddd,,,ddd ddddd dddp,ddddDdd  #p +333 ͱ22 +$/ְ Ͱ + 2ͰͰ +Ͱ +Ͱ +#ͱ%+ 99990153#5!'353'3535353'3ddd,ddddddPdd[[[[[[)+//ְ ͱ+ 99901463! 2764'&"  SS D TT1+3/Ͱ2/ְ ͱ+ $901463! 2764'&"%3 '  TT d 2 D TTD 2d ?+/ /ְ Ͱ +ͱ + 9999990137!!!dddddL 3 4&#!"E~ 'Y%+Ͱ /Ͳ  +@ +2 +@ +2(/ְ Ͱ2 +2ͱ)+  '"$90153!73#5!!7.#!"7>3!2#!"&dXd5(P>^ > B&  & dD||Z   dL%-1o/%Ͱ)/-Ͱ!/2/ְͲ +@/ +'++ͱ3+9+'!$% $9-)"#$9!.199 /0$90153!2654&+.+"#"462"264&"%53;));;)37S*)R:. );dȐ>X>>XXd);;)X);E5+);;;)pȐȐ X>>X>^dd5"+ 3Ͳ 222#/$+013!5".?!#!5&'./#5m)>$\R+5"(]q *k.tB6,-WBB*. 0 Ɍd )1e +!Ͳ +Ͱ)/*Ͱ1/ Ͱ  2/ְ!Ͱ*2!.+Ͱ% ͱ3+%.9)!9*9190135>54.'52#'32654&+532654&#d); $x!" E4+vOȡY}^LlY3(; G7]7( 3AvFTMaTZd{MRao +Ͱ2 /3 /+0135>76&'.'5!Ms (G !:" 0G9C/Q8$99#'% 4<9 %~+/333 Ͳ +@ + 2&/ְͰ +%Ͱ%+Ͳ +@ + +@ ++ͱ'+ 99 9 901'3#7#33!3#4.+!57#"KKK}}KK}2.!"dpd"!/ c,' 2dd2R '! %+Ͱ/3 Ͳ +@ +2&/ ְ%Ͱ%+Ͳ +@ + +@ ++ͱ'+% $9$99999901?!55!3!3#4.+!57#"! d2/!"dpd"!.3}KK}}KK,' v2dd2 'L/?53!26=4&#!"53!26=4&#!"53!26=4&#!"53!26=4&#!"L X2ddddL/?53!26=4&#!"3!26=4&#!"3!26=4&#!"3!26=4&#!"LLDD2ddpddL/?& +Ͱ-/$Ͱ/Ͱ=/4@/A+01=463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&Ld X2ddlddddlddL/?& +Ͱ/Ͱ-/$Ͱ=/4@/A+01=463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&LLLL2dd@dd@dd@ddL/?O_oR +L3ͰD2/\3ͰT2-/l3$Ͱd2=/|34Ͱt2/ֲ 0222 Ͳ(8222+01=46;2+"&546;2+"&546;2+"&546;2+"&5463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&dddddddd,    2dd@dd@dd@dddd@dd@dd@ddL *:J /&3Ͱ.2K/L+90153553#3!26=4&#!"53!26=4&#!"53!26=4&#!"5;26=4&+"eɦddX, dddK}}K LddddL/?CJ@+K/@ְCͱL+0173!26=4&#!"53!26=4&#!"53!26=4&#!"5;26=4&+"3535#5X, dd d!2ddddL&}KdK- /Ͱ/ְ ͱ+ 9 9901463!2#!"& ,,,,,,,v,,d,LY +/Ͱ/ /ְͰ+Ͱ+ ͱ!+999 9999015463!2#!"&?'!462"Xd*J%lNpNNp, >pNNpN= +//ְͰ+ͱ + 99 999014>32.'&73264&"yz{yII99 "c]s+?—jk֖|ׁ~rBB "koKk֖I +Ͱ//ְͰ+ ͱ+ 99  99 $9014>2".3"_ޠ__ޠMޠ__ޠ__ Vu%4>7.77.'&6?uDmssIOWM?%N~OrÀ~[[.  \7^`GvwsuEYd;^~RlbJ(I43nh!&W+Ͱ/'/ְ Ͱ +ͱ(+  $9"99!$9 "#%$901463!"3!26=7#!"&%7' 7/n);;));ԥrkqq\,;) );;)}j2qkqqUL.H+Ͱ"/'Ͱ /Ͱ//ְ ͱ0+"$999 %9&901463!#"3!2657#!"&> "U);;));ԥgg_hHCVC9,P X;) );;)5!&4 D>3CmL#R+Ͱ /$/ְ Ͱ +ͱ%+ "$9!9 "#$9 !9901463!2!"3!26=7#!"& '',=B);;));ԥV7R,;) );;)Eȩ7QE+/3Ͱ 2/ְ2Ͱ2+99 99 990135# #35 5#3 35#,,',[(,,L+ 3/ְ Ͱ2+01746;2+"&d d2KJL+ 33/ְͰ2+01546;2+"&d d2KJL+3/+014 &&LL3 |&&d7;2654&+";2654&+"  dL73!2654&#!"  (L+3/+011 4LL+33/ְ2 ͱ+01146;2+"&5dd L,L+3/ְ2 ͱ+01!46;2+"&5,ddLd( //+0175463!2#!"&!dLdd47 'PaWaaRt% 7a<aa B /Ͱ//ְ Ͱ +ͱ+  $9$901$  $33535#5##DDQ I / Ͱ//ְ Ͱ  +ͱ+  $9 999901$  $!5!DXDQ 2 /Ͱ/ְͰͱ+ 99  9901$  $77'7''DSՍՎՍԍD(ՎՍԍՍ 2 /Ͱ/ְͰͱ+ 99  9901$  $ ''DkfDf 8<l /9Ͱ+!499. (:;$9'<99!*9 .99949901$  $32264>:323>54.#"35#Dɏ '-"#1D12QE&D  =& )2X23L(5`.d ; / Ͱ/3Ͱ/Ͱ//+999901$  $7!5#!3#35#DddddDd,dd/i+/Ͱ2/!333Ͳ #-2220/ֲ)222Ͳ'2221+"#./$999()9990153>7533##5.'35367#53.'#536vkYȌ`oKȕ4eJKn}PEf!}Im0JjlH F /Ͱ/ /ְ Ͱ +ͱ!+  $9$901$  $ 6& 7'77'DVImmmD_Vۇmmm F /Ͱ//ְ Ͱ +ͱ+  $9$901$  $ 6& 77DVkW̎D_V#W͎ F /Ͱ//ְ Ͱ +ͱ+  $9$901$  $&#"32654'D>8dtap;Dsd7>;pac//+901!!XX#c//+901! XX,,;@-J+/ְͱ+901 !!XXXh+/ְͱ+901!!!h(,*?XXL 5>7 FX_Ȅխg;@-$Du +/+011!&ځ&p&ځ &"# 7'!' "''ف'p5'ق#O / Ͱ#/Ͱ/$/ְͰ+ ͱ%+ !#$9# 9999014>2".;2676&+"35#[՛[[՛V:#6#:0՛[[՛[[F.d&*04;4'+13*Ͱ227>7.#676%>7>'&" 8./ieh,Jhqx{\Sc'C78Fak[)!#==Y57>'>7>76''&'.7.7o FFB:8( OV $9DkC@&'GOS3 *gJ.  &:4?B8- %>=B'Pd!I,  =CnCSm,U!ٕfmS ;4( .MV .n}3!?GC/)Ͱ:/ H/<ְ7ͱI+7<@ )(5>@C$9 :$.5>BG$9017>2".'72>7.'"&5477./=FOsvvsOFFOsvvsOFC-[TzwRY,H 7:91.f1ii%LX( (WT`G//G`TW( (( (WT`G//G`TW( ( `=^8+(3\;hI%E:JY||UIWs|Ci`$$ )A+3B/C+6=+ .    + + + +$ +% + #999$9%9 9 $%........@ $%..........@017>3273#7.'77.547?./7>7&'7=FOsvH=<%Ɣ%Rri' ҷ%k.f1i/:(&-/"0/a+'C. %ZeX( (WT`G/Pegy8(6nUIWs|C/WR&2&?@06@(( 4kbf &3!26'.7 !5#5#o%%~8~ddDDG  " d-dd,dd)H/ */%ְ2Ͱ 2% +@ +% +@%# +++%99 %99015467462'%/#&=47&dkX|Xkd^^d)1ES>XX>1) [@ NN @[ L #'+/37;?CGKOSW53!265!5!54&+5#!5##"53'53'5353'53'5353'53'5353'53'5353'53'53Ld ddddddddddddddddddddddddddddddd2dddddJddddddpddddddpddddddpddddddpddddddx A/3Ͱ2 /3Ͱ2/+99  $99901=!35 5# !7'!735 5#X,ԟzz,XXz{L+/ 3/+01463!2#!#"&;));;)d);X);;));,;dL%)-`+ Ͳ  +@  +2&/*3'Ͱ+2./ְ&2Ͱ(2+*2Ͱ,2/+$9999015!32>'4=!".!!!d,U'5%;) ,'MeeM',,Xq \ #(,.*R~jqP33Pqj~RV,,h 7`aaCF ' FDBCa:dv(//ְͱ+9901 #!!!# #+,}++pX,pX2F"+3,Ͱ,&ͱ22//Ͱ/ 3/$ְͰ+ͱ4+-901&763!7>;2++"&=!"&=#"&5463!7!"&'&^6**20 -*? 2222*L +Ͱ/Ͱ 2 /+011!53463!2!P;),); d);;)dL(+Ͱ/ Ͱ2 /+9013! 3463!2!!,P;),);DX);;). ! + /ְͱ + 99013# #3.**,X,/ / / +9901!5 5!,X,X*!I +Ͱ2/ 3Ͱ/"/ְͰ+ Ͳ +@ +#+ 901=463!2#!"&>3!235#35#;));;));$%dddddd);;)d);;U'-$ddddL )7&8/ְͰ*+2ͱ9+* 9901546?.5<>;%%##"+"&'4632#"&e2"]&/ S7X22 !U   QRJf+35/+3Ͱ)/3Ͱ2) +@)% +4/5+)3,1990146;7>7'&6;232#"&/.267"Ju?zS^Sz?vdjO}:: 8F8 0l^GM~ $M( ))1==1777'7'7'7'''N--N괴N--N-N鳳N-,N鴴N,d".//(ְͱ0+(90153#;;276=4&#!6=4&+"?3!#',d=|.%='='20`dd22ֈXKd9X+d,Qv,Q(%wԯ}dL".p+%Ͱ/3(Ͱ./Ͱ2,/ //ְͰ+#Ͱ#&+Ͱ)+ͱ0+&#(,9999)+9.*901374;6;2#!+"&/&735'!5##dd=|.%='='20`dd22ֈdX}Kd9+d,Qv,Q(%կ}wddU"Ay /$Ͱ/)Ͱ1/Ͱ21 +@1 +B/ְͰ+#Ͱ#-+Ͳ- +@-< +C+-# ?$9$#9)91;2654&#!*.'&54?'dj  m U.UkmTkdd%7   VXK %  pyLN'YS(  SeV8<y/$Ͱ/Ͱ8/Ͱ:28 +@89 +=/ְͲ +@, +&+Ͱ9+<ͱ>+& )$9$&998',99901463'&54?632#!"&'#"'32!7%*#!3elU.U m  m!kT %kW   $CLy q  ' (Sd)YS   XaL6:G7+8;/ְ72)Ͳ) +@): +32)/+ͱ<+)699/9013!2654&'%54&"'&77><546!5!a ' (NLy%p[S22(SY XVjTnkUT  n V   dp 48E5/69/ ְ52+Ͳ+ +@+8 +!2+'+ͱ:++  99' 901?26=%>54&#!"!&5<.'&5!p &yMNS) % Y(22XIn  U3.TlnTjVSdڂ  q: +Ͱ//ְͱ+  999999014>32 $! _z%,nUzݠ_ &*8+Ͱ//ְ ͱ+9 9999014>32 $7'!7!5_yzݠ_,Uzݠ__z> +/ְͰ+ ͱ+ 9999  99014>32 $%333_z'Uzݠ_,M +//ְͰ+ ͱ+ 9999  99 999014>32 $% ##_z',,Uzݠ_p,|+*ͰO///ְͰX+ ͱ+9X@!#$32 $277>7.'.'"'&65.'6.'&76746'&67>7&72267.'6'?6.''&%>72>7.73_zyݠ_" T>9.*-hu"#. F = .2) ( (%  )#? 6 /R+>=>1  " ,$Uzݠ__zY!w F  /JG  s$>   #/ & % I+ *  ' ' $#   ' "qq $ U _<7&6767'"/X!N` {+o+We6\e~\F/n`/37;P /4Ͱ7/Ͱ/0Ͱ3/Ͱ,/8Ͱ;/%Ͱ>C+Hͳ7HC+1Ͱ1/7ͰH+ͱN+& $9>*-<9971 /;$9 $9*-<>$9(99#/;9901$  $ 654& 462#"64632#"46?&54632#"'"&%462#"&DVm. M  R)z  73H3 .  D.  ,! . 1~! . $33R . ;O:/'Ͱ /Ͱ6/JP/Q+'?9  1$9239901327>767>'&'&#"67632#"&'&>767>32>'.'&#"0#vF?8!@)'(#Z .A#{Ey&$4I7Z 0$&\4=k6_v[EC8fOESkZ(G־N9@1*+,#b/W!#tCu$'$4B?#>@$$\475be[<C]W$!7GP6X5=3/-3Ͱ26/ְͰ*+ ͱ7+*$939014632632'.'.76?>54&#"'&#"Pńbg#WCG`+rFBGCW#=>@]aRq @C>`9J:vr3HZo\o >FXGaSPc9w332764/&''7'&'7'7>54/&#"9BD[]BBB i{_.7BB i_/#7BB]_@Ba_@BBBB i{_-87B]B i`13#j+]BBB@E+Ͱ/Ͱ//ְͰ+ Ͱ Ͱ/+9990174>2#!"&7!!264&"2- +@-, +;/3Ͳ; +@ +D/ְ22ͰͰ2,+:222+Ͳ>222+@+'Ͱ ͱE+29, 9-)9;':@C$99013.#.54>753#.'#5&'.654&''WJ.BN/!XOd&ER<+6J@" MNW(k,;+@GdfC1/*Ͱ/3Ͱ2/ Ͳ +@ +D/ְ92Ͱ$2 +@ + +@ ++ͱE+8BC$9  *13$9,9*1-999,<990153&'.>7632#4.#"3#>36327#"&'>7>'d /-aʙDP$%T)!):#b!!L<2)O'*2'V7   0 $Xd17;V^(Xw4K,9S*3d2;6 "B   7G  +/ ְ ͱ+ 901 ## ##****,,|X,| "+3 Ͳ+Ͱ/ͱ22 /Ͱ/Ͳ +@ +2"/Ͱ2#/ְͰ+ 22 ͱ22 + 22ͱ 22+Ͱ/ͱ$+999 901333!5335!##535!#5#735#d,cdc,dddd,|dddddd, dd"+ 33 /Ͱ"/Ͱ/ͰͰ/Ͱ/Ͱ2#/ְͰ+22ͱ22 + 22 ͱ22 +Ͱ/ͱ$+99"$99901333!!#5#5335!##53535#,dddd,cdccdd,| dddddddd|L k + /Ͱ/Ͱ /Ͳ  +@  +/ְͳ+Ͱ/ 3Ͱ + 2 ͱ+ $9 9901 ##!#553#35#**X,dddd,,| dd |L k +/Ͱ/Ͳ +@ +// ְ ͳ + Ͱ /3Ͱ  +2ͱ+ $99901 ##%53#!#5'35#**Xdd,dcdd,,|dd  dd R/Ͱ / Ͱ/Ͱ//ֲ 222ͰͲ +@ +@ ++ $901 ##5!5!5!53** p,,,|,,, R/Ͱ / Ͱ/Ͱ// ֲ222Ͱ Ͳ +@  +@  ++ $901 ##535!5!5!**,p,,|,,,LL* +Ͱ/ /ְͰ+ ͱ!+01463!2#!"&73!2654&#!",ԥ;));;) );,ԥA);;));;)LL"> +Ͱ/#/ְͰ+ ͱ$+ !99 "9901463!2#!"&73!2654&#!"-,ԣ;));;) );M,ԥA);;));;) LL"> +Ͱ/#/ְͰ+ ͱ$+ "99 !9901463!2#!"&73!2654&#!",ԥ;));;) );d,ԥA);;));;)dMLL"> +Ͱ/#/ְͰ+ ͱ$+ !99 "9901463!2#!"&73!2654&#!"!,ԥ;));;) );d,Ԣ?);;));;)pML<+Ͱ/Ͱ// ְͱ+99901!5 55!2654&#!5!2#,p);;) ,p;));ԥ!(/"/ְͱ#+99013!327636'&#676/#".     KJ  i  VL?+ͰͰ/Ͱ/Ͱ /ְ ͱ!+999013!275!"&5463!5./"!5 5,/5 );;)]]X,p;));,$T+Ͱ/%/ְͰ +ͱ&+  $$9#9 "#$$99013!26='#!"&546;7'#"%'!',Nz;) );;)vJdabI{);;));zN V  Z /Ͱ/Ͱ//ְ Ͱ +Ͱ+ͱ+ $9 $901$  $ 6& 462"DVrrrD_VrrrL . +Ͱ/Ͱ 2/ְͲ +@ ++011463!2 !!35#  dd   pv2L + +Ͱ//ְͲ +@ ++011463!2!!! 35#  ,,'C^dd  ,2L . +Ͱ//ְ 2Ͳ +@ ++011463!2 ''35#  1TFdd  TF:2L + +Ͱ//ְͲ +@ ++011463!27'%'35#  aapԕdd  baԕ 2L . +Ͱ//ְ2Ͳ +@ ++011463!27'7 35#  |bԕcdd  daԔ2+ /ְͱ +01  %O`w8dLM/Ͳ +@ +2 +@ +2/ְͰͰ+ ͱ+ 99901546;!3+!#"&35#dDXdd,pg>@/Ͳ +@ + +@ +2/ְͰͱ+ 99901546;!3'!#"&%735#dx~E{xa{%dd,xp{x`{$#$/ְͰͱ%+01546;!3'!#"&35#7'77'dgXddd,gpgժl/Ͳ +@ + Ͱ/ͱ22/ְͲ +@ +Ͱ+Ͱ 2+9 99 901546;!3!!#"&% ##53dp X,,d,p,,[/Ͳ +@ +/ͱ22/ְͰͰ+ͱ+9 9 999 901546;!3'!#"&%333 53dnXd,np,,L 53!265!5!54&#!"5!LPd&df /33ͱ22/ 33ͱ 22/ְ Ͱ  +Ͱ+ͱ+ $9$9$9999901!!5335335!5 553;5#,pdddd,ddddd* d/:+0/ְͰ +ͳ +Ͱ/ Ͱ +ͱ1+0173737+"&5%;2654&d22d22d22dX $%dd,dd,ddpAd5!sRtEdL38+ 33Ͳ 222(/%333'Ͱ24/5+(3 99013!5"&5!#!5".546?5!2!4635!2dKK"2pK Kp"28 &v& 88 x88 &v& 88 LL *.2+Ͱ/Ͳ +@ +//0+$9013!2654&#!"!73%!!5!5!!%35!'!5%;),);;));di'Wdd,,'iWd,);;));;)Dbd,,bbdF 3?6&/&.'7>/.>fgї{4vev-+fg=!.vev1L@/+ Ͱ(/8A/B+  /99(&)2@$901=46754>2#!"&?>=6 6=.#"m&RpR&m>d|~\ud?, 23/2  23!""!A1)!((! dL+/+0135!%!'57##5##5##5#dL}dddddddddȖdpddL $ +3/ ְͰ+ͱ+013!4&+"46;2346;2d,;)d);;)d);d;)d););;)p);;));;)DL'+H +Ͱ/,/ְͰ+ ͱ-+ #(*$9 &()$901463!2#!"&7!!!#535!3#353#5#3d|||D||d,dddd,|| |,ddddd,dp,L'+H +Ͱ/,/ְͰ+ ͱ-+ #(*$9 &()$901463!2#!"&7!!3533##5#353#5#3d|||D||ddddddddddd,|| | d,dp,L#D +Ͱ/$/ְͰ+ ͱ%+$9"$901463!2#!"&7!!!5#35!!5#35!d|||D||d,,,|| |d,d d,dLD +Ͱ//ְͰ+ ͱ+$9$901463!2#!"&7!!-d|||D||d,d,,|| |,ԖL'Z +Ͱ/Ͱ#2/%3Ͱ/(/ְͰ+Ͱ+!Ͱ!$+Ͱ+ ͱ)+01463!2#!"&7!!!%3264&+;#"d|||D||d)69&6)&,|| | dTVVT,L#)H +Ͱ/*/ְͰ+ ͱ++ !$'$9 "&($901463!2#!"&7!!!#535!3#35#33#d|||D||d,ddcdd,|| |,ddddd,pL!'L +Ͱ/(/ְͰ+ ͱ)+"%$9 $&$901463!2#!"&7!!!#5#5335#33#d|||D||d,dedddcdd,|| |dpdd,pL!%+ +Ͱ/")33Ͱ#2/Ͱ/&3Ͱ'2/,/ְͰ+2!Ͱ!+ͳ+Ͱ/Ͱ"+%Ͱ%*+)Ͱ)&Ͱ&/)+ ͱ-+9901463!2#!"&7!!5!##53553!5353#d|||D||d,cdcd,dd,|| |dddpddddd  y /Ͱ/Ͱ/Ͱ//ְ Ͱ +Ͱ+ͱ+ $9 $9 $99 $901$  $ 6& 57!!!!DVd,,D_Vddd  $ /Ͱ!/3"Ͱ/Ͱ/%/ְ Ͱ + Ͱ2  +@  + !+2$Ͱ2$+ͱ&+  $9!9$ $9"! $9999 $901$  $ 6& !#5#3#353DV,dddD_VddddddddA r/Ͱ Ͱ2!/ְͰ+Ͱ+ ͱ"+999 99 99 $9  $901;!3264&#".#"333qOxx.,,nBU:Pr,ԭawי k,A /ְͱ!+99901; >54&#".#" ##qO^yx.,,nBU:,,Prmdxawי k,,dLm7!!'5!33 33dK^KԪț--,,My7)327!'32654'>54&'.#"&#"y9/iJ8,K^K.6Ji 2;{Y^t Ji5XJi--2iJ f=ZYqtiA_< . .::(dFHFddjdddddd5d!u,dh"oddF:.JadP9'ddddddy****f0HP6,Lrd"DL 0 ` D V >  v :`L&` b&bL8,J|0NZ2F  * F n !j!"B"#~#$$$%%%%%&Z&&&''j'(8(d()6)*n*+h++,D,--.f../:001&1~1223`34455f566\67 7`778P899X99::^::;,;t;<@>H>>?0?@@`@A"AABBCCD?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~glyph1uni000Duni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205FEurouni25FCuni2601uni2709uni270FuniE001uniE002uniE003uniE005uniE006uniE007uniE008uniE009uniE010uniE011uniE012uniE013uniE014uniE015uniE016uniE017uniE018uniE019uniE020uniE021uniE022uniE023uniE024uniE025uniE026uniE027uniE028uniE029uniE030uniE031uniE032uniE033uniE034uniE035uniE036uniE037uniE038uniE039uniE040uniE041uniE042uniE043uniE044uniE045uniE046uniE047uniE048uniE049uniE050uniE051uniE052uniE053uniE054uniE055uniE056uniE057uniE058uniE059uniE060uniE062uniE063uniE064uniE065uniE066uniE067uniE068uniE069uniE070uniE071uniE072uniE073uniE074uniE075uniE076uniE077uniE078uniE079uniE080uniE081uniE082uniE083uniE084uniE085uniE086uniE087uniE088uniE089uniE090uniE091uniE092uniE093uniE094uniE095uniE096uniE097uniE101uniE102uniE103uniE104uniE105uniE106uniE107uniE108uniE109uniE110uniE111uniE112uniE113uniE114uniE115uniE116uniE117uniE118uniE119uniE120uniE121uniE122uniE123uniE124uniE125uniE126uniE127uniE128uniE129uniE130uniE131uniE132uniE133uniE134uniE135uniE136uniE137uniE138uniE139uniE140uniE141uniE142uniE143uniE144uniE145uniE146uniE148uniE149uniE150uniE151uniE152uniE153uniE154uniE155uniE156uniE157uniE158uniE159uniE160uniE161uniE162uniE163uniE164uniE165uniE166uniE167uniE168uniE169uniE170uniE171uniE172uniE173uniE174uniE175uniE176uniE177uniE178uniE179uniE180uniE181uniE182uniE183uniE184uniE185uniE186uniE187uniE188uniE189uniE190uniE191uniE192uniE193uniE194uniE195uniE197uniE198uniE199uniE200KPXYF+X!YKRX!Y+\XY+RX Dashboard for {{full_path}}

    Classes

    Coverage Distribution

    Complexity

    Insufficient Coverage

    {{insufficient_coverage_classes}}
    Class
    Coverage

    Project Risks

    {{project_risks_classes}}
    Class
    CRAP

    Methods

    Coverage Distribution

    Complexity

    Insufficient Coverage

    {{insufficient_coverage_methods}}
    Method
    Coverage

    Project Risks

    {{project_risks_methods}}
    Method
    CRAP
    {{percent}}% covered ({{level}})
    {{name}} {{classes_bar}}
    {{classes_tested_percent}}
    {{classes_number}}
    {{methods_bar}}
    {{methods_tested_percent}}
    {{methods_number}}
    {{crap}} {{lines_bar}}
    {{lines_executed_percent}}
    {{lines_number}}
    Code Coverage for {{full_path}}
    {{items}}
     
    Code Coverage
     
    Lines
    Functions and Methods
    Classes and Traits
    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; }/*! * 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}} /******************** * 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; }/*! 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;iarticle,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}"; 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="";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;dthis.$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(''}),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);/*! 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='­',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;be;++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;++ue;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])&&++t0&&(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.t8?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;++aa;){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;++e68?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;++ea;++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];++r1&&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)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?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]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)A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)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)0?0:3:oa(r[0]-e)0?2:1:oa(r[1]-t)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)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)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)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?{x:f,y:oa(t-f)Aa?{x:oa(e-p)Aa?{x:h,y:oa(t-h)Aa?{x:oa(e-g)=-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.yd||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.yr||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.yg){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.xr;++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]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;++ie;++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;++i0&&(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=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.ro;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;++iu&&(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]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++0;h--)o.push(i(s)*h);for(s=0;o[s]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;++ae?[0/0,0/0]:[e>0?u[e-1]:n[0],et?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);++f1&&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]];++t1){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;s9&&(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;++ue?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]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=e);)e=void 0;for(;++ur&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ur&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ue&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ue&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=e);)e=u=void 0;for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=e);)e=void 0;for(;++ir&&(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(;++i1&&(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)r;){var i=r+u>>>1;er?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=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)=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=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=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=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(;++ur){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;++rr;++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);++oi;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=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;++tn;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;++ar){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++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;++rn?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]:nhc?(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=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,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.xm&&(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=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;++ea*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;++at;++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;++fg;++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;++i0)for(i=-1;++i=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;++h0&&(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;++ut?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;++oe&&(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);++ie.dx)&&(l=e.dx);++ie&&(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;++oi;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]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}();/*! 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="
    ",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="",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;++db;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.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="",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.lengthh;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="
    a",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="",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]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},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>")+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)?""!==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>");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("