From 31934913ad72c24de463847e7822b13efb0c5b73 Mon Sep 17 00:00:00 2001 From: Fulvio Notarstefano Date: Mon, 5 Dec 2022 11:36:15 +0800 Subject: [PATCH 1/6] Add php-compatibility --- composer.json | 3 +- composer.lock | 120 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 1c67bf90..f84ee2ef 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ "sempro/phpunit-pretty-print": "^1.4", "phpstan/phpstan": "^1.9", "phpstan/phpstan-phpunit": "^1.2", - "phpstan/phpstan-mockery": "^1.1" + "phpstan/phpstan-mockery": "^1.1", + "phpcompatibility/php-compatibility": "^9.3" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index d03a4d3e..eacbdabc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "21c198b21ef6831aea712330084b84de", + "content-hash": "2e69cc91124e657266b9e415e12f7ae7", "packages": [ { "name": "antecedent/patchwork", @@ -2517,6 +2517,68 @@ }, "time": "2022-09-12T20:47:09+00:00" }, + { + "name": "phpcompatibility/php-compatibility", + "version": "9.3.5", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", + "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", + "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" + }, + "conflict": { + "squizlabs/php_codesniffer": "2.6.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "homepage": "https://github.com/wimg", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" + } + ], + "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", + "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", + "keywords": [ + "compatibility", + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibility" + }, + "time": "2019-12-27T09:44:58+00:00" + }, { "name": "phpstan/phpstan", "version": "1.9.2", @@ -3068,6 +3130,62 @@ }, "time": "2021-01-04T13:25:10+00:00" }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2022-06-18T07:21:10+00:00" + }, { "name": "symfony/config", "version": "v5.4.11", From 466e38bb427709bb2d27463fd43df985b36e1a65 Mon Sep 17 00:00:00 2001 From: Fulvio Notarstefano Date: Mon, 5 Dec 2022 11:54:17 +0800 Subject: [PATCH 2/6] Configure phpcs --- .php_cs | 133 +++++++++++ composer.json | 5 +- composer.lock | 209 +++++++++--------- .../themes/vip/plugins/vip-init.php | 1 + .../dummy-files/wp-includes/class-http.php | 1 + phpcs.xml | 7 + 6 files changed, 253 insertions(+), 103 deletions(-) create mode 100644 .php_cs create mode 100644 phpcs.xml diff --git a/.php_cs b/.php_cs new file mode 100644 index 00000000..12dea481 --- /dev/null +++ b/.php_cs @@ -0,0 +1,133 @@ +in(array_filter([ + __DIR__.'/configurations', + __DIR__.'/src', + __DIR__.'/tests', +], 'is_dir')); + +return PhpCsFixer\Config::create() + ->setFinder($finder) + ->setLineEnding("\n") + ->setRiskyAllowed(true) + ->setRules([ + 'array_indentation' => true, + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => [ + 'default' => 'single_space', + 'operators' => ['=>' => null] + ], + 'blank_line_after_namespace' => true, + 'blank_line_after_opening_tag' => true, + 'blank_line_before_statement' => [ + 'statements' => ['return'] + ], + 'braces' => true, + 'cast_spaces' => true, + 'class_attributes_separation' => [ + 'elements' => ['method'] + ], + 'class_definition' => true, + 'concat_space' => [ + 'spacing' => 'none' + ], + 'declare_equal_normalize' => true, + 'elseif' => true, + 'encoding' => true, + 'full_opening_tag' => true, + 'fully_qualified_strict_types' => true, + 'function_declaration' => true, + 'function_typehint_space' => true, + 'heredoc_to_nowdoc' => true, + 'include' => true, + 'increment_style' => ['style' => 'post'], + 'indentation_type' => true, + 'linebreak_after_opening_tag' => true, + 'line_ending' => true, + 'lowercase_cast' => true, + 'lowercase_constants' => true, + 'lowercase_keywords' => true, + 'lowercase_static_reference' => true, + 'magic_method_casing' => true, + 'magic_constant_casing' => true, + 'method_argument_space' => true, + 'native_function_casing' => true, + 'no_alias_functions' => true, + 'no_extra_blank_lines' => [ + 'tokens' => [ + 'extra', + 'throw', + 'use', + 'use_trait', + ] + ], + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_closing_tag' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => [ + 'use' => 'echo' + ], + 'no_multiline_whitespace_around_double_arrow' => true, + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line' + ], + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_around_offset' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_trailing_whitespace' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unreachable_default_argument_value' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'normalize_index_brace' => true, + 'not_operator_with_successor_space' => true, + 'object_operator_without_whitespace' => true, + 'ordered_imports' => ['sortAlgorithm' => 'alpha'], + 'phpdoc_indent' => true, + 'phpdoc_inline_tag' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_package' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_scalar' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_summary' => true, + 'phpdoc_to_comment' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'phpdoc_var_without_name' => true, + 'psr4' => true, + 'self_accessor' => true, + 'short_scalar_cast' => true, + 'simplified_null_return' => false, + 'single_blank_line_at_eof' => true, + 'single_blank_line_before_namespace' => true, + 'single_class_element_per_statement' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'single_line_comment_style' => [ + 'comment_types' => ['hash'] + ], + 'single_quote' => true, + 'space_after_semicolon' => true, + 'standardize_not_equals' => true, + 'switch_case_semicolon_to_colon' => true, + 'switch_case_space' => true, + 'ternary_operator_spaces' => true, + 'trailing_comma_in_multiline_array' => true, + 'trim_array_spaces' => true, + 'unary_operator_spaces' => true, + 'visibility_required' => [ + 'elements' => ['method', 'property'] + ], + 'whitespace_after_comma_in_array' => true, + ]); diff --git a/composer.json b/composer.json index f84ee2ef..e8aa6272 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,7 @@ "description": "A mocking library to take the pain out of unit testing for WordPress", "license": "GPL-2.0-or-later", "version": "0.5.0", + "prefer-stable" : true, "require": { "php": ">=7.3 < 9.0", "phpunit/phpunit": "^9.5.24", @@ -46,6 +47,8 @@ "coverage": [ "@test:behat", "@test:phpunitcov" - ] + ], + "post-install-cmd": "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility", + "post-update-cmd" : "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility" } } diff --git a/composer.lock b/composer.lock index eacbdabc..a917ad2c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2e69cc91124e657266b9e415e12f7ae7", + "content-hash": "64a09a53e4abf3039ea3e1e3be805123", "packages": [ { "name": "antecedent/patchwork", @@ -308,16 +308,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.1", + "version": "v4.15.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", "shasum": "" }, "require": { @@ -358,9 +358,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2022-11-12T15:38:23+00:00" }, { "name": "phar-io/manifest", @@ -475,16 +475,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.17", + "version": "9.2.19", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", + "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", "shasum": "" }, "require": { @@ -540,7 +540,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" }, "funding": [ { @@ -548,7 +548,7 @@ "type": "github" } ], - "time": "2022-08-30T12:24:04+00:00" + "time": "2022-11-18T07:47:47+00:00" }, { "name": "phpunit/php-file-iterator", @@ -793,16 +793,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.24", + "version": "9.5.26", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" + "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/851867efcbb6a1b992ec515c71cdcf20d895e9d2", + "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2", "shasum": "" }, "require": { @@ -824,14 +824,14 @@ "phpunit/php-timer": "^5.0.2", "sebastian/cli-parser": "^1.0.1", "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", + "sebastian/comparator": "^4.0.8", "sebastian/diff": "^4.0.3", "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", + "sebastian/exporter": "^4.0.5", "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.1", + "sebastian/type": "^3.2", "sebastian/version": "^3.0.2" }, "suggest": { @@ -875,7 +875,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.26" }, "funding": [ { @@ -885,9 +885,13 @@ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" } ], - "time": "2022-08-30T07:42:16+00:00" + "time": "2022-10-28T06:00:21+00:00" }, { "name": "sebastian/cli-parser", @@ -1907,16 +1911,16 @@ "packages-dev": [ { "name": "behat/behat", - "version": "v3.11.0", + "version": "v3.12.0", "source": { "type": "git", "url": "https://github.com/Behat/Behat.git", - "reference": "a19c72c78eb0cdf7b7c4dabfeec9eb3a282728fc" + "reference": "2f059c9172764ba1f1759b3679aca499b665330a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Behat/zipball/a19c72c78eb0cdf7b7c4dabfeec9eb3a282728fc", - "reference": "a19c72c78eb0cdf7b7c4dabfeec9eb3a282728fc", + "url": "https://api.github.com/repos/Behat/Behat/zipball/2f059c9172764ba1f1759b3679aca499b665330a", + "reference": "2f059c9172764ba1f1759b3679aca499b665330a", "shasum": "" }, "require": { @@ -1934,6 +1938,7 @@ }, "require-dev": { "herrera-io/box": "~1.6.1", + "phpspec/prophecy": "^1.15", "phpunit/phpunit": "^8.5 || ^9.0", "symfony/process": "^4.4 || ^5.0 || ^6.0", "vimeo/psalm": "^4.8" @@ -1987,9 +1992,9 @@ ], "support": { "issues": "https://github.com/Behat/Behat/issues", - "source": "https://github.com/Behat/Behat/tree/v3.11.0" + "source": "https://github.com/Behat/Behat/tree/v3.12.0" }, - "time": "2022-07-07T09:49:27+00:00" + "time": "2022-11-29T15:30:11+00:00" }, { "name": "behat/gherkin", @@ -3267,16 +3272,16 @@ }, { "name": "symfony/console", - "version": "v5.4.15", + "version": "v5.4.16", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ea59bb0edfaf9f28d18d8791410ee0355f317669" + "reference": "8e9b9c8dfb33af6057c94e1b44846bee700dc5ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ea59bb0edfaf9f28d18d8791410ee0355f317669", - "reference": "ea59bb0edfaf9f28d18d8791410ee0355f317669", + "url": "https://api.github.com/repos/symfony/console/zipball/8e9b9c8dfb33af6057c94e1b44846bee700dc5ef", + "reference": "8e9b9c8dfb33af6057c94e1b44846bee700dc5ef", "shasum": "" }, "require": { @@ -3346,7 +3351,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.15" + "source": "https://github.com/symfony/console/tree/v5.4.16" }, "funding": [ { @@ -3362,20 +3367,20 @@ "type": "tidelift" } ], - "time": "2022-10-26T21:41:52+00:00" + "time": "2022-11-25T14:09:27+00:00" }, { "name": "symfony/dependency-injection", - "version": "v5.4.11", + "version": "v5.4.16", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "a8b9251016e9476db73e25fa836904bc0bf74c62" + "reference": "a93e1863500940780fc1235f52d54397be2d14b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a8b9251016e9476db73e25fa836904bc0bf74c62", - "reference": "a8b9251016e9476db73e25fa836904bc0bf74c62", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a93e1863500940780fc1235f52d54397be2d14b3", + "reference": "a93e1863500940780fc1235f52d54397be2d14b3", "shasum": "" }, "require": { @@ -3435,7 +3440,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v5.4.11" + "source": "https://github.com/symfony/dependency-injection/tree/v5.4.16" }, "funding": [ { @@ -3451,7 +3456,7 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2022-11-25T07:33:13+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3750,16 +3755,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", "shasum": "" }, "require": { @@ -3774,7 +3779,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3812,7 +3817,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" }, "funding": [ { @@ -3828,20 +3833,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "433d05519ce6990bf3530fba6957499d327395c2" + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", - "reference": "433d05519ce6990bf3530fba6957499d327395c2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", "shasum": "" }, "require": { @@ -3853,7 +3858,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3893,7 +3898,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" }, "funding": [ { @@ -3909,20 +3914,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", "shasum": "" }, "require": { @@ -3934,7 +3939,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3977,7 +3982,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" }, "funding": [ { @@ -3993,20 +3998,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "shasum": "" }, "require": { @@ -4021,7 +4026,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4060,7 +4065,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" }, "funding": [ { @@ -4076,20 +4081,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", "shasum": "" }, "require": { @@ -4098,7 +4103,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4139,7 +4144,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.0" }, "funding": [ { @@ -4155,20 +4160,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "shasum": "" }, "require": { @@ -4177,7 +4182,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4222,7 +4227,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" }, "funding": [ { @@ -4238,20 +4243,20 @@ "type": "tidelift" } ], - "time": "2022-05-10T07:21:04+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", "shasum": "" }, "require": { @@ -4260,7 +4265,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4301,7 +4306,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" }, "funding": [ { @@ -4317,7 +4322,7 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/service-contracts", @@ -4552,16 +4557,16 @@ }, { "name": "symfony/translation", - "version": "v5.4.12", + "version": "v5.4.14", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "42ecc77eb4f229ce2df702a648ec93b8478d76ae" + "reference": "f0ed07675863aa6e3939df8b1bc879450b585cab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/42ecc77eb4f229ce2df702a648ec93b8478d76ae", - "reference": "42ecc77eb4f229ce2df702a648ec93b8478d76ae", + "url": "https://api.github.com/repos/symfony/translation/zipball/f0ed07675863aa6e3939df8b1bc879450b585cab", + "reference": "f0ed07675863aa6e3939df8b1bc879450b585cab", "shasum": "" }, "require": { @@ -4629,7 +4634,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.4.12" + "source": "https://github.com/symfony/translation/tree/v5.4.14" }, "funding": [ { @@ -4645,7 +4650,7 @@ "type": "tidelift" } ], - "time": "2022-08-02T15:52:22+00:00" + "time": "2022-10-07T08:01:20+00:00" }, { "name": "symfony/translation-contracts", @@ -4727,16 +4732,16 @@ }, { "name": "symfony/yaml", - "version": "v5.4.14", + "version": "v5.4.16", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e83fe9a72011f07c662da46a05603d66deeeb487" + "reference": "ebd37c71f62d5ec5f6e27de3e06fee492d4c6298" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e83fe9a72011f07c662da46a05603d66deeeb487", - "reference": "e83fe9a72011f07c662da46a05603d66deeeb487", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ebd37c71f62d5ec5f6e27de3e06fee492d4c6298", + "reference": "ebd37c71f62d5ec5f6e27de3e06fee492d4c6298", "shasum": "" }, "require": { @@ -4782,7 +4787,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.4.14" + "source": "https://github.com/symfony/yaml/tree/v5.4.16" }, "funding": [ { @@ -4798,13 +4803,13 @@ "type": "tidelift" } ], - "time": "2022-10-03T15:15:50+00:00" + "time": "2022-11-25T16:04:03+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], - "prefer-stable": false, + "prefer-stable": true, "prefer-lowest": false, "platform": { "php": ">=7.3 < 9.0" diff --git a/php/WP_Mock/API/dummy-files/themes/vip/plugins/vip-init.php b/php/WP_Mock/API/dummy-files/themes/vip/plugins/vip-init.php index e69de29b..b3d9bbc7 100644 --- a/php/WP_Mock/API/dummy-files/themes/vip/plugins/vip-init.php +++ b/php/WP_Mock/API/dummy-files/themes/vip/plugins/vip-init.php @@ -0,0 +1 @@ + + + ./php + + + + From eba3a4914956d9b94a0b9bd1954e672fa872a983 Mon Sep 17 00:00:00 2001 From: Fulvio Notarstefano Date: Mon, 5 Dec 2022 11:56:08 +0800 Subject: [PATCH 3/6] Update ci.yml for phpcs --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3243a0a..84f95373 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,6 +79,30 @@ jobs: run: | vendor/bin/php-coveralls --coverage_clover="./clover.xml" --json_path="./coveralls-upload.json" -v + php-compatibility: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@e2f20e631ae6d7dd3b768f56a5d2af784dd54791 # v2.5.0 + + - name: Get Composer Cache Directory + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + + - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Install Dependencies + run: composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --ignore-platform-req php + + - name: Run PHP Code Sniffer using the PHPCompatibility standard + run: vendor/bin/phpcs + php-static-analysis: runs-on: ubuntu-latest From 1c63de22db97c808ad58896df5bd1b87b92725c0 Mon Sep 17 00:00:00 2001 From: Fulvio Notarstefano Date: Mon, 5 Dec 2022 12:01:57 +0800 Subject: [PATCH 4/6] Add editorconfig file --- .editorconfig | 26 +++++++++++++ composer.json | 104 +++++++++++++++++++++++++------------------------- 2 files changed, 78 insertions(+), 52 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..40fc2fa0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,26 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*.md] +charset = utf-8 +end_of_line = lf + +[{*.neon, *.xml}] +indent_style = tab +indent_size = 4 + +[*.json] +indent_style = space +indent_size = 4 + +# PHP PSR-12 Coding Standards +# http://www.php-fig.org/psr/psr-12/ +[*.php] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 \ No newline at end of file diff --git a/composer.json b/composer.json index e8aa6272..90d74420 100644 --- a/composer.json +++ b/composer.json @@ -1,54 +1,54 @@ { - "name": "10up/wp_mock", - "description": "A mocking library to take the pain out of unit testing for WordPress", - "license": "GPL-2.0-or-later", - "version": "0.5.0", - "prefer-stable" : true, - "require": { - "php": ">=7.3 < 9.0", - "phpunit/phpunit": "^9.5.24", - "mockery/mockery": "^1.5", - "antecedent/patchwork": "^2.1" - }, - "require-dev": { - "behat/behat": "^v3.11.0", - "sebastian/comparator": "^4.0.8", - "php-coveralls/php-coveralls": "^v2.5.3", - "sempro/phpunit-pretty-print": "^1.4", - "phpstan/phpstan": "^1.9", - "phpstan/phpstan-phpunit": "^1.2", - "phpstan/phpstan-mockery": "^1.1", - "phpcompatibility/php-compatibility": "^9.3" - }, - "autoload": { - "psr-4": { - "WP_Mock\\": "./php/WP_Mock" - }, - "classmap": [ - "php/WP_Mock.php" - ] - }, - "config": { - "platform": { - "php" : "7.3" - } - }, - "autoload-dev" : { - "classmap": ["tests"] - }, - "scripts": { - "test:behat": "behat", - "test:phpunit": "phpunit", - "test:phpunitcov": "phpunit --coverage-clover build/logs/clover.xml", - "test": [ - "@test:behat", - "@test:phpunit" - ], - "coverage": [ - "@test:behat", - "@test:phpunitcov" - ], - "post-install-cmd": "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility", - "post-update-cmd" : "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility" - } + "name": "10up/wp_mock", + "description": "A mocking library to take the pain out of unit testing for WordPress", + "license": "GPL-2.0-or-later", + "version": "0.5.0", + "prefer-stable" : true, + "require": { + "php": ">=7.3 < 9.0", + "phpunit/phpunit": "^9.5.24", + "mockery/mockery": "^1.5", + "antecedent/patchwork": "^2.1" + }, + "require-dev": { + "behat/behat": "^v3.11.0", + "sebastian/comparator": "^4.0.8", + "php-coveralls/php-coveralls": "^v2.5.3", + "sempro/phpunit-pretty-print": "^1.4", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-phpunit": "^1.2", + "phpstan/phpstan-mockery": "^1.1", + "phpcompatibility/php-compatibility": "^9.3" + }, + "autoload": { + "psr-4": { + "WP_Mock\\": "./php/WP_Mock" + }, + "classmap": [ + "php/WP_Mock.php" + ] + }, + "config": { + "platform": { + "php" : "7.3" + } + }, + "autoload-dev" : { + "classmap": ["tests"] + }, + "scripts": { + "test:behat": "behat", + "test:phpunit": "phpunit", + "test:phpunitcov": "phpunit --coverage-clover build/logs/clover.xml", + "test": [ + "@test:behat", + "@test:phpunit" + ], + "coverage": [ + "@test:behat", + "@test:phpunitcov" + ], + "post-install-cmd": "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility", + "post-update-cmd" : "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility" + } } From 22ab5711e2e045961a82d82bd1a03b2d65595323 Mon Sep 17 00:00:00 2001 From: Fulvio Notarstefano Date: Tue, 20 Dec 2022 01:27:49 +0800 Subject: [PATCH 5/6] Fix merge conflicts --- .php_cs | 133 -- composer.json | 10 +- composer.lock | 978 ++++++++++++++- php/WP_Mock.php | 1078 +++++++++-------- php/WP_Mock/API/constant-mocks.php | 42 +- php/WP_Mock/API/function-mocks.php | 365 +++--- php/WP_Mock/Action.php | 132 +- php/WP_Mock/DeprecatedListener.php | 238 ++-- php/WP_Mock/EventManager.php | 315 ++--- php/WP_Mock/Filter.php | 109 +- php/WP_Mock/Functions.php | 525 ++++---- php/WP_Mock/Handler.php | 183 +-- php/WP_Mock/Hook.php | 161 +-- php/WP_Mock/HookedCallback.php | 223 ++-- php/WP_Mock/InvokedFilterValue.php | 37 +- php/WP_Mock/Loader.php | 241 ++-- php/WP_Mock/Matcher/AnyInstance.php | 99 +- php/WP_Mock/Matcher/FuzzyObject.php | 172 +-- php/WP_Mock/ReturnSequence.php | 66 +- .../Tools/Constraints/ExpectationsMet.php | 65 +- php/WP_Mock/Tools/Constraints/IsEqualHtml.php | 103 +- php/WP_Mock/Tools/TestCase.php | 631 +++++----- phpcs.xml | 3 +- tests/DeprecatedMethodsTest.php | 93 +- tests/FunctionMocksTest.php | 196 +-- tests/WP_Mock/DeprecatedListenerTest.php | 282 ++--- tests/WP_Mock/Matcher/AnyInstanceTest.php | 58 +- tests/WP_Mock/Matcher/SampleClass.php | 9 +- tests/WP_Mock/Matcher/SampleSubClass.php | 9 +- tests/WP_MockTest.php | 244 ++-- 30 files changed, 3892 insertions(+), 2908 deletions(-) delete mode 100644 .php_cs diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 12dea481..00000000 --- a/.php_cs +++ /dev/null @@ -1,133 +0,0 @@ -in(array_filter([ - __DIR__.'/configurations', - __DIR__.'/src', - __DIR__.'/tests', -], 'is_dir')); - -return PhpCsFixer\Config::create() - ->setFinder($finder) - ->setLineEnding("\n") - ->setRiskyAllowed(true) - ->setRules([ - 'array_indentation' => true, - 'array_syntax' => ['syntax' => 'short'], - 'binary_operator_spaces' => [ - 'default' => 'single_space', - 'operators' => ['=>' => null] - ], - 'blank_line_after_namespace' => true, - 'blank_line_after_opening_tag' => true, - 'blank_line_before_statement' => [ - 'statements' => ['return'] - ], - 'braces' => true, - 'cast_spaces' => true, - 'class_attributes_separation' => [ - 'elements' => ['method'] - ], - 'class_definition' => true, - 'concat_space' => [ - 'spacing' => 'none' - ], - 'declare_equal_normalize' => true, - 'elseif' => true, - 'encoding' => true, - 'full_opening_tag' => true, - 'fully_qualified_strict_types' => true, - 'function_declaration' => true, - 'function_typehint_space' => true, - 'heredoc_to_nowdoc' => true, - 'include' => true, - 'increment_style' => ['style' => 'post'], - 'indentation_type' => true, - 'linebreak_after_opening_tag' => true, - 'line_ending' => true, - 'lowercase_cast' => true, - 'lowercase_constants' => true, - 'lowercase_keywords' => true, - 'lowercase_static_reference' => true, - 'magic_method_casing' => true, - 'magic_constant_casing' => true, - 'method_argument_space' => true, - 'native_function_casing' => true, - 'no_alias_functions' => true, - 'no_extra_blank_lines' => [ - 'tokens' => [ - 'extra', - 'throw', - 'use', - 'use_trait', - ] - ], - 'no_blank_lines_after_class_opening' => true, - 'no_blank_lines_after_phpdoc' => true, - 'no_closing_tag' => true, - 'no_empty_phpdoc' => true, - 'no_empty_statement' => true, - 'no_leading_import_slash' => true, - 'no_leading_namespace_whitespace' => true, - 'no_mixed_echo_print' => [ - 'use' => 'echo' - ], - 'no_multiline_whitespace_around_double_arrow' => true, - 'multiline_whitespace_before_semicolons' => [ - 'strategy' => 'no_multi_line' - ], - 'no_short_bool_cast' => true, - 'no_singleline_whitespace_before_semicolons' => true, - 'no_spaces_after_function_name' => true, - 'no_spaces_around_offset' => true, - 'no_spaces_inside_parenthesis' => true, - 'no_trailing_comma_in_list_call' => true, - 'no_trailing_comma_in_singleline_array' => true, - 'no_trailing_whitespace' => true, - 'no_trailing_whitespace_in_comment' => true, - 'no_unneeded_control_parentheses' => true, - 'no_unreachable_default_argument_value' => true, - 'no_useless_return' => true, - 'no_whitespace_before_comma_in_array' => true, - 'no_whitespace_in_blank_line' => true, - 'normalize_index_brace' => true, - 'not_operator_with_successor_space' => true, - 'object_operator_without_whitespace' => true, - 'ordered_imports' => ['sortAlgorithm' => 'alpha'], - 'phpdoc_indent' => true, - 'phpdoc_inline_tag' => true, - 'phpdoc_no_access' => true, - 'phpdoc_no_package' => true, - 'phpdoc_no_useless_inheritdoc' => true, - 'phpdoc_scalar' => true, - 'phpdoc_single_line_var_spacing' => true, - 'phpdoc_summary' => true, - 'phpdoc_to_comment' => true, - 'phpdoc_trim' => true, - 'phpdoc_types' => true, - 'phpdoc_var_without_name' => true, - 'psr4' => true, - 'self_accessor' => true, - 'short_scalar_cast' => true, - 'simplified_null_return' => false, - 'single_blank_line_at_eof' => true, - 'single_blank_line_before_namespace' => true, - 'single_class_element_per_statement' => true, - 'single_import_per_statement' => true, - 'single_line_after_imports' => true, - 'single_line_comment_style' => [ - 'comment_types' => ['hash'] - ], - 'single_quote' => true, - 'space_after_semicolon' => true, - 'standardize_not_equals' => true, - 'switch_case_semicolon_to_colon' => true, - 'switch_case_space' => true, - 'ternary_operator_spaces' => true, - 'trailing_comma_in_multiline_array' => true, - 'trim_array_spaces' => true, - 'unary_operator_spaces' => true, - 'visibility_required' => [ - 'elements' => ['method', 'property'] - ], - 'whitespace_after_comma_in_array' => true, - ]); diff --git a/composer.json b/composer.json index 90d74420..f5415b9b 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,10 @@ "phpstan/phpstan": "^1.9", "phpstan/phpstan-phpunit": "^1.2", "phpstan/phpstan-mockery": "^1.1", - "phpcompatibility/php-compatibility": "^9.3" + "phpcompatibility/php-compatibility": "^9.3", + "friendsofphp/php-cs-fixer": "^3.4", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", + "isaac/php-code-sniffer-baseliner": "^2.3" }, "autoload": { "psr-4": { @@ -31,6 +34,9 @@ "config": { "platform": { "php" : "7.3" + }, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true } }, "autoload-dev" : { @@ -51,4 +57,4 @@ "post-install-cmd": "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility", "post-update-cmd" : "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility" } -} +} \ No newline at end of file diff --git a/composer.lock b/composer.lock index a917ad2c..1b87ff94 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "64a09a53e4abf3039ea3e1e3be805123", + "content-hash": "db1e63489e66a58f3c1eefe202d2f244", "packages": [ { "name": "antecedent/patchwork", @@ -475,16 +475,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.19", + "version": "9.2.22", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" + "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e4bf60d2220b4baaa0572986b5d69870226b06df", + "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df", "shasum": "" }, "require": { @@ -540,7 +540,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.22" }, "funding": [ { @@ -548,7 +548,7 @@ "type": "github" } ], - "time": "2022-11-18T07:47:47+00:00" + "time": "2022-12-18T16:40:55+00:00" }, { "name": "phpunit/php-file-iterator", @@ -793,16 +793,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.26", + "version": "9.5.27", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2" + "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/851867efcbb6a1b992ec515c71cdcf20d895e9d2", - "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38", + "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38", "shasum": "" }, "require": { @@ -875,7 +875,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.26" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27" }, "funding": [ { @@ -891,7 +891,7 @@ "type": "tidelift" } ], - "time": "2022-10-28T06:00:21+00:00" + "time": "2022-12-09T07:31:23+00:00" }, { "name": "sebastian/cli-parser", @@ -2108,6 +2108,585 @@ }, "time": "2022-03-30T09:27:43+00:00" }, + { + "name": "composer/pcre", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/1.0.1" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-01-21T20:24:37+00:00" + }, + { + "name": "composer/semver", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-04-01T19:23:25+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/9e36aeed4616366d2b690bdce11f71e9178c579a", + "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a", + "shasum": "" + }, + "require": { + "composer/pcre": "^1", + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/2.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-24T20:20:32+00:00" + }, + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.7.2", + "source": { + "type": "git", + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + }, + "time": "2022-02-04T12:51:07+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.14.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "9e034d7a70032d422169f27d8759e8d84abb4f51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/9e034d7a70032d422169f27d8759e8d84abb4f51", + "reference": "9e034d7a70032d422169f27d8759e8d84abb4f51", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1 || ^2", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "vimeo/psalm": "^4.10" + }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.14.1" + }, + "time": "2022-12-12T12:46:12+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5|^8.5|^9.5", + "psr/log": "^1|^2|^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" + }, + "time": "2022-05-02T15:47:09+00:00" + }, + { + "name": "doctrine/lexer", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^4.11 || ^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/2.1.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-12-14T08:49:07+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", + "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", + "shasum": "" + }, + "require": { + "composer/semver": "^3.2", + "composer/xdebug-handler": "^2.0", + "doctrine/annotations": "^1.12", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.2.5 || ^8.0", + "php-cs-fixer/diff": "^2.0", + "symfony/console": "^4.4.20 || ^5.1.3 || ^6.0", + "symfony/event-dispatcher": "^4.4.20 || ^5.0 || ^6.0", + "symfony/filesystem": "^4.4.20 || ^5.0 || ^6.0", + "symfony/finder": "^4.4.20 || ^5.0 || ^6.0", + "symfony/options-resolver": "^4.4.20 || ^5.0 || ^6.0", + "symfony/polyfill-mbstring": "^1.23", + "symfony/polyfill-php80": "^1.23", + "symfony/polyfill-php81": "^1.23", + "symfony/process": "^4.4.20 || ^5.0 || ^6.0", + "symfony/stopwatch": "^4.4.20 || ^5.0 || ^6.0" + }, + "require-dev": { + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^1.5", + "mikey179/vfsstream": "^1.6.8", + "php-coveralls/php-coveralls": "^2.5.2", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", + "phpspec/prophecy": "^1.15", + "phpspec/prophecy-phpunit": "^1.1 || ^2.0", + "phpunit/phpunit": "^8.5.21 || ^9.5", + "phpunitgoodpractices/polyfill": "^1.5", + "phpunitgoodpractices/traits": "^1.9.1", + "symfony/phpunit-bridge": "^5.2.4 || ^6.0", + "symfony/yaml": "^4.4.20 || ^5.0 || ^6.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2021-12-11T16:25:08+00:00" + }, { "name": "guzzlehttp/guzzle", "version": "7.5.0", @@ -2437,7 +3016,56 @@ "type": "tidelift" } ], - "time": "2022-10-26T14:07:24+00:00" + "time": "2022-10-26T14:07:24+00:00" + }, + { + "name": "isaac/php-code-sniffer-baseliner", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/isaaceindhoven/php-code-sniffer-baseliner.git", + "reference": "2c4e8ef2763b925cb0bb6aa2a0b3542f107db3b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/isaaceindhoven/php-code-sniffer-baseliner/zipball/2c4e8ef2763b925cb0bb6aa2a0b3542f107db3b2", + "reference": "2c4e8ef2763b925cb0bb6aa2a0b3542f107db3b2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-simplexml": "*", + "php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "require-dev": { + "isaac/php-code-sniffer-standard": "^28.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.6.8", + "phpstan/phpstan-phpunit": "^1.1.1", + "phpstan/phpstan-strict-rules": "^1.2.3", + "phpunit/phpunit": "^9.5" + }, + "bin": [ + "bin/phpcs-baseliner" + ], + "type": "library", + "autoload": { + "psr-4": { + "ISAAC\\CodeSnifferBaseliner\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "ISAAC PHP Code Sniffer Baseliner", + "support": { + "issues": "https://github.com/isaaceindhoven/php-code-sniffer-baseliner/issues", + "source": "https://github.com/isaaceindhoven/php-code-sniffer-baseliner/tree/v2.3.1" + }, + "time": "2022-11-16T13:51:09+00:00" }, { "name": "php-coveralls/php-coveralls", @@ -2522,6 +3150,59 @@ }, "time": "2022-09-12T20:47:09+00:00" }, + { + "name": "php-cs-fixer/diff", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/diff.git", + "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/29dc0d507e838c4580d018bd8b5cb412474f7ec3", + "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", + "symfony/process": "^3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "sebastian/diff v3 backport support for PHP 5.6+", + "homepage": "https://github.com/PHP-CS-Fixer", + "keywords": [ + "diff" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/diff/issues", + "source": "https://github.com/PHP-CS-Fixer/diff/tree/v2.0.2" + }, + "abandoned": true, + "time": "2020-10-14T08:32:19+00:00" + }, { "name": "phpcompatibility/php-compatibility", "version": "9.3.5", @@ -2586,16 +3267,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.9.2", + "version": "1.9.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa" + "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d6fdf01c53978b6429f1393ba4afeca39cc68afa", - "reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d03bccee595e2146b7c9d174486b84f4dc61b0f2", + "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2", "shasum": "" }, "require": { @@ -2625,7 +3306,7 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.9.2" + "source": "https://github.com/phpstan/phpstan/tree/1.9.4" }, "funding": [ { @@ -2641,7 +3322,7 @@ "type": "tidelift" } ], - "time": "2022-11-10T09:56:11+00:00" + "time": "2022-12-17T13:33:52+00:00" }, { "name": "phpstan/phpstan-mockery", @@ -2695,21 +3376,21 @@ }, { "name": "phpstan/phpstan-phpunit", - "version": "1.2.2", + "version": "1.3.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "dea1f87344c6964c607d9076dee42d891f3923f0" + "reference": "cd9c6938f8bbfcb6da3ed5a3c7ea60873825d088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/dea1f87344c6964c607d9076dee42d891f3923f0", - "reference": "dea1f87344c6964c607d9076dee42d891f3923f0", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/cd9c6938f8bbfcb6da3ed5a3c7ea60873825d088", + "reference": "cd9c6938f8bbfcb6da3ed5a3c7ea60873825d088", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.8.11" + "phpstan/phpstan": "^1.9.3" }, "conflict": { "phpunit/phpunit": "<7.0" @@ -2741,9 +3422,58 @@ "description": "PHPUnit extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.2.2" + "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.2" + }, + "time": "2022-12-13T15:08:22+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" }, - "time": "2022-10-28T10:23:07+00:00" + "time": "2016-08-06T20:24:11+00:00" }, { "name": "psr/container", @@ -3753,6 +4483,138 @@ ], "time": "2022-09-21T19:53:16+00:00" }, + { + "name": "symfony/finder", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.4.11" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-29T07:37:50+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/54f14e36aa73cb8f7261d7686691fd4d75ea2690", + "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v5.4.11" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-20T13:00:38+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.27.0", @@ -4324,6 +5186,68 @@ ], "time": "2022-11-03T14:55:06+00:00" }, + { + "name": "symfony/process", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v5.4.11" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T16:58:25+00:00" + }, { "name": "symfony/service-contracts", "version": "v2.5.2", diff --git a/php/WP_Mock.php b/php/WP_Mock.php index 37db9373..861bd0bd 100644 --- a/php/WP_Mock.php +++ b/php/WP_Mock.php @@ -33,525 +33,561 @@ use WP_Mock\Matcher\FuzzyObject; -class WP_Mock { - /** - * @var \WP_Mock\EventManager - */ - protected static $event_manager; - - /** - * @var \WP_Mock\Functions - */ - protected static $function_manager; - - protected static $__bootstrapped = false; - - protected static $__use_patchwork = false; - - protected static $__strict_mode = false; - - protected static $deprecated_listener; - - /** - * @param boolean $use_patchwork - */ - public static function setUsePatchwork( $use_patchwork ) { - if ( ! self::$__bootstrapped ) { - self::$__use_patchwork = (bool) $use_patchwork; - } - } - - public static function usingPatchwork() { - return (bool) self::$__use_patchwork; - } - - /** - * Check whether strict mode is turned on - * - * @return bool - */ - public static function strictMode() { - return (bool) self::$__strict_mode; - } - - /** - * Turns on strict mode - */ - public static function activateStrictMode() { - if ( ! self::$__bootstrapped ) { - self::$__strict_mode = true; - } - } - - /** - * Bootstrap WP_Mock - */ - public static function bootstrap() { - if ( ! self::$__bootstrapped ) { - self::$__bootstrapped = true; - static::$deprecated_listener = new \WP_Mock\DeprecatedListener(); - require_once __DIR__ . '/WP_Mock/API/function-mocks.php'; - require_once __DIR__ . '/WP_Mock/API/constant-mocks.php'; - if ( self::usingPatchwork() ) { - $possible_locations = array( - 'vendor', - '../..', - ); - $patchwork_path = 'antecedent/patchwork/Patchwork.php'; - foreach ( $possible_locations as $loc ) { - $path = __DIR__ . "/../$loc/$patchwork_path"; - if ( file_exists( $path ) ) { - break; - } - } - // Will cause a fatal error if patchwork can't be found - require_once( $path ); - } - self::setUp(); - } - } - - /** - * Make sure Mockery doesn't have anything set up already. - */ - public static function setUp() : void { - if ( self::$__bootstrapped ) { - \Mockery::close(); - - self::$event_manager = new \WP_Mock\EventManager(); - self::$function_manager = new \WP_Mock\Functions(); - } else { - self::bootstrap(); - } - } - - /** - * Tear down anything built up inside Mockery when we're ready to do so. - */ - public static function tearDown() : void { - self::$event_manager->flush(); - self::$function_manager->flush(); - - \Mockery::close(); - \WP_Mock\Handler::cleanup(); - } - - /** - * Fire a specific (mocked) callback when an apply_filters() call is used. - * - * @param string $filter - * - * @return \WP_Mock\Filter - */ - public static function onFilter( $filter ) { - self::$event_manager->called($filter,'filter'); - return self::$event_manager->filter( $filter ); - } - - /** - * Fire a specific (mocked) callback when a do_action() call is used. - * - * @param string $action - * - * @return \WP_Mock\Action - */ - public static function onAction( $action ) { - return self::$event_manager->action( $action ); - } - - /** - * Get a filter or action added callback object - * - * @param string $hook - * @param string $type - * - * @return \WP_Mock\HookedCallback - */ - public static function onHookAdded( $hook, $type = 'filter' ) { - return self::$event_manager->callback( $hook, $type ); - } - - /** - * Get a filter added callback object - * - * @param string $hook - * - * @return \WP_Mock\HookedCallback - */ - public static function onFilterAdded( $hook ) { - return self::onHookAdded( $hook, 'filter' ); - } - - /** - * Get an action added callback object - * - * @param string $hook - * - * @return \WP_Mock\HookedCallback - */ - public static function onActionAdded( $hook ) { - return self::onHookAdded( $hook, 'action' ); - } - - /** - * Alert the Event Manager that an action has been invoked. - * - * @param string $action - */ - public static function invokeAction( $action ) { - self::$event_manager->called( $action ); - } - - public static function addFilter( $hook ) { - self::addHook( $hook, 'filter' ); - } - - public static function addAction( $hook ) { - self::addHook( $hook, 'action' ); - } - - public static function addHook( $hook, $type = 'filter' ) { - $type_name = "$type::$hook"; - self::$event_manager->called( $type_name, 'callback' ); - } - - /** - * Set up the expectation that an action will be called during the test. - * - * Mock a WordPress action, regardless of the parameters used. This call merely - * verifies that the action is invoked by the tested method. - * - * @param string $action Action we expect the method to call - */ - public static function expectAction( $action ) { - $intercept = \Mockery::mock( 'intercept' ); - $intercept->shouldReceive( 'intercepted' )->atLeast()->once(); - $args = func_get_args(); - $args = count( $args ) > 1 ? array_slice( $args, 1 ) : array( null ); - - $mocked_action = self::onAction( $action ); - $responder = call_user_func_array( array( $mocked_action, 'with' ), $args ); - $responder->perform( array( $intercept, 'intercepted' ) ); - } - - /** - * Set up the expectation that a filter will be applied during the test. - * - * Mock a WordPress filter with specific arguments. You need all arguments that you expect - * in order to fulfill the expectation. - * - * @param string $filter - */ - public static function expectFilter( $filter ) { - $intercept = \Mockery::mock( 'intercept' ); - $intercept->shouldReceive( 'intercepted' )->atLeast()->once()->andReturnUsing( function( $value ) { - return $value; - } ); - $args = func_num_args() > 1 ? array_slice( func_get_args(), 1 ) : array( null ); - - $mocked_filter = self::onFilter( $filter ); - $responder = call_user_func_array( array( $mocked_filter, 'with' ), $args ); - $responder->reply( new \WP_Mock\InvokedFilterValue( array( $intercept, 'intercepted' ) ) ); - } - - /** - * Assert that all actions are called. - */ - public static function assertActionsCalled() { - $allActionsCalled = self::$event_manager->allActionsCalled(); - $failed = implode( ', ', self::$event_manager->expectedActions() ); - \PHPUnit\Framework\Assert::assertTrue( $allActionsCalled, 'Method failed to invoke actions: ' . $failed ); - } - - /** - * Assert that all filters are called. - */ - public static function assertFiltersCalled() { - $allFiltersCalled = self::$event_manager->allFiltersCalled(); - $failed = implode( ', ', self::$event_manager->expectedFilters() ); - \PHPUnit\Framework\Assert::assertTrue( $allFiltersCalled, 'Method failed to invoke filters: ' . $failed ); - } - - /** - * Add an expectation that an action should be added - * - * Really just a wrapper function for expectHookAdded() - * - * @param string $action The action name - * @param callable $callback The callback that should be registered - * @param int $priority The priority it should be registered at - * @param int $args The number of arguments that should be allowed - */ - public static function expectActionAdded( $action, $callback, $priority = 10, $args = 1 ) { - self::expectHookAdded( 'action', $action, $callback, $priority, $args ); - } - - /** - * Add an expection that an action should not be added. A wrapper - * around the expectHookNotAdded function. - * - * @param string $action The action hook name - * @param callable $callback The action callback - */ - public static function expectActionNotAdded( $action, $callback ) { - self::expectHookNotAdded( 'action', $action, $callback ); - } - - /** - * Add an expectation that a filter should be added - * - * Really just a wrapper function for expectHookAdded() - * - * @param string $filter The action name - * @param callable $callback The callback that should be registered - * @param int $priority The priority it should be registered at - * @param int $args The number of arguments that should be allowed - */ - public static function expectFilterAdded( $filter, $callback, $priority = 10, $args = 1 ) { - self::expectHookAdded( 'filter', $filter, $callback, $priority, $args ); - } - - /** - * Adds an expectation that a filter will not be added. A wrapper - * around the expectHookNotAdded function. - * - * @param string $filter The filter hook name - * @param callable $callback The filter callback - */ - public static function expectFilterNotAdded( $filter, $callback ) { - self::expectHookNotAdded( 'filter', $filter, $callback ); - } - - /** - * Add an expectation that a hook should be added - * - * @param string $type The type of hook being added - * @param string $action The action name - * @param callable $callback The callback that should be registered - * @param int $priority The priority it should be registered at - * @param int $args The number of arguments that should be allowed - */ - public static function expectHookAdded( $type, $action, $callback, $priority = 10, $args = 1 ) { - $intercept = \Mockery::mock( 'intercept' ); - $intercept->shouldReceive( 'intercepted' )->atLeast()->once(); - - /** @var WP_Mock\HookedCallbackResponder $responder */ - $responder = self::onHookAdded( $action, $type ) - ->with( $callback, $priority, $args ); - $responder->perform( array( $intercept, 'intercepted' ) ); - } - - /** - * Adds an expectation that a hook should not be added. Based on the - * shouldNotReceive API of Mocker. - * - * @param string $type The hook type, 'action' or 'filter' - * @param string $action The name of the hook - * @param callable $callback The hooks callback handler. - */ - public static function expectHookNotAdded( $type, $action, $callback ) { - $intercept = \Mockery::mock( 'intercept' ); - $intercept->shouldNotReceive( 'intercepted' ); - - /** @var WP_Mock\HookedCallbackResponder $responder */ - $responder = self::onHookAdded( $action, $type ) - ->with( $callback, 10, 1 ); - $responder->perform( array( $intercept, 'intercepted' ) ); - } - - /** - * Assert that all hooks are added. - */ - public static function assertHooksAdded() { - $allHooksAdded = self::$event_manager->allHooksAdded(); - $failed = implode( ', ', self::$event_manager->expectedHooks() ); - PHPUnit\Framework\Assert::assertTrue( $allHooksAdded, 'Method failed to add hooks: ' . $failed ); - } - - /** - * Mock a WordPress API function - * - * This function registers a mock object for a WordPress function and, if - * necessary, dynamically defines the function. Pass the function name as - * the first argument (e.g. wp_remote_get) and pass in details about the - * expectations in the $arguments array. The arguments array has a few - * options for defining expectations about how the WordPress function should - * be used during a test. Currently, it accepts the following settings: - * - * - times: Defines expectations for the number of times a function should - * be called. The default is 0 or more times. To expect the function to be - * called an exact amount of times, set times to a non-negative numeric - * value. To specify that the function should be called a minimum number - * of times, use a string with the minimum followed by '+' (e.g. '3+' - * means 3 or more times). Append a '-' to indicate a maximum number of - * times a function should be called (e.g. '3-' means no more than 3 times) - * To indicate a range, use '-' between two numbers (e.g. '2-5' means at - * least 2 times and no more than 5 times) - * - return: Defines the value (if any) that the function should return. If - * you pass a Closure as the return value, the function will return - * whatever the Closure's return value. - * - return_in_order: Use this if your function will be called multiple - * times in the test but needs to have different return values. Set this to - * an array of return values. Each time the function is called, it will - * return the next value in the sequence until it reaches the last value, - * which will become the return value for all subsequent calls. For - * example, if I am mocking is_single(), I can set return_in_order to - * array( false, true ). The first time is_single() is called it will - * return false. The second and all subsequent times it will return true. - * Setting this value overrides return, so if you set both, return will be - * ignored. - * - return_arg: Use this to specify that the function should return one of - * its arguments. return_arg should be the position of the argument in the - * arguments array, so 0 for the first argument, 1 for the second, etc. - * You can also set this to true, which is equivalent to 0. This will - * override both return and return_in_order. - * - args: Use this to set expectations about what the arguments passed to - * the function should be. This value should always be an array with the - * arguments in order. Like with return, if you use a Closure, its return - * value will be used to validate the argument expectations. WP_Mock has - * several helper functions to make this feature more flexible. The are - * static methods on the \WP_Mock\Functions class. They are: - * - Functions::type( $type ) Expects an argument of a certain type. This - * can be any core PHP data type (string, int, resource, callable, etc.) - * or any class or interface name. - * - Functions::anyOf( $values ) Expects the argument to be any value in - * the $values array - * In addition to these helper functions, you can indicate that the - * argument can be any value of any type by using '*'. So, for example, if - * I am expecting get_post_meta to be called, the args array might look - * something like this: - * array( $post->ID, 'some_meta_key', true ) - * - * Returns the Mockery\Expectation object with the function expectations - * added. It is possible to use Mockery methods to add expectations to the - * object returned, which will then be combined with any expectations that - * may have been passed as arguments. - * - * @param string $function_name - * @param array $arguments - * - * @return Mockery\Expectation - */ - public static function userFunction( $function_name, $arguments = array() ) { - return self::$function_manager->register( $function_name, $arguments ); - } - - /** - * Alias for userFunction - * - * @deprecated since 1.0 - * - * @param string $function_name - * @param array $arguments - * - * @return Mockery\Expectation - */ - public static function wpFunction( $function_name, $arguments = array() ) { - static::getDeprecatedListener()->logDeprecatedCall( __METHOD__, array( $function_name, $arguments ) ); - return self::userFunction( $function_name, $arguments ); - } - - /** - * A wrapper for userFunction that will simply set/override the return to be - * a function that echoes the value that its passed. For example, esc_attr_e - * may need to be mocked, and it must echo some value. echoFunction will set - * esc_attr_e to echo the value its passed. - * - * \WP_Mock::echoFunction( 'esc_attr_e' ); - * esc_attr_e( 'some_value' ); // echoes (translated) "some_value" - * - * @param string $function_name Function name. - * @param array $arguments Optional. Arguments. Defaults to array(). - * - * @return Mockery\Expectation - */ - public static function echoFunction( $function_name, $arguments = array() ) { - $arguments = (array) $arguments; - $arguments['return'] = function ( $param ) { - echo $param; - }; - return self::$function_manager->register( $function_name, $arguments ); - } - - /** - * A wrapper for userFunction that will simply set/override the return to be - * a function that returns the value that its passed. For example, esc_attr - * may need to be mocked, and it must return some value. passthruFunction - * will set esc_attr to return the value its passed. - * - * \WP_Mock::passthruFunction( 'esc_attr' ); - * echo esc_attr( 'some_value' ); // echoes "some_value" - * - * @param string $function_name - * @param array $arguments - * - * @return Mockery\Expectation - */ - public static function passthruFunction( $function_name, $arguments = array() ) { - $arguments = (array) $arguments; - $arguments['return'] = function ( $param ) { - return $param; - }; - return self::$function_manager->register( $function_name, $arguments ); - } - - /** - * Alias for passthruFunction - * - * @deprecated since 1.0 - * - * @param string $function_name - * @param array $arguments - * - * @return Mockery\Expectation - */ - public static function wpPassthruFunction( $function_name, $arguments = array() ) { - static::getDeprecatedListener()->logDeprecatedCall( __METHOD__, array( $function_name, $arguments ) ); - return self::passthruFunction( $function_name, $arguments ); - } - - /** - * Add a function mock that aliases another callable. - * - * e.g.: WP_Mock::alias( 'wp_hash', 'md5' ); - * - * @param string $function_name - * @param callable $alias - * @param array $arguments - * - * @return Mockery\Expectation - */ - public static function alias( $function_name, $alias, $arguments = array() ) { - $arguments = (array) $arguments; - if ( is_callable( $alias ) ) { - $arguments['return'] = function () use ( $alias ) { - return call_user_func_array( $alias, func_get_args() ); - }; - } - return self::$function_manager->register( $function_name, $arguments ); - } - - /** - * Generate a fuzzy object match expectation - * - * This will let you fuzzy match objects based on their properties without - * needing to use the identical (===) operator. This is helpful when the - * object being passed to a function is constructed inside the scope of the - * function being tested but where you want to make assertions on more than - * just the type of the object. - * - * @param $thing - * - * @return FuzzyObject - */ - public static function fuzzyObject( $thing ) { - return new FuzzyObject( $thing ); - } - - /** - * @return \WP_Mock\DeprecatedListener - */ - public static function getDeprecatedListener() { - return static::$deprecated_listener; - } +class WP_Mock +{ + /** + * @var \WP_Mock\EventManager + */ + protected static $event_manager; + + /** + * @var \WP_Mock\Functions + */ + protected static $function_manager; + + protected static $__bootstrapped = false; + + protected static $__use_patchwork = false; + + protected static $__strict_mode = false; + + protected static $deprecated_listener; + + /** + * @param boolean $use_patchwork + */ + public static function setUsePatchwork($use_patchwork) + { + if (! self::$__bootstrapped) { + self::$__use_patchwork = (bool) $use_patchwork; + } + } + + public static function usingPatchwork() + { + return (bool) self::$__use_patchwork; + } + + /** + * Check whether strict mode is turned on + * + * @return bool + */ + public static function strictMode() + { + return (bool) self::$__strict_mode; + } + + /** + * Turns on strict mode + */ + public static function activateStrictMode() + { + if (! self::$__bootstrapped) { + self::$__strict_mode = true; + } + } + + /** + * Bootstrap WP_Mock + */ + public static function bootstrap() + { + if (! self::$__bootstrapped) { + self::$__bootstrapped = true; + static::$deprecated_listener = new \WP_Mock\DeprecatedListener(); + require_once __DIR__ . '/WP_Mock/API/function-mocks.php'; + require_once __DIR__ . '/WP_Mock/API/constant-mocks.php'; + if (self::usingPatchwork()) { + $possible_locations = array( + 'vendor', + '../..', + ); + $patchwork_path = 'antecedent/patchwork/Patchwork.php'; + foreach ($possible_locations as $loc) { + $path = __DIR__ . "/../$loc/$patchwork_path"; + if (file_exists($path)) { + break; + } + } + // Will cause a fatal error if patchwork can't be found + require_once($path); + } + self::setUp(); + } + } + + /** + * Make sure Mockery doesn't have anything set up already. + */ + public static function setUp(): void + { + if (self::$__bootstrapped) { + \Mockery::close(); + + self::$event_manager = new \WP_Mock\EventManager(); + self::$function_manager = new \WP_Mock\Functions(); + } else { + self::bootstrap(); + } + } + + /** + * Tear down anything built up inside Mockery when we're ready to do so. + */ + public static function tearDown(): void + { + self::$event_manager->flush(); + self::$function_manager->flush(); + + \Mockery::close(); + \WP_Mock\Handler::cleanup(); + } + + /** + * Fire a specific (mocked) callback when an apply_filters() call is used. + * + * @param string $filter + * + * @return \WP_Mock\Filter + */ + public static function onFilter($filter) + { + self::$event_manager->called($filter, 'filter'); + return self::$event_manager->filter($filter); + } + + /** + * Fire a specific (mocked) callback when a do_action() call is used. + * + * @param string $action + * + * @return \WP_Mock\Action + */ + public static function onAction($action) + { + return self::$event_manager->action($action); + } + + /** + * Get a filter or action added callback object + * + * @param string $hook + * @param string $type + * + * @return \WP_Mock\HookedCallback + */ + public static function onHookAdded($hook, $type = 'filter') + { + return self::$event_manager->callback($hook, $type); + } + + /** + * Get a filter added callback object + * + * @param string $hook + * + * @return \WP_Mock\HookedCallback + */ + public static function onFilterAdded($hook) + { + return self::onHookAdded($hook, 'filter'); + } + + /** + * Get an action added callback object + * + * @param string $hook + * + * @return \WP_Mock\HookedCallback + */ + public static function onActionAdded($hook) + { + return self::onHookAdded($hook, 'action'); + } + + /** + * Alert the Event Manager that an action has been invoked. + * + * @param string $action + */ + public static function invokeAction($action) + { + self::$event_manager->called($action); + } + + public static function addFilter($hook) + { + self::addHook($hook, 'filter'); + } + + public static function addAction($hook) + { + self::addHook($hook, 'action'); + } + + public static function addHook($hook, $type = 'filter') + { + $type_name = "$type::$hook"; + self::$event_manager->called($type_name, 'callback'); + } + + /** + * Set up the expectation that an action will be called during the test. + * + * Mock a WordPress action, regardless of the parameters used. This call merely + * verifies that the action is invoked by the tested method. + * + * @param string $action Action we expect the method to call + */ + public static function expectAction($action) + { + $intercept = \Mockery::mock('intercept'); + $intercept->shouldReceive('intercepted')->atLeast()->once(); + $args = func_get_args(); + $args = count($args) > 1 ? array_slice($args, 1) : array( null ); + + $mocked_action = self::onAction($action); + $responder = call_user_func_array(array( $mocked_action, 'with' ), $args); + $responder->perform(array( $intercept, 'intercepted' )); + } + + /** + * Set up the expectation that a filter will be applied during the test. + * + * Mock a WordPress filter with specific arguments. You need all arguments that you expect + * in order to fulfill the expectation. + * + * @param string $filter + */ + public static function expectFilter($filter) + { + $intercept = \Mockery::mock('intercept'); + $intercept->shouldReceive('intercepted')->atLeast()->once()->andReturnUsing(function ($value) { + return $value; + }); + $args = func_num_args() > 1 ? array_slice(func_get_args(), 1) : array( null ); + + $mocked_filter = self::onFilter($filter); + $responder = call_user_func_array(array( $mocked_filter, 'with' ), $args); + $responder->reply(new \WP_Mock\InvokedFilterValue(array( $intercept, 'intercepted' ))); + } + + /** + * Assert that all actions are called. + */ + public static function assertActionsCalled() + { + $allActionsCalled = self::$event_manager->allActionsCalled(); + $failed = implode(', ', self::$event_manager->expectedActions()); + \PHPUnit\Framework\Assert::assertTrue($allActionsCalled, 'Method failed to invoke actions: ' . $failed); + } + + /** + * Assert that all filters are called. + */ + public static function assertFiltersCalled() + { + $allFiltersCalled = self::$event_manager->allFiltersCalled(); + $failed = implode(', ', self::$event_manager->expectedFilters()); + \PHPUnit\Framework\Assert::assertTrue($allFiltersCalled, 'Method failed to invoke filters: ' . $failed); + } + + /** + * Add an expectation that an action should be added + * + * Really just a wrapper function for expectHookAdded() + * + * @param string $action The action name + * @param callable $callback The callback that should be registered + * @param int $priority The priority it should be registered at + * @param int $args The number of arguments that should be allowed + */ + public static function expectActionAdded($action, $callback, $priority = 10, $args = 1) + { + self::expectHookAdded('action', $action, $callback, $priority, $args); + } + + /** + * Add an expection that an action should not be added. A wrapper + * around the expectHookNotAdded function. + * + * @param string $action The action hook name + * @param callable $callback The action callback + */ + public static function expectActionNotAdded($action, $callback) + { + self::expectHookNotAdded('action', $action, $callback); + } + + /** + * Add an expectation that a filter should be added + * + * Really just a wrapper function for expectHookAdded() + * + * @param string $filter The action name + * @param callable $callback The callback that should be registered + * @param int $priority The priority it should be registered at + * @param int $args The number of arguments that should be allowed + */ + public static function expectFilterAdded($filter, $callback, $priority = 10, $args = 1) + { + self::expectHookAdded('filter', $filter, $callback, $priority, $args); + } + + /** + * Adds an expectation that a filter will not be added. A wrapper + * around the expectHookNotAdded function. + * + * @param string $filter The filter hook name + * @param callable $callback The filter callback + */ + public static function expectFilterNotAdded($filter, $callback) + { + self::expectHookNotAdded('filter', $filter, $callback); + } + + /** + * Add an expectation that a hook should be added + * + * @param string $type The type of hook being added + * @param string $action The action name + * @param callable $callback The callback that should be registered + * @param int $priority The priority it should be registered at + * @param int $args The number of arguments that should be allowed + */ + public static function expectHookAdded($type, $action, $callback, $priority = 10, $args = 1) + { + $intercept = \Mockery::mock('intercept'); + $intercept->shouldReceive('intercepted')->atLeast()->once(); + + /** @var WP_Mock\HookedCallbackResponder $responder */ + $responder = self::onHookAdded($action, $type) + ->with($callback, $priority, $args); + $responder->perform(array( $intercept, 'intercepted' )); + } + + /** + * Adds an expectation that a hook should not be added. Based on the + * shouldNotReceive API of Mocker. + * + * @param string $type The hook type, 'action' or 'filter' + * @param string $action The name of the hook + * @param callable $callback The hooks callback handler. + */ + public static function expectHookNotAdded($type, $action, $callback) + { + $intercept = \Mockery::mock('intercept'); + $intercept->shouldNotReceive('intercepted'); + + /** @var WP_Mock\HookedCallbackResponder $responder */ + $responder = self::onHookAdded($action, $type) + ->with($callback, 10, 1); + $responder->perform(array( $intercept, 'intercepted' )); + } + + /** + * Assert that all hooks are added. + */ + public static function assertHooksAdded() + { + $allHooksAdded = self::$event_manager->allHooksAdded(); + $failed = implode(', ', self::$event_manager->expectedHooks()); + PHPUnit\Framework\Assert::assertTrue($allHooksAdded, 'Method failed to add hooks: ' . $failed); + } + + /** + * Mock a WordPress API function + * + * This function registers a mock object for a WordPress function and, if + * necessary, dynamically defines the function. Pass the function name as + * the first argument (e.g. wp_remote_get) and pass in details about the + * expectations in the $arguments array. The arguments array has a few + * options for defining expectations about how the WordPress function should + * be used during a test. Currently, it accepts the following settings: + * + * - times: Defines expectations for the number of times a function should + * be called. The default is 0 or more times. To expect the function to be + * called an exact amount of times, set times to a non-negative numeric + * value. To specify that the function should be called a minimum number + * of times, use a string with the minimum followed by '+' (e.g. '3+' + * means 3 or more times). Append a '-' to indicate a maximum number of + * times a function should be called (e.g. '3-' means no more than 3 times) + * To indicate a range, use '-' between two numbers (e.g. '2-5' means at + * least 2 times and no more than 5 times) + * - return: Defines the value (if any) that the function should return. If + * you pass a Closure as the return value, the function will return + * whatever the Closure's return value. + * - return_in_order: Use this if your function will be called multiple + * times in the test but needs to have different return values. Set this to + * an array of return values. Each time the function is called, it will + * return the next value in the sequence until it reaches the last value, + * which will become the return value for all subsequent calls. For + * example, if I am mocking is_single(), I can set return_in_order to + * array( false, true ). The first time is_single() is called it will + * return false. The second and all subsequent times it will return true. + * Setting this value overrides return, so if you set both, return will be + * ignored. + * - return_arg: Use this to specify that the function should return one of + * its arguments. return_arg should be the position of the argument in the + * arguments array, so 0 for the first argument, 1 for the second, etc. + * You can also set this to true, which is equivalent to 0. This will + * override both return and return_in_order. + * - args: Use this to set expectations about what the arguments passed to + * the function should be. This value should always be an array with the + * arguments in order. Like with return, if you use a Closure, its return + * value will be used to validate the argument expectations. WP_Mock has + * several helper functions to make this feature more flexible. The are + * static methods on the \WP_Mock\Functions class. They are: + * - Functions::type( $type ) Expects an argument of a certain type. This + * can be any core PHP data type (string, int, resource, callable, etc.) + * or any class or interface name. + * - Functions::anyOf( $values ) Expects the argument to be any value in + * the $values array + * In addition to these helper functions, you can indicate that the + * argument can be any value of any type by using '*'. So, for example, if + * I am expecting get_post_meta to be called, the args array might look + * something like this: + * array( $post->ID, 'some_meta_key', true ) + * + * Returns the Mockery\Expectation object with the function expectations + * added. It is possible to use Mockery methods to add expectations to the + * object returned, which will then be combined with any expectations that + * may have been passed as arguments. + * + * @param string $function_name + * @param array $arguments + * + * @return Mockery\Expectation + */ + public static function userFunction($function_name, $arguments = array()) + { + return self::$function_manager->register($function_name, $arguments); + } + + /** + * Alias for userFunction + * + * @deprecated since 1.0 + * + * @param string $function_name + * @param array $arguments + * + * @return Mockery\Expectation + */ + public static function wpFunction($function_name, $arguments = array()) + { + static::getDeprecatedListener()->logDeprecatedCall(__METHOD__, array( $function_name, $arguments )); + return self::userFunction($function_name, $arguments); + } + + /** + * A wrapper for userFunction that will simply set/override the return to be + * a function that echoes the value that its passed. For example, esc_attr_e + * may need to be mocked, and it must echo some value. echoFunction will set + * esc_attr_e to echo the value its passed. + * + * \WP_Mock::echoFunction( 'esc_attr_e' ); + * esc_attr_e( 'some_value' ); // echoes (translated) "some_value" + * + * @param string $function_name Function name. + * @param array $arguments Optional. Arguments. Defaults to array(). + * + * @return Mockery\Expectation + */ + public static function echoFunction($function_name, $arguments = array()) + { + $arguments = (array) $arguments; + $arguments['return'] = function ($param) { + echo $param; + }; + return self::$function_manager->register($function_name, $arguments); + } + + /** + * A wrapper for userFunction that will simply set/override the return to be + * a function that returns the value that its passed. For example, esc_attr + * may need to be mocked, and it must return some value. passthruFunction + * will set esc_attr to return the value its passed. + * + * \WP_Mock::passthruFunction( 'esc_attr' ); + * echo esc_attr( 'some_value' ); // echoes "some_value" + * + * @param string $function_name + * @param array $arguments + * + * @return Mockery\Expectation + */ + public static function passthruFunction($function_name, $arguments = array()) + { + $arguments = (array) $arguments; + $arguments['return'] = function ($param) { + return $param; + }; + return self::$function_manager->register($function_name, $arguments); + } + + /** + * Alias for passthruFunction + * + * @deprecated since 1.0 + * + * @param string $function_name + * @param array $arguments + * + * @return Mockery\Expectation + */ + public static function wpPassthruFunction($function_name, $arguments = array()) + { + static::getDeprecatedListener()->logDeprecatedCall(__METHOD__, array( $function_name, $arguments )); + return self::passthruFunction($function_name, $arguments); + } + + /** + * Add a function mock that aliases another callable. + * + * e.g.: WP_Mock::alias( 'wp_hash', 'md5' ); + * + * @param string $function_name + * @param callable $alias + * @param array $arguments + * + * @return Mockery\Expectation + */ + public static function alias($function_name, $alias, $arguments = array()) + { + $arguments = (array) $arguments; + if (is_callable($alias)) { + $arguments['return'] = function () use ($alias) { + return call_user_func_array($alias, func_get_args()); + }; + } + return self::$function_manager->register($function_name, $arguments); + } + + /** + * Generate a fuzzy object match expectation + * + * This will let you fuzzy match objects based on their properties without + * needing to use the identical (===) operator. This is helpful when the + * object being passed to a function is constructed inside the scope of the + * function being tested but where you want to make assertions on more than + * just the type of the object. + * + * @param $thing + * + * @return FuzzyObject + */ + public static function fuzzyObject($thing) + { + return new FuzzyObject($thing); + } + + /** + * @return \WP_Mock\DeprecatedListener + */ + public static function getDeprecatedListener() + { + return static::$deprecated_listener; + } } diff --git a/php/WP_Mock/API/constant-mocks.php b/php/WP_Mock/API/constant-mocks.php index aa8f92bf..6aaca279 100644 --- a/php/WP_Mock/API/constant-mocks.php +++ b/php/WP_Mock/API/constant-mocks.php @@ -13,60 +13,60 @@ * the normal default by setting constants in a bootstrap configuration file. */ -if ( ! defined( 'WP_CONTENT_DIR' ) ) { - define( 'WP_CONTENT_DIR', __DIR__ . '/dummy-files' ); +if (! defined('WP_CONTENT_DIR')) { + define('WP_CONTENT_DIR', __DIR__ . '/dummy-files'); } -if ( ! defined( 'ABSPATH' ) ) { - define( 'ABSPATH', '' ); +if (! defined('ABSPATH')) { + define('ABSPATH', ''); } -if ( ! defined( 'WPINC' ) ) { - define( 'WPINC', __DIR__ . '/dummy-files/wp-includes' ); +if (! defined('WPINC')) { + define('WPINC', __DIR__ . '/dummy-files/wp-includes'); } /** * @since 0.71 */ -if ( ! defined( 'EZSQL_VERSION' ) ) { - define( 'EZSQL_VERSION', 'WP1.25' ); +if (! defined('EZSQL_VERSION')) { + define('EZSQL_VERSION', 'WP1.25'); } /** * HHVM does not support case-insensitive constants. - * + * * @since 0.71 * @see http://hhvm.com/blog/3095/getting-wordpress-running-on-hhvm */ -if ( ! defined( 'OBJECT' ) ) { - define( 'OBJECT', 'OBJECT' ); +if (! defined('OBJECT')) { + define('OBJECT', 'OBJECT'); } -if ( ! defined( 'Object' ) ) { - define( 'Object', 'OBJECT' ); +if (! defined('Object')) { + define('Object', 'OBJECT'); } -if ( ! defined( 'object' ) ) { - define( 'object', 'OBJECT' ); +if (! defined('object')) { + define('object', 'OBJECT'); } /** * @since 2.5.0 */ -if ( ! defined( 'OBJECT_K' ) ) { - define( 'OBJECT_K', 'OBJECT_K' ); +if (! defined('OBJECT_K')) { + define('OBJECT_K', 'OBJECT_K'); } /** * @since 0.71 */ -if ( ! defined( 'ARRAY_A' ) ) { - define( 'ARRAY_A', 'ARRAY_A' ); +if (! defined('ARRAY_A')) { + define('ARRAY_A', 'ARRAY_A'); } /** * @since 0.71 */ -if ( ! defined( 'ARRAY_N' ) ) { - define( 'ARRAY_N', 'ARRAY_N' ); +if (! defined('ARRAY_N')) { + define('ARRAY_N', 'ARRAY_N'); } diff --git a/php/WP_Mock/API/function-mocks.php b/php/WP_Mock/API/function-mocks.php index 3d0cf3a8..db463cd9 100644 --- a/php/WP_Mock/API/function-mocks.php +++ b/php/WP_Mock/API/function-mocks.php @@ -1,181 +1,200 @@ react( $function_to_add, (int) $priority, (int) $accepted_args ); - } -} - -if ( ! function_exists( 'do_action' ) ) { - /** - * Execute functions hooked on a specific action hook. - * - * @param string $tag The name of the action to be executed. - * @param mixed $arg,... Optional additional arguments which are passed on to the functions hooked to the action. - * - * @return null Will return null if $tag does not exist in $wp_filter array - */ - function do_action( $tag, $arg = '' ) { - $args = func_get_args(); - $args = array_slice( $args, 1 ); - - return \WP_Mock::onAction( $tag )->react( $args ); - } -} - -if ( ! function_exists( 'add_filter' ) ) { - /** - * Dummy method to prevent filter hooks in constructor from failing. - */ - function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { - \WP_Mock::onFilterAdded( $tag )->react( $function_to_add, (int) $priority, (int) $accepted_args ); - } -} - -if ( ! function_exists( 'apply_filters' ) ) { - /** - * Call the functions added to a filter hook. - * - * @param string $tag The name of the filter hook. - * @param mixed $value The value on which the filters hooked to $tag are applied on. - * @param mixed $var,... Additional variables passed to the functions hooked to $tag. - * - * @return mixed The filtered value after all hooked functions are applied to it. - */ - function apply_filters( $tag, $value ) { - $args = func_get_args(); - $args = array_slice( $args, 1 ); - $args[0] = $value; - - return \WP_Mock::onFilter( $tag )->apply( $args ); - } -} - -if ( ! function_exists( 'esc_html' ) ) { - function esc_html() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( 'esc_attr' ) ) { - function esc_attr() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( 'esc_url' ) ) { - function esc_url() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( 'esc_url_raw' ) ) { - function esc_url_raw() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( 'esc_js' ) ) { - function esc_js() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( 'esc_textarea' ) ) { - function esc_textarea() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( '__' ) ) { - function __() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( '_e' ) ) { - function _e() { - \WP_Mock\Handler::predefined_echo_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( '_x' ) ) { - function _x() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( 'esc_html__' ) ) { - function esc_html__() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} +if (! function_exists('add_action')) { + /** + * Hooks a function on to a specific action. + * + * Actions are the hooks that the WordPress core launches at specific points + * during execution, or when specific events occur. Plugins can specify that + * one or more of its PHP functions are executed at these points, using the + * Action API. + * + * @param string $tag The name of the action to which the $function_to_add is hooked. + * @param callback $function_to_add The name of the function you wish to be called. + * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action. + * @param int $accepted_args optional. The number of arguments the function accept (default 1). + */ + function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) + { + \WP_Mock::onActionAdded($tag)->react($function_to_add, (int) $priority, (int) $accepted_args); + } +} + +if (! function_exists('do_action')) { + /** + * Execute functions hooked on a specific action hook. + * + * @param string $tag The name of the action to be executed. + * @param mixed $arg,... Optional additional arguments which are passed on to the functions hooked to the action. + * + * @return null Will return null if $tag does not exist in $wp_filter array + */ + function do_action($tag, $arg = '') + { + $args = func_get_args(); + $args = array_slice($args, 1); + + return \WP_Mock::onAction($tag)->react($args); + } +} + +if (! function_exists('add_filter')) { + /** + * Dummy method to prevent filter hooks in constructor from failing. + */ + function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) + { + \WP_Mock::onFilterAdded($tag)->react($function_to_add, (int) $priority, (int) $accepted_args); + } +} + +if (! function_exists('apply_filters')) { + /** + * Call the functions added to a filter hook. + * + * @param string $tag The name of the filter hook. + * @param mixed $value The value on which the filters hooked to $tag are applied on. + * @param mixed $var,... Additional variables passed to the functions hooked to $tag. + * + * @return mixed The filtered value after all hooked functions are applied to it. + */ + function apply_filters($tag, $value) + { + $args = func_get_args(); + $args = array_slice($args, 1); + $args[0] = $value; + + return \WP_Mock::onFilter($tag)->apply($args); + } +} + +if (! function_exists('esc_html')) { + function esc_html() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('esc_attr')) { + function esc_attr() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('esc_url')) { + function esc_url() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('esc_url_raw')) { + function esc_url_raw() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('esc_js')) { + function esc_js() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('esc_textarea')) { + function esc_textarea() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('__')) { + function __() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('_e')) { + function _e() + { + \WP_Mock\Handler::predefined_echo_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('_x')) { + function _x() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('esc_html__')) { + function esc_html__() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('esc_html_e')) { + function esc_html_e() + { + \WP_Mock\Handler::predefined_echo_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('esc_html_x')) { + function esc_html_x() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} + +if (! function_exists('esc_attr__')) { + function esc_attr__() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } +} -if ( ! function_exists( 'esc_html_e' ) ) { - function esc_html_e() { - \WP_Mock\Handler::predefined_echo_function_helper( __FUNCTION__, func_get_args() ); - } +if (! function_exists('esc_attr_e')) { + function esc_attr_e() + { + \WP_Mock\Handler::predefined_echo_function_helper(__FUNCTION__, func_get_args()); + } } -if ( ! function_exists( 'esc_html_x' ) ) { - function esc_html_x() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } +if (! function_exists('esc_attr_x')) { + function esc_attr_x() + { + return \WP_Mock\Handler::predefined_return_function_helper(__FUNCTION__, func_get_args()); + } } -if ( ! function_exists( 'esc_attr__' ) ) { - function esc_attr__() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( 'esc_attr_e' ) ) { - function esc_attr_e() { - \WP_Mock\Handler::predefined_echo_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( 'esc_attr_x' ) ) { - function esc_attr_x() { - return \WP_Mock\Handler::predefined_return_function_helper( __FUNCTION__, func_get_args() ); - } -} - -if ( ! function_exists( '_n' ) ) { - - /** - * Dummy method for _n(). - * - * @throws \PHPUnit\Framework\ExpectationFailedException Throws error if too few arguments. - * - * @return mixed singular or plural string based on number. - */ - function _n() { - $args = func_get_args(); - - if ( count( $args ) >= 3 ) { - if ( isset( $args[0] ) && 1 >= intval( $args[2] ) ) { - return $args[0]; - } else { - return $args[1]; - } - } else { - throw new \PHPUnit\Framework\ExpectationFailedException( - sprintf( 'Too few arguments to function %s', __FUNCTION__ ) - ); - } - } +if (! function_exists('_n')) { + /** + * Dummy method for _n(). + * + * @throws \PHPUnit\Framework\ExpectationFailedException Throws error if too few arguments. + * + * @return mixed singular or plural string based on number. + */ + function _n() + { + $args = func_get_args(); + + if (count($args) >= 3) { + if (isset($args[0]) && 1 >= intval($args[2])) { + return $args[0]; + } else { + return $args[1]; + } + } else { + throw new \PHPUnit\Framework\ExpectationFailedException( + sprintf('Too few arguments to function %s', __FUNCTION__) + ); + } + } } diff --git a/php/WP_Mock/Action.php b/php/WP_Mock/Action.php index b984b422..be7beedf 100644 --- a/php/WP_Mock/Action.php +++ b/php/WP_Mock/Action.php @@ -9,69 +9,75 @@ namespace WP_Mock; - -class Action extends Hook { - public function react( $args ) { - \WP_Mock::invokeAction( $this->name ); - - $arg_num = count( $args ); - - if ( 0 === $arg_num ) { - if ( ! isset( $this->processors['argsnull'] ) ) { - $this->strict_check(); - - return; - } - - $this->processors['argsnull']->react(); - } else { - $processors = $this->processors; - for ( $i = 0; $i < $arg_num - 1; $i ++ ) { - $arg = $this->safe_offset( $args[ $i ] ); - - if ( ! isset( $processors[ $arg ] ) ) { - $this->strict_check(); - - return; - } - - $processors = $processors[ $arg ]; - } - - $arg = $this->safe_offset( $args[ $arg_num - 1 ] ); - if ( ! is_array( $processors ) || ! isset( $processors[ $arg ] ) ) { - $this->strict_check(); - - return; - } - - $processors[ $arg ]->react(); - } - } - - protected function new_responder() { - return new Action_Responder(); - } - - /** - * @return string - */ - protected function get_strict_mode_message() { - return sprintf( 'Unexpected use of do_action for action %s', $this->name ); - } +class Action extends Hook +{ + public function react($args) + { + \WP_Mock::invokeAction($this->name); + + $arg_num = count($args); + + if (0 === $arg_num) { + if (! isset($this->processors['argsnull'])) { + $this->strict_check(); + + return; + } + + $this->processors['argsnull']->react(); + } else { + $processors = $this->processors; + for ($i = 0; $i < $arg_num - 1; $i ++) { + $arg = $this->safe_offset($args[ $i ]); + + if (! isset($processors[ $arg ])) { + $this->strict_check(); + + return; + } + + $processors = $processors[ $arg ]; + } + + $arg = $this->safe_offset($args[ $arg_num - 1 ]); + if (! is_array($processors) || ! isset($processors[ $arg ])) { + $this->strict_check(); + + return; + } + + $processors[ $arg ]->react(); + } + } + + protected function new_responder() + { + return new Action_Responder(); + } + + /** + * @return string + */ + protected function get_strict_mode_message() + { + return sprintf('Unexpected use of do_action for action %s', $this->name); + } } -class Action_Responder { - /** - * @var mixed - */ - protected $callable; - - public function perform( $callable ) { - $this->callable = $callable; - } - - public function react() { - call_user_func( $this->callable ); - } +class Action_Responder +{ + /** + * @var mixed + */ + protected $callable; + + public function perform($callable) + { + $this->callable = $callable; + } + + public function react() + { + call_user_func($this->callable); + } } diff --git a/php/WP_Mock/DeprecatedListener.php b/php/WP_Mock/DeprecatedListener.php index 155a6403..9962f64f 100644 --- a/php/WP_Mock/DeprecatedListener.php +++ b/php/WP_Mock/DeprecatedListener.php @@ -2,118 +2,128 @@ namespace WP_Mock; -use \PHPUnit\Framework\TestCase; - -class DeprecatedListener { - - protected $calls = array(); - - /** @var \PHPUnit\Framework\TestCase */ - protected $testResult; - - protected $testName; - - /** - * @var \PHPUnit\Framework\TestCase - */ - protected $testCase; - - public function logDeprecatedCall( $method, array $args = array() ) { - $this->calls[] = array( $method, $args ); - } - - public function reset() { - $this->calls = array(); - } - - public function checkCalls() { - if ( empty( $this->calls ) ) { - return; - } - $e = new \PHPUnit\Framework\RiskyTestError( $this->getMessage() ); - $this->testResult->addFailure( $this->testCase, $e, 0 ); - } - - /** - * @param \PHPUnit\Framework\TestResult $testResult - */ - public function setTestResult( $testResult ) { - $this->testResult = $testResult; - } - - /** - * @param mixed $testName - */ - public function setTestName( $testName ) { - $this->testName = $testName; - } - - public function setTestCase( \PHPUnit\Framework\TestCase $testCase ) { - $this->testCase = $testCase; - } - - protected function getMessage() { - $maxLength = array_reduce( $this->getDeprecatedMethods(), function ( $carry, $item ) { - return max( $carry, strlen( $item ) ); - }, 0 ) + 1; - $message = 'Deprecated WP Mock calls inside ' . $this->testName . ":"; - foreach ( $this->getDeprecatedMethodsWithArgs() as $method => $args ) { - $firstRun = true; - $extra = $maxLength - strlen( $method ); - foreach ( $args as $arg ) { - $message .= "\n "; - if ( $firstRun ) { - $message .= $method . str_repeat( ' ', $extra ); - $firstRun = false; - $extra = $maxLength; - } else { - $message .= str_repeat( ' ', $extra ); - } - $message .= $arg; - } - } - - return $message; - } - - protected function getDeprecatedMethods() { - $methods = array(); - foreach ( $this->calls as $call ) { - $methods[] = $call[0]; - } - - return array_unique( $methods ); - } - - protected function getDeprecatedMethodsWithArgs() { - $collection = array(); - foreach ( $this->calls as $call ) { - $method = $call[0]; - $args = json_encode( array_map( array( $this, 'scalarizeArg' ), $call[1] ) ); - if ( empty( $collection[ $method ] ) ) { - $collection[ $method ] = array(); - } - $collection[ $method ][] = $args; - } - - return array_map( 'array_unique', $collection ); - } - - protected function scalarizeArg( $value ) { - if ( is_scalar( $value ) ) { - return $value; - } elseif ( is_object( $value ) ) { - return '<' . get_class( $value ) . ':' . spl_object_hash( $value ) . '>'; - } elseif ( is_array( $value ) ) { - if ( is_callable( $value ) ) { - return '[' . implode( ',', array_map( array( $this, 'scalarizeArg' ), $value ) ) . ']'; - } else { - return 'Array([' . count( $value ) . '] ...)'; - } - } elseif ( is_resource( $value ) ) { - return 'Resource'; - } else { - return 'Unknown Value'; - } - } +use PHPUnit\Framework\TestCase; + +class DeprecatedListener +{ + protected $calls = array(); + + /** @var \PHPUnit\Framework\TestCase */ + protected $testResult; + + protected $testName; + + /** + * @var \PHPUnit\Framework\TestCase + */ + protected $testCase; + + public function logDeprecatedCall($method, array $args = array()) + { + $this->calls[] = array( $method, $args ); + } + + public function reset() + { + $this->calls = array(); + } + + public function checkCalls() + { + if (empty($this->calls)) { + return; + } + $e = new \PHPUnit\Framework\RiskyTestError($this->getMessage()); + $this->testResult->addFailure($this->testCase, $e, 0); + } + + /** + * @param \PHPUnit\Framework\TestResult $testResult + */ + public function setTestResult($testResult) + { + $this->testResult = $testResult; + } + + /** + * @param mixed $testName + */ + public function setTestName($testName) + { + $this->testName = $testName; + } + + public function setTestCase(\PHPUnit\Framework\TestCase $testCase) + { + $this->testCase = $testCase; + } + + protected function getMessage() + { + $maxLength = array_reduce($this->getDeprecatedMethods(), function ($carry, $item) { + return max($carry, strlen($item)); + }, 0) + 1; + $message = 'Deprecated WP Mock calls inside ' . $this->testName . ":"; + foreach ($this->getDeprecatedMethodsWithArgs() as $method => $args) { + $firstRun = true; + $extra = $maxLength - strlen($method); + foreach ($args as $arg) { + $message .= "\n "; + if ($firstRun) { + $message .= $method . str_repeat(' ', $extra); + $firstRun = false; + $extra = $maxLength; + } else { + $message .= str_repeat(' ', $extra); + } + $message .= $arg; + } + } + + return $message; + } + + protected function getDeprecatedMethods() + { + $methods = array(); + foreach ($this->calls as $call) { + $methods[] = $call[0]; + } + + return array_unique($methods); + } + + protected function getDeprecatedMethodsWithArgs() + { + $collection = array(); + foreach ($this->calls as $call) { + $method = $call[0]; + $args = json_encode(array_map(array( $this, 'scalarizeArg' ), $call[1])); + if (empty($collection[ $method ])) { + $collection[ $method ] = array(); + } + $collection[ $method ][] = $args; + } + + return array_map('array_unique', $collection); + } + + protected function scalarizeArg($value) + { + if (is_scalar($value)) { + return $value; + } elseif (is_object($value)) { + return '<' . get_class($value) . ':' . spl_object_hash($value) . '>'; + } elseif (is_array($value)) { + if (is_callable($value)) { + return '[' . implode(',', array_map(array( $this, 'scalarizeArg' ), $value)) . ']'; + } else { + return 'Array([' . count($value) . '] ...)'; + } + } elseif (is_resource($value)) { + return 'Resource'; + } else { + return 'Unknown Value'; + } + } } diff --git a/php/WP_Mock/EventManager.php b/php/WP_Mock/EventManager.php index 652daa81..7fa58e88 100644 --- a/php/WP_Mock/EventManager.php +++ b/php/WP_Mock/EventManager.php @@ -2,155 +2,168 @@ namespace WP_Mock; -class EventManager { - /** - * @var array - */ - protected $filters; - - /** - * @var array - */ - protected $actions; - - /** - * @var array - */ - protected $expected; - - protected $callbacks; - - public function __construct() { - $this->flush(); - } - - /** - * Clear internal storage. - */ - public function flush() { - $this->filters = array(); - $this->actions = array(); - $this->expected = array(); - } - - /** - * @param string $name Action handler to retrieve - * - * @return Action - */ - public function action( $name ) { - if ( ! isset( $this->actions[ $name ] ) ) { - $this->actions[ $name ] = new Action( $name ); - $this->expected[] = 'action::' . $name; - } - - return $this->actions[ $name ]; - } - - /** - * @param string $name Filter handler to retrieve - * - * @return Filter - */ - public function filter( $name ) { - if ( ! isset( $this->filters[ $name ] ) ) { - $this->filters[ $name ] = new Filter( $name ); - $this->expected[] = 'filter::' . $name; - } - - return $this->filters[ $name ]; - } - - public function callback( $name, $type = 'filter' ) { - $type_name = "$type::$name"; - if ( ! isset( $this->callbacks[ $type_name ] ) ) { - $hookedCallback = new HookedCallback( $name ); - $hookedCallback->setType( $type ); - $this->callbacks[ $type_name ] = $hookedCallback; - $this->expected[] = "callback::$type_name"; - } - - return $this->callbacks[ $type_name ]; - } - - /** - * Remember that a particular hook has been invoked during operation. - * - * @param string $hook - * @param string $type - */ - public function called( $hook, $type = 'action' ) { - $position = array_search( $type . '::' . $hook, $this->expected ); - array_splice( $this->expected, $position, 1 ); - } - - /** - * Return a list of all the actions we're expecting a test to invoke. - * - * @return array - */ - public function expectedActions() { - return array_keys( $this->actions ); - } - - /** - * Return a list of all the filters we're expecting a test to invoke. - * @return array - */ - public function expectedFilters() { - return array_keys( $this->filters ); - } - - /** - * Return a list of all the hooks we're expecting a test to invoke. - * @return array - */ - public function expectedHooks() { - return array_keys( $this->callbacks ); - } - - /** - * Check whether or not all actions have been invoked at least once. - * - * @return bool - */ - public function allActionsCalled() { - foreach( $this->expected as $hook ) { - if ( 0 === strpos( $hook, 'action::' ) ) { - return false; - } - } - - return true; - } - - /** - * Check whether or not all filters have been invoked at least once. - * - * @return bool - */ - public function allFiltersCalled() { - foreach ( $this->expected as $hook ) { - if ( 0 === strpos( $hook, 'filter::' ) ) { - return false; - } - } - - return true; - } - - /** - * Check whether or not all hooks have been invoked at least once. - * - * @return bool - */ - public function allHooksAdded() { - foreach( $this->expected as $hook ) { - if ( 0 === strpos( $hook, 'callback::' ) ) { - return false; - } - } - - return true; - } +class EventManager +{ + /** + * @var array + */ + protected $filters; + + /** + * @var array + */ + protected $actions; + + /** + * @var array + */ + protected $expected; + + protected $callbacks; + + public function __construct() + { + $this->flush(); + } + + /** + * Clear internal storage. + */ + public function flush() + { + $this->filters = array(); + $this->actions = array(); + $this->expected = array(); + } + + /** + * @param string $name Action handler to retrieve + * + * @return Action + */ + public function action($name) + { + if (! isset($this->actions[ $name ])) { + $this->actions[ $name ] = new Action($name); + $this->expected[] = 'action::' . $name; + } + + return $this->actions[ $name ]; + } + + /** + * @param string $name Filter handler to retrieve + * + * @return Filter + */ + public function filter($name) + { + if (! isset($this->filters[ $name ])) { + $this->filters[ $name ] = new Filter($name); + $this->expected[] = 'filter::' . $name; + } + + return $this->filters[ $name ]; + } + + public function callback($name, $type = 'filter') + { + $type_name = "$type::$name"; + if (! isset($this->callbacks[ $type_name ])) { + $hookedCallback = new HookedCallback($name); + $hookedCallback->setType($type); + $this->callbacks[ $type_name ] = $hookedCallback; + $this->expected[] = "callback::$type_name"; + } + + return $this->callbacks[ $type_name ]; + } + + /** + * Remember that a particular hook has been invoked during operation. + * + * @param string $hook + * @param string $type + */ + public function called($hook, $type = 'action') + { + $position = array_search($type . '::' . $hook, $this->expected); + array_splice($this->expected, $position, 1); + } + + /** + * Return a list of all the actions we're expecting a test to invoke. + * + * @return array + */ + public function expectedActions() + { + return array_keys($this->actions); + } + + /** + * Return a list of all the filters we're expecting a test to invoke. + * @return array + */ + public function expectedFilters() + { + return array_keys($this->filters); + } + + /** + * Return a list of all the hooks we're expecting a test to invoke. + * @return array + */ + public function expectedHooks() + { + return array_keys($this->callbacks); + } + + /** + * Check whether or not all actions have been invoked at least once. + * + * @return bool + */ + public function allActionsCalled() + { + foreach ($this->expected as $hook) { + if (0 === strpos($hook, 'action::')) { + return false; + } + } + + return true; + } + + /** + * Check whether or not all filters have been invoked at least once. + * + * @return bool + */ + public function allFiltersCalled() + { + foreach ($this->expected as $hook) { + if (0 === strpos($hook, 'filter::')) { + return false; + } + } + + return true; + } + + /** + * Check whether or not all hooks have been invoked at least once. + * + * @return bool + */ + public function allHooksAdded() + { + foreach ($this->expected as $hook) { + if (0 === strpos($hook, 'callback::')) { + return false; + } + } + + return true; + } } diff --git a/php/WP_Mock/Filter.php b/php/WP_Mock/Filter.php index d1503e98..b272b649 100644 --- a/php/WP_Mock/Filter.php +++ b/php/WP_Mock/Filter.php @@ -9,68 +9,73 @@ namespace WP_Mock; +class Filter extends Hook +{ + /** + * Apply the stored filter. + * + * @param array $args Arguments passed to apply_filters() + * + * @return mixed + */ + public function apply($args) + { + if ($args[0] === null && count($args) === 1) { + if (isset($this->processors['argsnull'])) { + return $this->processors['argsnull']->send(); + } + $this->strict_check(); -class Filter extends Hook { - /** - * Apply the stored filter. - * - * @param array $args Arguments passed to apply_filters() - * - * @return mixed - */ - public function apply( $args ) { - if ( $args[0] === null && count( $args ) === 1 ) { - if ( isset( $this->processors['argsnull'] ) ) { - return $this->processors['argsnull']->send(); - } - $this->strict_check(); + return null; + } - return null; - } + $processors = $this->processors; + foreach ($args as $arg) { + $key = $this->safe_offset($arg); + if (! is_array($processors) || ! isset($processors[ $key ])) { + $this->strict_check(); - $processors = $this->processors; - foreach ( $args as $arg ) { - $key = $this->safe_offset( $arg ); - if ( ! is_array( $processors ) || ! isset( $processors[ $key ] ) ) { - $this->strict_check(); + return $arg; + } - return $arg; - } + $processors = $processors[ $key ]; + } - $processors = $processors[ $key ]; - } + return call_user_func_array(array($processors, 'send'), $args); + } - return call_user_func_array( array($processors, 'send'), $args ); - } + protected function new_responder() + { + return new Filter_Responder(); + } - protected function new_responder() { - return new Filter_Responder(); - } - - /** - * @return string - */ - protected function get_strict_mode_message() { - return sprintf( 'Unexpected use of apply_filters for filter %s', $this->name ); - } + /** + * @return string + */ + protected function get_strict_mode_message() + { + return sprintf('Unexpected use of apply_filters for filter %s', $this->name); + } } -class Filter_Responder { - /** - * @var mixed - */ - protected $value; +class Filter_Responder +{ + /** + * @var mixed + */ + protected $value; - public function reply( $value ) { - $this->value = $value; - } + public function reply($value) + { + $this->value = $value; + } - public function send() { - if ( $this->value instanceof InvokedFilterValue ) { - return call_user_func_array( $this->value, func_get_args() ); - } + public function send() + { + if ($this->value instanceof InvokedFilterValue) { + return call_user_func_array($this->value, func_get_args()); + } - return $this->value; - } + return $this->value; + } } - diff --git a/php/WP_Mock/Functions.php b/php/WP_Mock/Functions.php index 8fdd3279..e9d2497e 100644 --- a/php/WP_Mock/Functions.php +++ b/php/WP_Mock/Functions.php @@ -4,292 +4,301 @@ use Mockery; -class Functions { +class Functions +{ + private $mocked_functions = array(); - private $mocked_functions = array(); + private $internal_functions = array(); - private $internal_functions = array(); + private static $wp_mocked_functions = array(); - private static $wp_mocked_functions = array(); + private $patchwork_functions = array(); - private $patchwork_functions = array(); + /** + * Constructor for the Functions object + */ + public function __construct() + { + Handler::cleanup(); + $this->flush(); + } - /** - * Constructor for the Functions object - */ - public function __construct() { - Handler::cleanup(); - $this->flush(); - } + /** + * Emptys the mocked_functions array + */ + public function flush() + { + $this->mocked_functions = array(); + Handler::cleanup(); + $this->patchwork_functions = array(); + if (function_exists('Patchwork\undoAll')) { + \Patchwork\restoreAll(); + } + if (empty(self::$wp_mocked_functions)) { + self::$wp_mocked_functions = array( + 'add_action', + 'do_action', + 'add_filter', + 'apply_filters', + 'esc_attr', + 'esc_html', + 'esc_js', + 'esc_textarea', + 'esc_url', + 'esc_url_raw', + '__', + '_e', + '_x', + 'esc_attr__', + 'esc_attr_e', + 'esc_attr_x', + 'esc_html__', + 'esc_html_e', + 'esc_html_x', + '_n', + ); + } + } - /** - * Emptys the mocked_functions array - */ - public function flush() { - $this->mocked_functions = array(); - Handler::cleanup(); - $this->patchwork_functions = array(); - if ( function_exists( 'Patchwork\undoAll' ) ) { - \Patchwork\restoreAll(); - } - if ( empty( self::$wp_mocked_functions ) ) { - self::$wp_mocked_functions = array( - 'add_action', - 'do_action', - 'add_filter', - 'apply_filters', - 'esc_attr', - 'esc_html', - 'esc_js', - 'esc_textarea', - 'esc_url', - 'esc_url_raw', - '__', - '_e', - '_x', - 'esc_attr__', - 'esc_attr_e', - 'esc_attr_x', - 'esc_html__', - 'esc_html_e', - 'esc_html_x', - '_n', - ); - } - } + /** + * Registers the function to be mocked and sets up its expectations + * + * @param string $function + * @param array $arguments + * + * @throws \Exception If the function name is invalid + * + * @return Mockery\Expectation + */ + public function register($function, $arguments) + { + $expectation = null; + try { + $this->generate_function($function); + if (empty($this->mocked_functions[$function])) { + $this->mocked_functions[$function] = Mockery::mock('wp_api'); + } + $mock = $this->mocked_functions[$function]; - /** - * Registers the function to be mocked and sets up its expectations - * - * @param string $function - * @param array $arguments - * - * @throws \Exception If the function name is invalid - * - * @return Mockery\Expectation - */ - public function register( $function, $arguments ) { - $expectation = null; - try { - $this->generate_function( $function ); - if ( empty( $this->mocked_functions[$function] ) ) { - $this->mocked_functions[$function] = Mockery::mock( 'wp_api' ); - } - $mock = $this->mocked_functions[$function]; + $method = preg_replace('/\\\\+/', '_', $function); + $expectation = $this->set_up_mock($mock, $method, $arguments); + Handler::register_handler($function, array( $mock, $method )); + } catch (\Exception $e) { + throw $e; + } + return $expectation; + } - $method = preg_replace( '/\\\\+/', '_', $function ); - $expectation = $this->set_up_mock( $mock, $method, $arguments ); - Handler::register_handler( $function, array( $mock, $method ) ); - } catch ( \Exception $e ) { - throw $e; - } - return $expectation; - } + /** + * Sets up an argument placeholder that allows it to be any of an enumerated + * list of possibilities + * + * @return \Mockery\Matcher\anyOf + */ + public static function anyOf() + { + return call_user_func_array(array( '\\Mockery', 'anyOf' ), func_get_args()); + } - /** - * Sets up an argument placeholder that allows it to be any of an enumerated - * list of possibilities - * - * @return \Mockery\Matcher\anyOf - */ - public static function anyOf() { - return call_user_func_array( array( '\\Mockery', 'anyOf' ), func_get_args() ); - } + /** + * Sets up an argument placeholder that requires the argument to be of a + * certain type + * + * This may be any type for which there is a "is_*" function, or any class or + * interface. + * + * @param string $expected + * + * @return Mockery\Matcher\Type + */ + public static function type($expected) + { + return Mockery::type($expected); + } - /** - * Sets up an argument placeholder that requires the argument to be of a - * certain type - * - * This may be any type for which there is a "is_*" function, or any class or - * interface. - * - * @param string $expected - * - * @return Mockery\Matcher\Type - */ - public static function type( $expected ) { - return Mockery::type( $expected ); - } + /** + * Set up the mock object with an expectation for this test. + * + * @param \Mockery\Mock $mock + * @param string $function + * @param array $arguments + * + * @return Mockery\Expectation + */ + protected function set_up_mock($mock, $function, $arguments) + { + $expectation = $mock->shouldReceive($function); - /** - * Set up the mock object with an expectation for this test. - * - * @param \Mockery\Mock $mock - * @param string $function - * @param array $arguments - * - * @return Mockery\Expectation - */ - protected function set_up_mock( $mock, $function, $arguments ) { - $expectation = $mock->shouldReceive( $function ); + if (isset($arguments['times'])) { + $times = $arguments['times']; + if (is_int($times) || preg_match('/^\d+$/', $times)) { + $expectation->times((int) $times); + } elseif (preg_match('/^(\d+)([\-+])$/', $times, $matches)) { + $method = '+' === $matches[2] ? 'atLeast' : 'atMost'; + $expectation->$method()->times((int) $matches[1]); + } elseif (preg_match('/^(\d+)-(\d+)$/', $times, $matches)) { + $num1 = (int) $matches[1]; + $num2 = (int) $matches[2]; + if ($num1 === $num2) { + $expectation->times($num1); + } else { + $expectation->between(min($num1, $num2), max($num1, $num2)); + } + } + } + if (isset($arguments['args'])) { + $arguments['args'] = array_map(function ($argument) { + if ($argument instanceof \Closure) { + return Mockery::on($argument); + } + if ($argument === '*') { + return Mockery::any(); + } + return $argument; + }, (array) $arguments['args']); + call_user_func_array(array( $expectation, 'with' ), $arguments['args']); + } + if (isset($arguments['return_arg'])) { + $argument_position = true === $arguments['return_arg'] ? 0 : (int) $arguments['return_arg']; + $arguments['return'] = function () use ($argument_position) { + if ($argument_position >= func_num_args()) { + return null; + } + return func_get_arg($argument_position); + }; + } elseif (isset($arguments['return_in_order'])) { + $arguments['return'] = new ReturnSequence(); + $arguments['return']->setReturnValues((array) $arguments['return_in_order']); + } + if (isset($arguments['return'])) { + $return = $arguments['return']; + if ($return instanceof ReturnSequence) { + $expectation->andReturnValues($return->getReturnValues()); + } elseif ($return instanceof \Closure) { + $expectation->andReturnUsing($return); + } else { + $expectation->andReturn($return); + } + } + return $expectation; + } - if ( isset( $arguments['times'] ) ) { - $times = $arguments['times']; - if ( is_int( $times ) || preg_match( '/^\d+$/', $times ) ) { - $expectation->times( (int) $times ); - } elseif ( preg_match( '/^(\d+)([\-+])$/', $times, $matches ) ) { - $method = '+' === $matches[2] ? 'atLeast' : 'atMost'; - $expectation->$method()->times( (int) $matches[1] ); - } elseif ( preg_match( '/^(\d+)-(\d+)$/', $times, $matches ) ) { - $num1 = (int) $matches[1]; - $num2 = (int) $matches[2]; - if ( $num1 === $num2 ) { - $expectation->times( $num1 ); - } else { - $expectation->between( min( $num1, $num2 ), max( $num1, $num2 ) ); - } - } - } - if ( isset( $arguments['args'] ) ) { - $arguments['args'] = array_map( function ( $argument ) { - if ( $argument instanceof \Closure ) { - return Mockery::on( $argument ); - } - if ( $argument === '*' ) { - return Mockery::any(); - } - return $argument; - }, (array) $arguments['args'] ); - call_user_func_array( array( $expectation, 'with' ), $arguments['args'] ); - } - if ( isset( $arguments['return_arg'] ) ) { - $argument_position = true === $arguments['return_arg'] ? 0 : (int) $arguments['return_arg']; - $arguments['return'] = function () use ( $argument_position ) { - if ( $argument_position >= func_num_args() ) { - return null; - } - return func_get_arg( $argument_position ); - }; - } elseif ( isset( $arguments['return_in_order'] ) ) { - $arguments['return'] = new ReturnSequence(); - $arguments['return']->setReturnValues( (array) $arguments['return_in_order'] ); - } - if ( isset( $arguments['return'] ) ) { - $return = $arguments['return']; - if ( $return instanceof ReturnSequence ) { - $expectation->andReturnValues( $return->getReturnValues() ); - } elseif ( $return instanceof \Closure ) { - $expectation->andReturnUsing( $return ); - } else { - $expectation->andReturn( $return ); - } - } - return $expectation; - } + /** + * Dynamically declares a function if it doesn't already exist + * + * This function is namespace-aware. + * + * @param $function_name + */ + private function generate_function($function_name) + { + $function_name = $this->sanitize_function_name($function_name); - /** - * Dynamically declares a function if it doesn't already exist - * - * This function is namespace-aware. - * - * @param $function_name - */ - private function generate_function( $function_name ) { - $function_name = $this->sanitize_function_name( $function_name ); + $this->validate_function_name($function_name); - $this->validate_function_name( $function_name ); + $this->create_function($function_name) or $this->replace_function($function_name); + } - $this->create_function( $function_name ) OR $this->replace_function( $function_name ); - } + /** + * Create a function with WP_Mock + * + * @param string $function_name + * + * @return bool True if this function created the mock, false otherwise + */ + private function create_function($function_name) + { + if (in_array($function_name, self::$wp_mocked_functions)) { + return true; + } + if (function_exists($function_name)) { + return false; + } - /** - * Create a function with WP_Mock - * - * @param string $function_name - * - * @return bool True if this function created the mock, false otherwise - */ - private function create_function( $function_name ) { - if ( in_array( $function_name, self::$wp_mocked_functions ) ) { - return true; - } - if ( function_exists( $function_name ) ) { - return false; - } + $parts = explode('\\', $function_name); + $name = array_pop($parts); + $namespace = empty($parts) ? '' : 'namespace ' . implode('\\', $parts) . ';' . PHP_EOL; - $parts = explode( '\\', $function_name ); - $name = array_pop( $parts ); - $namespace = empty( $parts ) ? '' : 'namespace ' . implode( '\\', $parts ) . ';' . PHP_EOL; - - $declaration = <<patchwork_functions ) ) { - return true; - } - if ( ! function_exists( 'Patchwork\\replace' ) ) { - return true; - } - $this->patchwork_functions[] = $function_name; - \Patchwork\redefine( $function_name, function () use ( $function_name ) { - return Handler::handle_function( $function_name, func_get_args() ); - } ); - return true; - } + return true; + } - /** - * Clean the function name to be of a standard shape - * - * @param string $function_name - * - * @return string - */ - private function sanitize_function_name( $function_name ) { - $function_name = trim( $function_name, '\\' ); - return $function_name; - } + /** + * Replace a function with patchwork + * + * @param string $function_name + * + * @return bool + */ + private function replace_function($function_name) + { + if (in_array($function_name, $this->patchwork_functions)) { + return true; + } + if (! function_exists('Patchwork\\replace')) { + return true; + } + $this->patchwork_functions[] = $function_name; + \Patchwork\redefine($function_name, function () use ($function_name) { + return Handler::handle_function($function_name, func_get_args()); + }); + return true; + } - /** - * Validate the function name for format and other considerations - * - * Validation will fail if the string doesn't match the regex, if it's an - * internal function, or if it is a reserved word in PHP. - * - * @param string $function_name - * - * @throws \InvalidArgumentException - */ - private function validate_function_name( $function_name ) { - if ( function_exists( $function_name ) ) { - if ( empty( $this->internal_functions ) ) { - $defined_functions = get_defined_functions(); - $this->internal_functions = $defined_functions['internal']; - } - if ( in_array( $function_name, $this->internal_functions ) ) { - throw new \InvalidArgumentException( 'Cannot override internal PHP functions!' ); - } - } + /** + * Clean the function name to be of a standard shape + * + * @param string $function_name + * + * @return string + */ + private function sanitize_function_name($function_name) + { + $function_name = trim($function_name, '\\'); + return $function_name; + } - $parts = explode( '\\', $function_name ); - $name = array_pop( $parts ); + /** + * Validate the function name for format and other considerations + * + * Validation will fail if the string doesn't match the regex, if it's an + * internal function, or if it is a reserved word in PHP. + * + * @param string $function_name + * + * @throws \InvalidArgumentException + */ + private function validate_function_name($function_name) + { + if (function_exists($function_name)) { + if (empty($this->internal_functions)) { + $defined_functions = get_defined_functions(); + $this->internal_functions = $defined_functions['internal']; + } + if (in_array($function_name, $this->internal_functions)) { + throw new \InvalidArgumentException('Cannot override internal PHP functions!'); + } + } - if ( ! preg_match( '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $function_name ) ) { - throw new \InvalidArgumentException( 'Function name not properly formatted!' ); - } + $parts = explode('\\', $function_name); + $name = array_pop($parts); - $reserved_words = ' __halt_compiler abstract and array as break callable case catch class clone const continue declare default die do echo else elseif empty enddeclare endfor endforeach endif endswitch endwhile eval exit extends final for foreach function global goto if implements include include_once instanceof insteadof interface isset list namespace new or print private protected public require require_once return static switch throw trait try unset use var while xor __CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ '; - if ( false !== strpos( $reserved_words, " $name " ) ) { - throw new \InvalidArgumentException( 'Function name can not be a reserved word!' ); - } - } + if (! preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $function_name)) { + throw new \InvalidArgumentException('Function name not properly formatted!'); + } + $reserved_words = ' __halt_compiler abstract and array as break callable case catch class clone const continue declare default die do echo else elseif empty enddeclare endfor endforeach endif endswitch endwhile eval exit extends final for foreach function global goto if implements include include_once instanceof insteadof interface isset list namespace new or print private protected public require require_once return static switch throw trait try unset use var while xor __CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ '; + if (false !== strpos($reserved_words, " $name ")) { + throw new \InvalidArgumentException('Function name can not be a reserved word!'); + } + } } - diff --git a/php/WP_Mock/Handler.php b/php/WP_Mock/Handler.php index 9b701668..ba7b556f 100644 --- a/php/WP_Mock/Handler.php +++ b/php/WP_Mock/Handler.php @@ -9,102 +9,107 @@ namespace WP_Mock; +class Handler +{ + /** + * Mocked method handlers registered by the test class. + * + * @var array + */ + private static $handlers = array(); -class Handler { - /** - * Mocked method handlers registered by the test class. - * - * @var array - */ - private static $handlers = array(); + /** + * Overrides any existing handlers to set a new callback. + * + * @param string $function_name + * @param string $callback + */ + public static function register_handler($function_name, $callback) + { + self::$handlers[ $function_name ] = $callback; + } - /** - * Overrides any existing handlers to set a new callback. - * - * @param string $function_name - * @param string $callback - */ - public static function register_handler( $function_name, $callback ) { - self::$handlers[ $function_name ] = $callback; - } + /** + * Handle a mocked function call. + * + * @param string $function_name + * @param array $args + * + * @return mixed + */ + public static function handle_function($function_name, $args = array()) + { + if (self::handler_exists($function_name)) { + $callback = self::$handlers[ $function_name ]; - /** - * Handle a mocked function call. - * - * @param string $function_name - * @param array $args - * - * @return mixed - */ - public static function handle_function( $function_name, $args = array() ) { - if ( self::handler_exists( $function_name ) ) { - $callback = self::$handlers[ $function_name ]; + return call_user_func_array($callback, $args); + } elseif (\WP_Mock::strictMode()) { + throw new \PHPUnit\Framework\ExpectationFailedException( + sprintf('No handler found for %s', $function_name) + ); + } + } - return call_user_func_array( $callback, $args ); - } elseif ( \WP_Mock::strictMode() ) { - throw new \PHPUnit\Framework\ExpectationFailedException( - sprintf( 'No handler found for %s', $function_name ) - ); - } - } + /** + * Check if a handler exists + * + * @param string $function_name + * + * @return bool + */ + public static function handler_exists($function_name) + { + return isset(self::$handlers[ $function_name ]); + } - /** - * Check if a handler exists - * - * @param string $function_name - * - * @return bool - */ - public static function handler_exists( $function_name ) { - return isset( self::$handlers[ $function_name ] ); - } + /** + * Clear all registered handlers. + */ + public static function cleanup() + { + self::$handlers = array(); + } - /** - * Clear all registered handlers. - */ - public static function cleanup() { - self::$handlers = array(); - } + /** + * Helper function for common passthru return functions + * + * @param string $function_name + * @param array $args + * + * @return mixed + */ + public static function predefined_return_function_helper($function_name, array $args) + { + $result = self::handle_function($function_name, $args); + if (! self::handler_exists($function_name)) { + $result = isset($args[0]) ? $args[0] : $result; + } - /** - * Helper function for common passthru return functions - * - * @param string $function_name - * @param array $args - * - * @return mixed - */ - public static function predefined_return_function_helper( $function_name, array $args ) { - $result = self::handle_function( $function_name, $args ); - if ( ! self::handler_exists( $function_name ) ) { - $result = isset( $args[0] ) ? $args[0] : $result; - } + return $result; + } - return $result; - } - - /** - * Helper function for common echo functions - * - * @param string $function_name - * @param array $args - * - * @throws \Exception - */ - public static function predefined_echo_function_helper( $function_name, array $args ) { - ob_start(); - try { - self::handle_function( $function_name, $args ); - } catch ( \Exception $exception ) { - ob_end_clean(); - throw $exception; - } - $result = ob_get_clean(); - if ( ! self::handler_exists( $function_name ) ) { - $result = isset( $args[0] ) ? $args[0] : $result; - } - - echo $result; - } + /** + * Helper function for common echo functions + * + * @param string $function_name + * @param array $args + * + * @throws \Exception + */ + public static function predefined_echo_function_helper($function_name, array $args) + { + ob_start(); + try { + self::handle_function($function_name, $args); + } catch (\Exception $exception) { + ob_end_clean(); + throw $exception; + } + $result = ob_get_clean(); + if (! self::handler_exists($function_name)) { + $result = isset($args[0]) ? $args[0] : $result; + } + echo $result; + } } diff --git a/php/WP_Mock/Hook.php b/php/WP_Mock/Hook.php index 646779d2..e875aefe 100644 --- a/php/WP_Mock/Hook.php +++ b/php/WP_Mock/Hook.php @@ -8,85 +8,88 @@ namespace WP_Mock; - use WP_Mock\Matcher\AnyInstance; -abstract class Hook { - /** @var string Hook name */ - protected $name; - - /** @var array Collection of processors */ - protected $processors = array(); - - public function __construct( $name ) { - $this->name = $name; - } - - protected function safe_offset( $value ) { - if ( is_null( $value ) ) { - return 'null'; - } elseif ( is_scalar( $value ) ) { - return $value; - }elseif( $value instanceof AnyInstance ) { - return (string) $value; - } elseif ( is_object( $value ) ) { - return spl_object_hash( $value ); - } elseif ( is_array( $value ) ) { - $return = ''; - foreach ( $value as $k => $v ) { - $k = is_numeric( $k ) ? '' : $k; - $return .= $k . $this->safe_offset( $v ); - } - - return $return; - } - - return ''; - } - - /** @return Action_Responder|Filter_Responder */ - public function with() { - $args = func_get_args(); - $responder = $this->new_responder(); - - if ( $args === array( null ) ) { - $this->processors['argsnull'] = $responder; - } else { - $num_args = count( $args ); - - $processors = &$this->processors; - for ( $i = 0; $i < $num_args - 1; $i ++ ) { - $arg = $this->safe_offset( $args[ $i ] ); - - if ( ! isset( $processors[ $arg ] ) ) { - $processors[ $arg ] = array(); - } - - $processors = &$processors[ $arg ]; - } - - $processors[ $this->safe_offset( $args[ $num_args - 1 ] ) ] = $responder; - } - - return $responder; - } - - protected abstract function new_responder(); - - /** - * Throw an exception if strict mode is on - * - * @throws \PHPUnit\Framework\ExpectationFailedException - */ - protected function strict_check() { - if ( \WP_Mock::strictMode() ) { - throw new \PHPUnit\Framework\ExpectationFailedException( $this->get_strict_mode_message() ); - } - } - - /** - * @return string - */ - abstract protected function get_strict_mode_message(); - +abstract class Hook +{ + /** @var string Hook name */ + protected $name; + + /** @var array Collection of processors */ + protected $processors = array(); + + public function __construct($name) + { + $this->name = $name; + } + + protected function safe_offset($value) + { + if (is_null($value)) { + return 'null'; + } elseif (is_scalar($value)) { + return $value; + } elseif ($value instanceof AnyInstance) { + return (string) $value; + } elseif (is_object($value)) { + return spl_object_hash($value); + } elseif (is_array($value)) { + $return = ''; + foreach ($value as $k => $v) { + $k = is_numeric($k) ? '' : $k; + $return .= $k . $this->safe_offset($v); + } + + return $return; + } + + return ''; + } + + /** @return Action_Responder|Filter_Responder */ + public function with() + { + $args = func_get_args(); + $responder = $this->new_responder(); + + if ($args === array( null )) { + $this->processors['argsnull'] = $responder; + } else { + $num_args = count($args); + + $processors = &$this->processors; + for ($i = 0; $i < $num_args - 1; $i ++) { + $arg = $this->safe_offset($args[ $i ]); + + if (! isset($processors[ $arg ])) { + $processors[ $arg ] = array(); + } + + $processors = &$processors[ $arg ]; + } + + $processors[ $this->safe_offset($args[ $num_args - 1 ]) ] = $responder; + } + + return $responder; + } + + abstract protected function new_responder(); + + /** + * Throw an exception if strict mode is on + * + * @throws \PHPUnit\Framework\ExpectationFailedException + */ + protected function strict_check() + { + if (\WP_Mock::strictMode()) { + throw new \PHPUnit\Framework\ExpectationFailedException($this->get_strict_mode_message()); + } + } + + /** + * @return string + */ + abstract protected function get_strict_mode_message(); } diff --git a/php/WP_Mock/HookedCallback.php b/php/WP_Mock/HookedCallback.php index 55015386..bae8d230 100644 --- a/php/WP_Mock/HookedCallback.php +++ b/php/WP_Mock/HookedCallback.php @@ -3,115 +3,122 @@ namespace WP_Mock; use WP_Mock\Matcher\AnyInstance; -class HookedCallback extends Hook { - - protected $type = 'filter'; - protected $callback; - - /** - * @param string $type - */ - public function setType( $type ) { - $this->type = $type; - } - - public function react( $callback, $priority, $argument_count ) { - \WP_Mock::addHook( $this->name ); - - $safe_callback = $this->safe_offset( $callback ); - - if( is_array( $callback ) ) { - $any_instance_callback = array( new AnyInstance( $callback[0] ), $callback[1] ); - $safe_any_instance_callback = $this->safe_offset( $any_instance_callback ); - if( ! empty( $this->processors[ $safe_any_instance_callback ])) { - $safe_callback = $safe_any_instance_callback; - } - } - - if ( - empty( $this->processors[ $safe_callback ] ) || - empty( $this->processors[ $safe_callback ][ $priority ] ) || - empty( $this->processors[ $safe_callback ][ $priority ][ $argument_count ] ) - ) { - $this->callback = $callback; - $this->strict_check(); - - return null; - } - - return $this->processors[ $safe_callback ][ $priority ][ $argument_count ]->react(); - } - - protected function new_responder() { - return new HookedCallbackResponder(); - } - - protected function safe_offset( $value ) { - if ( $value instanceof \Closure ) { - $value = '__CLOSURE__'; - } - - return parent::safe_offset( $value ); - } - - /** - * Converts a callable to a string - * - * Closures get returned as 'Closure', objects (those with an __invoke() method get turned into ::__invoke, - * and arrays get turned into :: - * - * @param callable $callback - * - * @return string - */ - protected function callback_to_string( $callback ) { - if ( ! is_string( $callback ) ) { - if ( $callback instanceof \Closure ) { - $callback = 'Closure'; - } elseif ( is_object( $callback ) ) { - $callback = get_class( $callback ) . '::__invoke'; - } else { - $class = $callback[0]; - $method = $callback[1]; - if ( ! is_string( $class ) ) { - $class = get_class( $class ); - } - $callback = "{$class}::$method"; - } - } - - return $callback; - } - - /** - * @param $callback - * - * @return string - */ - protected function get_strict_mode_message() { - return sprintf( - 'Unexpected use of add_%s for action %s with callback %s', - $this->type, - $this->name, - $this->callback_to_string( $this->callback ) - ); - } +class HookedCallback extends Hook +{ + protected $type = 'filter'; + protected $callback; + + /** + * @param string $type + */ + public function setType($type) + { + $this->type = $type; + } + + public function react($callback, $priority, $argument_count) + { + \WP_Mock::addHook($this->name); + + $safe_callback = $this->safe_offset($callback); + + if (is_array($callback)) { + $any_instance_callback = array( new AnyInstance($callback[0]), $callback[1] ); + $safe_any_instance_callback = $this->safe_offset($any_instance_callback); + if (! empty($this->processors[ $safe_any_instance_callback ])) { + $safe_callback = $safe_any_instance_callback; + } + } + + if ( + empty($this->processors[ $safe_callback ]) || + empty($this->processors[ $safe_callback ][ $priority ]) || + empty($this->processors[ $safe_callback ][ $priority ][ $argument_count ]) + ) { + $this->callback = $callback; + $this->strict_check(); + + return null; + } + + return $this->processors[ $safe_callback ][ $priority ][ $argument_count ]->react(); + } + + protected function new_responder() + { + return new HookedCallbackResponder(); + } + + protected function safe_offset($value) + { + if ($value instanceof \Closure) { + $value = '__CLOSURE__'; + } + + return parent::safe_offset($value); + } + + /** + * Converts a callable to a string + * + * Closures get returned as 'Closure', objects (those with an __invoke() method get turned into ::__invoke, + * and arrays get turned into :: + * + * @param callable $callback + * + * @return string + */ + protected function callback_to_string($callback) + { + if (! is_string($callback)) { + if ($callback instanceof \Closure) { + $callback = 'Closure'; + } elseif (is_object($callback)) { + $callback = get_class($callback) . '::__invoke'; + } else { + $class = $callback[0]; + $method = $callback[1]; + if (! is_string($class)) { + $class = get_class($class); + } + $callback = "{$class}::$method"; + } + } + + return $callback; + } + + /** + * @param $callback + * + * @return string + */ + protected function get_strict_mode_message() + { + return sprintf( + 'Unexpected use of add_%s for action %s with callback %s', + $this->type, + $this->name, + $this->callback_to_string($this->callback) + ); + } } -class HookedCallbackResponder { - - /** - * @var callable - */ - protected $callable; - - public function perform( $callable ) { - $this->callable = $callable; - } - - public function react() { - call_user_func( $this->callable ); - } - +class HookedCallbackResponder +{ + /** + * @var callable + */ + protected $callable; + + public function perform($callable) + { + $this->callable = $callable; + } + + public function react() + { + call_user_func($this->callable); + } } diff --git a/php/WP_Mock/InvokedFilterValue.php b/php/WP_Mock/InvokedFilterValue.php index bf7a56a5..7517a6cb 100644 --- a/php/WP_Mock/InvokedFilterValue.php +++ b/php/WP_Mock/InvokedFilterValue.php @@ -2,24 +2,25 @@ namespace WP_Mock; -class InvokedFilterValue { +class InvokedFilterValue +{ + /** + * @var callable + */ + protected $callback; - /** - * @var callable - */ - protected $callback; - - /** - * InvokedFilterValue constructor. - * - * @param callable $callable - */ - public function __construct( $callable ) { - $this->callback = $callable; - } - - public function __invoke() { - return call_user_func_array( $this->callback, func_get_args() ); - } + /** + * InvokedFilterValue constructor. + * + * @param callable $callable + */ + public function __construct($callable) + { + $this->callback = $callable; + } + public function __invoke() + { + return call_user_func_array($this->callback, func_get_args()); + } } diff --git a/php/WP_Mock/Loader.php b/php/WP_Mock/Loader.php index 91277cbc..bcd1d995 100644 --- a/php/WP_Mock/Loader.php +++ b/php/WP_Mock/Loader.php @@ -19,131 +19,142 @@ namespace WP_Mock; +class Loader +{ + private $_fileExtension = '.php'; + private $_namespace; + private $_includePath; + private $_namespaceSeparator = '\\'; -class Loader { - private $_fileExtension = '.php'; - private $_namespace; - private $_includePath; - private $_namespaceSeparator = '\\'; + /** + * Creates a new Loader that loads classes of the + * specified namespace. + * + * @param string $ns The namespace to use. + */ + public function __construct($ns = 'WP_Mock', $includePath = null) + { + $this->_namespace = $ns; + $this->_includePath = $includePath; + } - /** - * Creates a new Loader that loads classes of the - * specified namespace. - * - * @param string $ns The namespace to use. - */ - public function __construct( $ns = 'WP_Mock', $includePath = null ) { - $this->_namespace = $ns; - $this->_includePath = $includePath; - } + /** + * Sets the namespace separator used by classes in the namespace of this class loader. + * + * @param string $sep The separator to use. + */ + public function setNamespaceSeparator($sep) + { + $this->_namespaceSeparator = $sep; + } - /** - * Sets the namespace separator used by classes in the namespace of this class loader. - * - * @param string $sep The separator to use. - */ - public function setNamespaceSeparator( $sep ) { - $this->_namespaceSeparator = $sep; - } + /** + * Gets the namespace seperator used by classes in the namespace of this class loader. + * + * @return void + */ + public function getNamespaceSeparator() + { + return $this->_namespaceSeparator; + } - /** - * Gets the namespace seperator used by classes in the namespace of this class loader. - * - * @return void - */ - public function getNamespaceSeparator() { - return $this->_namespaceSeparator; - } + /** + * Sets the base include path for all class files in the namespace of this class loader. + * + * @param string $includePath + */ + public function setIncludePath($includePath) + { + $this->_includePath = $includePath; + } - /** - * Sets the base include path for all class files in the namespace of this class loader. - * - * @param string $includePath - */ - public function setIncludePath( $includePath ) { - $this->_includePath = $includePath; - } + /** + * Gets the base include path for all class files in the namespace of this class loader. + * + * @return string $includePath + */ + public function getIncludePath() + { + return $this->_includePath; + } - /** - * Gets the base include path for all class files in the namespace of this class loader. - * - * @return string $includePath - */ - public function getIncludePath() { - return $this->_includePath; - } + /** + * Sets the file extension of class files in the namespace of this class loader. + * + * @param string $fileExtension + */ + public function setFileExtension($fileExtension) + { + $this->_fileExtension = $fileExtension; + } - /** - * Sets the file extension of class files in the namespace of this class loader. - * - * @param string $fileExtension - */ - public function setFileExtension( $fileExtension ) { - $this->_fileExtension = $fileExtension; - } + /** + * Gets the file extension of class files in the namespace of this class loader. + * + * @return string $fileExtension + */ + public function getFileExtension() + { + return $this->_fileExtension; + } - /** - * Gets the file extension of class files in the namespace of this class loader. - * - * @return string $fileExtension - */ - public function getFileExtension() { - return $this->_fileExtension; - } + /** + * Installs this class loader on the SPL autoload stack. + * + * @param bool $prepend If true, prepend autoloader on the autoload stack + */ + public function register($prepend = false) + { + //spl_autoload_register( array( $this, 'loadClass' ), true, $prepend ); + } - /** - * Installs this class loader on the SPL autoload stack. - * - * @param bool $prepend If true, prepend autoloader on the autoload stack - */ - public function register( $prepend = false ) { - //spl_autoload_register( array( $this, 'loadClass' ), true, $prepend ); - } + /** + * Uninstalls this class loader from the SPL autoloader stack. + */ + public function unregister() + { + //spl_autoload_unregister( array( $this, 'loadClass' ) ); + } - /** - * Uninstalls this class loader from the SPL autoloader stack. - */ - public function unregister() { - //spl_autoload_unregister( array( $this, 'loadClass' ) ); - } + /** + * Loads the given class or interface. + * + * @param string $className The name of the class to load. + * + * @return void + */ + public function loadClass($className) + { + return; + if ($className === 'WP_Mock') { + require $this->getFullPath('WP_Mock.php'); - /** - * Loads the given class or interface. - * - * @param string $className The name of the class to load. - * - * @return void - */ - public function loadClass( $className ) { - return; - if ( $className === 'WP_Mock' ) { - require $this->getFullPath( 'WP_Mock.php' ); + return; + } + if (null === $this->_namespace + || $this->_namespace . $this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace . $this->_namespaceSeparator)) + ) { + $fileName = ''; + $namespace = ''; + if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) { + $namespace = substr($className, 0, $lastNsPos); + $className = substr($className, $lastNsPos + 1); + $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; + } + $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension; + require $this->getFullPath($fileName); + } + } - return; - } - if ( null === $this->_namespace - || $this->_namespace . $this->_namespaceSeparator === substr( $className, 0, strlen( $this->_namespace . $this->_namespaceSeparator ) ) - ) { - $fileName = ''; - $namespace = ''; - if ( false !== ( $lastNsPos = strripos( $className, $this->_namespaceSeparator ) ) ) { - $namespace = substr( $className, 0, $lastNsPos ); - $className = substr( $className, $lastNsPos + 1 ); - $fileName = str_replace( $this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace ) . DIRECTORY_SEPARATOR; - } - $fileName .= str_replace( '_', DIRECTORY_SEPARATOR, $className ) . $this->_fileExtension; - require $this->getFullPath( $fileName ); - } - } - - /** - * Returns full path for $fileName if _includePath is set, or leaves as-is for PHP's internal search in 'require'. - * - * @param string $fileName relative to include path. - * - * @return string - */ - private function getFullPath( $fileName ) { - return ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName; - } + /** + * Returns full path for $fileName if _includePath is set, or leaves as-is for PHP's internal search in 'require'. + * + * @param string $fileName relative to include path. + * + * @return string + */ + private function getFullPath($fileName) + { + return ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName; + } } diff --git a/php/WP_Mock/Matcher/AnyInstance.php b/php/WP_Mock/Matcher/AnyInstance.php index cd538148..fd2153f3 100644 --- a/php/WP_Mock/Matcher/AnyInstance.php +++ b/php/WP_Mock/Matcher/AnyInstance.php @@ -1,4 +1,5 @@ newInstanceWithoutConstructor(); - } elseif ( is_object( $expected ) ) { + } elseif (is_object($expected)) { $expectedInstance = $expected; - } else { - throw new Exception( 'AnyInstance matcher can only match objects!' ); - } + } else { + throw new Exception('AnyInstance matcher can only match objects!'); + } - parent::__construct($expectedInstance); - } + parent::__construct($expectedInstance); + } - /** - * Check if the actual value matches the expected. - * Actual passed by reference to preserve reference trail (where applicable) - * back to the original method parameter. - * - * @param mixed $actual - * - * @return bool - */ - public function match( &$actual ) { - if ( ! is_object( $actual ) ) { - return false; - } + /** + * Check if the actual value matches the expected. + * Actual passed by reference to preserve reference trail (where applicable) + * back to the original method parameter. + * + * @param mixed $actual + * + * @return bool + */ + public function match(&$actual) + { + if (! is_object($actual)) { + return false; + } - if( $actual instanceof \Closure ) { - return false; + if ($actual instanceof \Closure) { + return false; } - if( get_class( $actual ) === get_class( $this->_expected ) ) { + if (get_class($actual) === get_class($this->_expected)) { return true; } // parent::haveCommonAncestor() expects two objects. - $reflectedExpected = new \ReflectionClass( $this->_expected ); + $reflectedExpected = new \ReflectionClass($this->_expected); $expectedInstance = $reflectedExpected->newInstanceWithoutConstructor(); - if ( ! $this->haveCommonAncestor( $actual, $expectedInstance ) ) { - return false; - } - - return true; - } + if (! $this->haveCommonAncestor($actual, $expectedInstance)) { + return false; + } - /** - * Return a string representation of this Matcher - * - * @return string - */ - public function __toString() { - $classname = get_class($this->_expected); - return ""; - } + return true; + } + /** + * Return a string representation of this Matcher + * + * @return string + */ + public function __toString() + { + $classname = get_class($this->_expected); + return ""; + } } diff --git a/php/WP_Mock/Matcher/FuzzyObject.php b/php/WP_Mock/Matcher/FuzzyObject.php index c173a327..69b129e3 100644 --- a/php/WP_Mock/Matcher/FuzzyObject.php +++ b/php/WP_Mock/Matcher/FuzzyObject.php @@ -5,97 +5,101 @@ use Mockery\Exception; use Mockery\Matcher\MatcherAbstract; -class FuzzyObject extends MatcherAbstract { - - /** - * @param object|array $expected - * - * @throws \Mockery\Exception If a non-object non-array expectation is provided - */ - public function __construct( $expected = null ) { - if ( ! is_object( $expected ) ) { - if ( is_array( $expected ) ) { - $expected = (object) $expected; - } else { - throw new Exception( 'FuzzyObject matcher can only match objects!' ); - } - } - parent::__construct( $expected ); - } +class FuzzyObject extends MatcherAbstract +{ + /** + * @param object|array $expected + * + * @throws \Mockery\Exception If a non-object non-array expectation is provided + */ + public function __construct($expected = null) + { + if (! is_object($expected)) { + if (is_array($expected)) { + $expected = (object) $expected; + } else { + throw new Exception('FuzzyObject matcher can only match objects!'); + } + } + parent::__construct($expected); + } - /** - * Check if the actual value matches the expected. - * Actual passed by reference to preserve reference trail (where applicable) - * back to the original method parameter. - * - * @param mixed $actual - * - * @return bool - */ - public function match( &$actual ) { - if ( ! is_object( $actual ) ) { - return false; - } + /** + * Check if the actual value matches the expected. + * Actual passed by reference to preserve reference trail (where applicable) + * back to the original method parameter. + * + * @param mixed $actual + * + * @return bool + */ + public function match(&$actual) + { + if (! is_object($actual)) { + return false; + } - if ( ! $this->haveCommonAncestor( $actual, $this->_expected ) ) { - return false; - } + if (! $this->haveCommonAncestor($actual, $this->_expected)) { + return false; + } - $expected_properties = get_object_vars( $this->_expected ); + $expected_properties = get_object_vars($this->_expected); - foreach ( $expected_properties as $prop => $value ) { - if ( ! isset( $actual->$prop ) || $value !== $actual->$prop ) { - return false; - } - } + foreach ($expected_properties as $prop => $value) { + if (! isset($actual->$prop) || $value !== $actual->$prop) { + return false; + } + } - $actual_keys = array_keys( get_object_vars( $actual ) ); - $extra_actual = array_diff( $actual_keys, array_keys( $expected_properties ) ); - if ( ! empty( $extra_actual ) ) { - return false; - } + $actual_keys = array_keys(get_object_vars($actual)); + $extra_actual = array_diff($actual_keys, array_keys($expected_properties)); + if (! empty($extra_actual)) { + return false; + } - return true; - } + return true; + } - /** - * Return a string representation of this Matcher - * - * @return string - */ - public function __toString() { - $values = array_values( get_object_vars( $this->_expected ) ); - $values = array_map( function ( $value ) { - if ( ! is_scalar( $value ) ) { - if ( is_array( $value ) ) { - $value = 'Array'; - } elseif ( is_object( $value ) ) { - $value = get_class( $value ); - } elseif ( is_resource( $value ) ) { - $value = get_resource_type( $value ); - } else { - $value = 'unknown'; - } - } - return $value; - }, $values ); - return ''; - } + /** + * Return a string representation of this Matcher + * + * @return string + */ + public function __toString() + { + $values = array_values(get_object_vars($this->_expected)); + $values = array_map(function ($value) { + if (! is_scalar($value)) { + if (is_array($value)) { + $value = 'Array'; + } elseif (is_object($value)) { + $value = get_class($value); + } elseif (is_resource($value)) { + $value = get_resource_type($value); + } else { + $value = 'unknown'; + } + } + return $value; + }, $values); + return ''; + } - /** - * @param object $object1 - * @param object $object2 - * - * @return bool - */ - protected function haveCommonAncestor( $object1, $object2 ) { - $class1 = get_class( $object1 ); - $class2 = get_class( $object2 ); - if ( $class1 === $class2 ) { - return true; - } - $inheritance1 = class_parents( $class1 ); - $inheritance2 = class_parents( $class2 ); - return in_array( $class1, $inheritance2 ) || in_array( $class2, $inheritance1 ); + /** + * @param object $object1 + * @param object $object2 + * + * @return bool + */ + protected function haveCommonAncestor($object1, $object2) + { + $class1 = get_class($object1); + $class2 = get_class($object2); + if ($class1 === $class2) { + return true; + } + $inheritance1 = class_parents($class1); + $inheritance2 = class_parents($class2); + return in_array($class1, $inheritance2) || in_array($class2, $inheritance1); } } diff --git a/php/WP_Mock/ReturnSequence.php b/php/WP_Mock/ReturnSequence.php index a7c55a32..44d667f7 100644 --- a/php/WP_Mock/ReturnSequence.php +++ b/php/WP_Mock/ReturnSequence.php @@ -2,38 +2,40 @@ namespace WP_Mock; -class ReturnSequence { +class ReturnSequence +{ + private $return_values = array(); - private $return_values = array(); + /** + * Constructor to set up the return sequence object + * + * You can pass arbitrary arguments to the constructor to set to the internal + * $return_values array + */ + public function __construct() + { + $this->return_values = func_get_args(); + } - /** - * Constructor to set up the return sequence object - * - * You can pass arbitrary arguments to the constructor to set to the internal - * $return_values array - */ - public function __construct() { - $this->return_values = func_get_args(); - } + /** + * Retrieve the $return_values array + * + * @return array + */ + public function getReturnValues() + { + return $this->return_values; + } - /** - * Retrieve the $return_values array - * - * @return array - */ - public function getReturnValues() { - return $this->return_values; - } - - /** - * Set the return_values array - * - * Values should be passed in as one array. Keys will be discarded. - * - * @param array $return_values - */ - public function setReturnValues( $return_values ) { - $this->return_values = array_values( (array) $return_values ); - } - -} \ No newline at end of file + /** + * Set the return_values array + * + * Values should be passed in as one array. Keys will be discarded. + * + * @param array $return_values + */ + public function setReturnValues($return_values) + { + $this->return_values = array_values((array) $return_values); + } +} diff --git a/php/WP_Mock/Tools/Constraints/ExpectationsMet.php b/php/WP_Mock/Tools/Constraints/ExpectationsMet.php index 6feba966..049db06e 100644 --- a/php/WP_Mock/Tools/Constraints/ExpectationsMet.php +++ b/php/WP_Mock/Tools/Constraints/ExpectationsMet.php @@ -6,35 +6,38 @@ use Mockery; use Exception; -class ExpectationsMet extends \PHPUnit\Framework\Constraint\Constraint { - - private $_mockery_message; - - public function matches( $other ): bool { - try { - Mockery::getContainer()->mockery_verify(); - } catch ( Exception $e ) { - $this->_mockery_message = $e->getMessage(); - return false; - } - return true; - } - - /** - * Returns a string representation of the object. - * - * @return string - */ - public function toString(): string { - return 'WP Mock expectations are met'; - } - - protected function additionalFailureDescription( $other ): string { - return str_replace( array( "\r", "\n" ), '', (string) $this->_mockery_message ); - } - - protected function failureDescription( $other ): string { - return $this->toString(); - } - +class ExpectationsMet extends \PHPUnit\Framework\Constraint\Constraint +{ + private $_mockery_message; + + public function matches($other): bool + { + try { + Mockery::getContainer()->mockery_verify(); + } catch (Exception $e) { + $this->_mockery_message = $e->getMessage(); + return false; + } + return true; + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString(): string + { + return 'WP Mock expectations are met'; + } + + protected function additionalFailureDescription($other): string + { + return str_replace(array( "\r", "\n" ), '', (string) $this->_mockery_message); + } + + protected function failureDescription($other): string + { + return $this->toString(); + } } diff --git a/php/WP_Mock/Tools/Constraints/IsEqualHtml.php b/php/WP_Mock/Tools/Constraints/IsEqualHtml.php index 38bed5a0..0d56210d 100644 --- a/php/WP_Mock/Tools/Constraints/IsEqualHtml.php +++ b/php/WP_Mock/Tools/Constraints/IsEqualHtml.php @@ -4,54 +4,57 @@ use PHPUnit\Framework\Constraint\IsEqual; -class IsEqualHtml { - protected $IsEqual; - protected $value; - - /** - * @var float - */ - private $delta; - - /** - * @var int - */ - private $maxDepth; - - /** - * @var bool - */ - private $canonicalize; - - /** - * @var bool - */ - private $ignoreCase; - - public function __construct( - $value, - float $delta = 0.0, - int $maxDepth = 10, - bool $canonicalize = false, - bool $ignoreCase = false - ) { - $this->value = $value; - $this->delta = $delta; - $this->maxDepth = $maxDepth; - $this->canonicalize = $canonicalize; - $this->ignoreCase = $ignoreCase; - } - - private function clean( $thing ) { - $thing = preg_replace( '/\n\s+/', '', $thing ); - $thing = preg_replace( '/\s\s+/', ' ', $thing ); - return str_replace( array( "\r", "\n", "\t" ), '', $thing ); - } - - public function evaluate( $other, $description = '', $returnResult = FALSE ) { - $other = $this->clean( $other ); - $this->value = $this->clean( $this->value ); - $isEqual = new IsEqual( $this->value, $this->delta, $this->maxDepth, $this->canonicalize, $this->ignoreCase ); - return $isEqual->evaluate( $other, $description, $returnResult ); - } +class IsEqualHtml +{ + protected $IsEqual; + protected $value; + + /** + * @var float + */ + private $delta; + + /** + * @var int + */ + private $maxDepth; + + /** + * @var bool + */ + private $canonicalize; + + /** + * @var bool + */ + private $ignoreCase; + + public function __construct( + $value, + float $delta = 0.0, + int $maxDepth = 10, + bool $canonicalize = false, + bool $ignoreCase = false + ) { + $this->value = $value; + $this->delta = $delta; + $this->maxDepth = $maxDepth; + $this->canonicalize = $canonicalize; + $this->ignoreCase = $ignoreCase; + } + + private function clean($thing) + { + $thing = preg_replace('/\n\s+/', '', $thing); + $thing = preg_replace('/\s\s+/', ' ', $thing); + return str_replace(array( "\r", "\n", "\t" ), '', $thing); + } + + public function evaluate($other, $description = '', $returnResult = false) + { + $other = $this->clean($other); + $this->value = $this->clean($this->value); + $isEqual = new IsEqual($this->value, $this->delta, $this->maxDepth, $this->canonicalize, $this->ignoreCase); + return $isEqual->evaluate($other, $description, $returnResult); + } } diff --git a/php/WP_Mock/Tools/TestCase.php b/php/WP_Mock/Tools/TestCase.php index 82ffff1e..ea9e4ec1 100644 --- a/php/WP_Mock/Tools/TestCase.php +++ b/php/WP_Mock/Tools/TestCase.php @@ -12,312 +12,327 @@ use WP_Mock\Tools\Constraints\ExpectationsMet; use WP_Mock\Tools\Constraints\IsEqualHtml; -abstract class TestCase extends \PHPUnit\Framework\TestCase { - - protected $mockedStaticMethods = array(); - - /** - * @var array - */ - protected $__default_post = array(); - - /** - * @var array - */ - protected $__default_get = array(); - - /** - * @var array - */ - protected $__default_request = array(); - - /** - * @var bool|callable - */ - protected $__contentFilterCallback = false; - - /** - * @var array - */ - protected $testFiles = array(); - - public function setUp() : void { - $this->requireFileDependencies(); - - WP_Mock::setUp(); - - $_GET = (array) $this->__default_get; - $_POST = (array) $this->__default_post; - $_REQUEST = (array) $this->__default_request; - - $this->setUpContentFiltering(); - - $this->cleanGlobals(); - } - - public function tearDown() : void { - WP_Mock::tearDown(); - - $this->cleanGlobals(); - - $this->mockedStaticMethods = array(); - - $_GET = array(); - $_POST = array(); - $_REQUEST = array(); - } - - public function assertActionsCalled() { - $actions_not_added = $expected_actions = 0; - try { - WP_Mock::assertActionsCalled(); - } catch ( Exception $e ) { - $actions_not_added = 1; - $expected_actions = $e->getMessage(); - } - $this->assertEmpty( $actions_not_added, $expected_actions ); - } - - public function assertHooksAdded() { - $hooks_not_added = $expected_hooks = 0; - try { - WP_Mock::assertHooksAdded(); - } catch ( Exception $e ) { - $hooks_not_added = 1; - $expected_hooks = $e->getMessage(); - } - $this->assertEmpty( $hooks_not_added, $expected_hooks ); - } - - public function ns( $function ) { - if ( ! is_string( $function ) || false !== strpos( $function, '\\' ) ) { - return $function; - } - - $thisClassName = trim( get_class( $this ), '\\' ); - - if ( ! strpos( $thisClassName, '\\' ) ) { - return $function; - } - - // $thisNamespace is constructed by exploding the current class name on - // namespace separators, running array_slice on that array starting at 0 - // and ending one element from the end (chops the class name off) and - // imploding that using namespace separators as the glue. - $thisNamespace = implode( '\\', array_slice( explode( '\\', $thisClassName ), 0, - 1 ) ); - - return "$thisNamespace\\$function"; - } - - public function stripTabsAndNewlines( $content ) { - return str_replace( array( "\t", "\r", "\n" ), '', $content ); - } - - public function expectOutputString( string $expectedString ): void { - if ( is_callable( $this->__contentFilterCallback ) ) { - $expectedString = call_user_func( $this->__contentFilterCallback, $expectedString ); - } - parent::expectOutputString( $expectedString ); - } - - public function assertCurrentConditionsMet( $message = '' ) { - $this->assertThat( null, new ExpectationsMet, $message ); - } - - public function assertConditionsMet( $message = '' ) { - $this->assertCurrentConditionsMet( $message ); - } - - public function assertEqualsHTML( $expected, $actual, $message = '' ) { - $constraint = new IsEqualHtml( $expected ); - $this->assertThat( $actual, $constraint, $message ); - } - - /** - * Nuke the globals from orbit for process isolation - * - * See http://kpayne.me/2012/07/02/phpunit-process-isolation-and-constant-already-defined/ - * for more details - * - * {@inheritdoc} - */ - protected function prepareTemplate( Text_Template $template ) { - $template->setVar( array( - 'globals' => '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = \'' . $GLOBALS['__PHPUNIT_BOOTSTRAP'] . '\';', - ) ); - parent::prepareTemplate( $template ); - } - - - /** - * Mock a static method of a class - * - * @param string $class The classname or class::method name - * @param null|string $method The method name. Optional if class::method used for $class - * - * @return \Mockery\Expectation - * @throws Exception - */ - protected function mockStaticMethod( $class, $method = null ) { - if ( ! $method ) { - list( $class, $method ) = ( explode( '::', $class ) + array( null, null ) ); - } - if ( ! $method ) { - throw new Exception( sprintf( 'Could not mock %s::%s', $class, $method ) ); - } - if ( ! WP_Mock::usingPatchwork() || ! function_exists( 'Patchwork\redefine' ) ) { - throw new Exception( 'Patchwork is not loaded! Please load patchwork before mocking static methods!' ); - } - - $safe_method = "wp_mock_safe_$method"; - $signature = md5( "$class::$method" ); - if ( ! empty( $this->mockedStaticMethods[ $signature ] ) ) { - $mock = $this->mockedStaticMethods[ $signature ]; - } else { - - $rMethod = false; - if ( class_exists( $class ) ) { - $rMethod = new ReflectionMethod( $class, $method ); - } - if ( - $rMethod && - ( - ! $rMethod->isUserDefined() || - ! $rMethod->isStatic() || - $rMethod->isPrivate() - ) - ) { - throw new Exception( sprintf( '%s::%s is not a user-defined non-private static method!', $class, $method ) ); - } - - /** @var \Mockery\Mock $mock */ - $mock = Mockery::mock( $class ); - $mock->shouldAllowMockingProtectedMethods(); - $this->mockedStaticMethods[ $signature ] = $mock; - - \Patchwork\redefine( "$class::$method", function () use ( $mock, $safe_method ) { - return call_user_func_array( array( $mock, $safe_method ), func_get_args() ); - } ); - } - $expectation = $mock->shouldReceive( $safe_method ); - - return $expectation; - } - - /** - * @param array|object $data The post data to add to the post - * - * @return \WP_Post - */ - protected function mockPost( $data ) { - /** @var \WP_Post $post */ - $post = \Mockery::mock( 'WP_Post' ); - $data = array_merge( array( - 'ID' => 0, - 'post_author' => 0, - 'post_type' => '', - 'post_title' => '', - 'post_date' => '', - 'post_date_gmt' => '', - 'post_content' => '', - 'post_excerpt' => '', - 'post_status' => '', - 'comment_status' => '', - 'ping_status' => '', - 'post_password' => '', - 'post_parent' => 0, - 'post_modified' => '', - 'post_modified_gmt' => '', - 'comment_count' => 0, - 'menu_order' => 0, - ), (array) $data ); - array_walk( $data, function ( $value, $prop ) use ( $post ) { - $post->$prop = $value; - } ); - - return $post; - } - - /** - * @param array $query_vars - * - * @return \WP - */ - protected function mockWp( array $query_vars = array() ) { - /** @var \WP $wp */ - $wp = \Mockery::mock( 'WP' ); - $wp->query_vars = $query_vars; - - return $wp; - } - - protected function cleanGlobals() { - $common_globals = array( - 'post', - 'wp_query', - ); - foreach ( $common_globals as $var ) { - if ( isset( $GLOBALS[ $var ] ) ) { - unset( $GLOBALS[ $var ] ); - } - } - - } - - /** - * Require any testFiles that are defined in a subclass - * - * This will only work if the WP_MOCK_INCLUDE_DIR is defined to point to the root directory you want to include - * files from. - */ - protected function requireFileDependencies() { - if ( ! empty( $this->testFiles ) && defined( 'WP_MOCK_INCLUDE_DIR' ) ) { - foreach ( $this->testFiles as $file ) { - if ( file_exists( WP_MOCK_INCLUDE_DIR . $file ) ) { - require_once( WP_MOCK_INCLUDE_DIR . $file ); - } - } - } - } - - protected function setUpContentFiltering() { - $this->__contentFilterCallback = false; - - $annotations = TestUtil::parseTestMethodAnnotations( - static::class, - $this->getName( false ) - ); - if ( - ! isset( $annotations['stripTabsAndNewlinesFromOutput'] ) || - $annotations['stripTabsAndNewlinesFromOutput'][0] !== 'disabled' || - ( - is_numeric( $annotations['stripTabsAndNewlinesFromOutput'][0] ) && - (int) $annotations['stripTabsAndNewlinesFromOutput'][0] !== 0 - ) - ) { - $this->__contentFilterCallback = array( $this, 'stripTabsAndNewlines' ); - $this->setOutputCallback( $this->__contentFilterCallback ); - } - } - - public function run( TestResult $result = null ): TestResult { - if ( $result === null ) { - $result = $this->createResult(); - } - - WP_Mock::getDeprecatedListener()->setTestResult( $result ); - WP_Mock::getDeprecatedListener()->setTestCase($this); - - return parent::run( $result ); - } - - /** - * @after - */ - public function checkDeprecatedCalls() { - WP_Mock::getDeprecatedListener()->checkCalls(); - WP_Mock::getDeprecatedListener()->reset(); - } - +abstract class TestCase extends \PHPUnit\Framework\TestCase +{ + protected $mockedStaticMethods = array(); + + /** + * @var array + */ + protected $__default_post = array(); + + /** + * @var array + */ + protected $__default_get = array(); + + /** + * @var array + */ + protected $__default_request = array(); + + /** + * @var bool|callable + */ + protected $__contentFilterCallback = false; + + /** + * @var array + */ + protected $testFiles = array(); + + public function setUp(): void + { + $this->requireFileDependencies(); + + WP_Mock::setUp(); + + $_GET = (array) $this->__default_get; + $_POST = (array) $this->__default_post; + $_REQUEST = (array) $this->__default_request; + + $this->setUpContentFiltering(); + + $this->cleanGlobals(); + } + + public function tearDown(): void + { + WP_Mock::tearDown(); + + $this->cleanGlobals(); + + $this->mockedStaticMethods = array(); + + $_GET = array(); + $_POST = array(); + $_REQUEST = array(); + } + + public function assertActionsCalled() + { + $actions_not_added = $expected_actions = 0; + try { + WP_Mock::assertActionsCalled(); + } catch (Exception $e) { + $actions_not_added = 1; + $expected_actions = $e->getMessage(); + } + $this->assertEmpty($actions_not_added, $expected_actions); + } + + public function assertHooksAdded() + { + $hooks_not_added = $expected_hooks = 0; + try { + WP_Mock::assertHooksAdded(); + } catch (Exception $e) { + $hooks_not_added = 1; + $expected_hooks = $e->getMessage(); + } + $this->assertEmpty($hooks_not_added, $expected_hooks); + } + + public function ns($function) + { + if (! is_string($function) || false !== strpos($function, '\\')) { + return $function; + } + + $thisClassName = trim(get_class($this), '\\'); + + if (! strpos($thisClassName, '\\')) { + return $function; + } + + // $thisNamespace is constructed by exploding the current class name on + // namespace separators, running array_slice on that array starting at 0 + // and ending one element from the end (chops the class name off) and + // imploding that using namespace separators as the glue. + $thisNamespace = implode('\\', array_slice(explode('\\', $thisClassName), 0, - 1)); + + return "$thisNamespace\\$function"; + } + + public function stripTabsAndNewlines($content) + { + return str_replace(array( "\t", "\r", "\n" ), '', $content); + } + + public function expectOutputString(string $expectedString): void + { + if (is_callable($this->__contentFilterCallback)) { + $expectedString = call_user_func($this->__contentFilterCallback, $expectedString); + } + parent::expectOutputString($expectedString); + } + + public function assertCurrentConditionsMet($message = '') + { + $this->assertThat(null, new ExpectationsMet(), $message); + } + + public function assertConditionsMet($message = '') + { + $this->assertCurrentConditionsMet($message); + } + + public function assertEqualsHTML($expected, $actual, $message = '') + { + $constraint = new IsEqualHtml($expected); + $this->assertThat($actual, $constraint, $message); + } + + /** + * Nuke the globals from orbit for process isolation + * + * See http://kpayne.me/2012/07/02/phpunit-process-isolation-and-constant-already-defined/ + * for more details + * + * {@inheritdoc} + */ + protected function prepareTemplate(Text_Template $template) + { + $template->setVar(array( + 'globals' => '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = \'' . $GLOBALS['__PHPUNIT_BOOTSTRAP'] . '\';', + )); + parent::prepareTemplate($template); + } + + + /** + * Mock a static method of a class + * + * @param string $class The classname or class::method name + * @param null|string $method The method name. Optional if class::method used for $class + * + * @return \Mockery\Expectation + * @throws Exception + */ + protected function mockStaticMethod($class, $method = null) + { + if (! $method) { + list($class, $method) = (explode('::', $class) + array( null, null )); + } + if (! $method) { + throw new Exception(sprintf('Could not mock %s::%s', $class, $method)); + } + if (! WP_Mock::usingPatchwork() || ! function_exists('Patchwork\redefine')) { + throw new Exception('Patchwork is not loaded! Please load patchwork before mocking static methods!'); + } + + $safe_method = "wp_mock_safe_$method"; + $signature = md5("$class::$method"); + if (! empty($this->mockedStaticMethods[ $signature ])) { + $mock = $this->mockedStaticMethods[ $signature ]; + } else { + $rMethod = false; + if (class_exists($class)) { + $rMethod = new ReflectionMethod($class, $method); + } + if ( + $rMethod && + ( + ! $rMethod->isUserDefined() || + ! $rMethod->isStatic() || + $rMethod->isPrivate() + ) + ) { + throw new Exception(sprintf('%s::%s is not a user-defined non-private static method!', $class, $method)); + } + + /** @var \Mockery\Mock $mock */ + $mock = Mockery::mock($class); + $mock->shouldAllowMockingProtectedMethods(); + $this->mockedStaticMethods[ $signature ] = $mock; + + \Patchwork\redefine("$class::$method", function () use ($mock, $safe_method) { + return call_user_func_array(array( $mock, $safe_method ), func_get_args()); + }); + } + $expectation = $mock->shouldReceive($safe_method); + + return $expectation; + } + + /** + * @param array|object $data The post data to add to the post + * + * @return \WP_Post + */ + protected function mockPost($data) + { + /** @var \WP_Post $post */ + $post = \Mockery::mock('WP_Post'); + $data = array_merge(array( + 'ID' => 0, + 'post_author' => 0, + 'post_type' => '', + 'post_title' => '', + 'post_date' => '', + 'post_date_gmt' => '', + 'post_content' => '', + 'post_excerpt' => '', + 'post_status' => '', + 'comment_status' => '', + 'ping_status' => '', + 'post_password' => '', + 'post_parent' => 0, + 'post_modified' => '', + 'post_modified_gmt' => '', + 'comment_count' => 0, + 'menu_order' => 0, + ), (array) $data); + array_walk($data, function ($value, $prop) use ($post) { + $post->$prop = $value; + }); + + return $post; + } + + /** + * @param array $query_vars + * + * @return \WP + */ + protected function mockWp(array $query_vars = array()) + { + /** @var \WP $wp */ + $wp = \Mockery::mock('WP'); + $wp->query_vars = $query_vars; + + return $wp; + } + + protected function cleanGlobals() + { + $common_globals = array( + 'post', + 'wp_query', + ); + foreach ($common_globals as $var) { + if (isset($GLOBALS[ $var ])) { + unset($GLOBALS[ $var ]); + } + } + } + + /** + * Require any testFiles that are defined in a subclass + * + * This will only work if the WP_MOCK_INCLUDE_DIR is defined to point to the root directory you want to include + * files from. + */ + protected function requireFileDependencies() + { + if (! empty($this->testFiles) && defined('WP_MOCK_INCLUDE_DIR')) { + foreach ($this->testFiles as $file) { + if (file_exists(WP_MOCK_INCLUDE_DIR . $file)) { + require_once(WP_MOCK_INCLUDE_DIR . $file); + } + } + } + } + + protected function setUpContentFiltering() + { + $this->__contentFilterCallback = false; + + $annotations = TestUtil::parseTestMethodAnnotations( + static::class, + $this->getName(false) + ); + if ( + ! isset($annotations['stripTabsAndNewlinesFromOutput']) || + $annotations['stripTabsAndNewlinesFromOutput'][0] !== 'disabled' || + ( + is_numeric($annotations['stripTabsAndNewlinesFromOutput'][0]) && + (int) $annotations['stripTabsAndNewlinesFromOutput'][0] !== 0 + ) + ) { + $this->__contentFilterCallback = array( $this, 'stripTabsAndNewlines' ); + $this->setOutputCallback($this->__contentFilterCallback); + } + } + + public function run(TestResult $result = null): TestResult + { + if ($result === null) { + $result = $this->createResult(); + } + + WP_Mock::getDeprecatedListener()->setTestResult($result); + WP_Mock::getDeprecatedListener()->setTestCase($this); + + return parent::run($result); + } + + /** + * @after + */ + public function checkDeprecatedCalls() + { + WP_Mock::getDeprecatedListener()->checkCalls(); + WP_Mock::getDeprecatedListener()->reset(); + } } - diff --git a/phpcs.xml b/phpcs.xml index d9a3dba4..96c393c8 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,7 +1,8 @@ ./php + ./tests - + \ No newline at end of file diff --git a/tests/DeprecatedMethodsTest.php b/tests/DeprecatedMethodsTest.php index efaf1f3f..795f8eff 100644 --- a/tests/DeprecatedMethodsTest.php +++ b/tests/DeprecatedMethodsTest.php @@ -3,52 +3,55 @@ /** * @covers \WP_Mock\DeprecatedListener */ -class DeprecatedMethodsTest extends \PHPUnit\Framework\TestCase { +class DeprecatedMethodsTest extends \PHPUnit\Framework\TestCase +{ + public function setUp(): void + { + WP_Mock::setUp(); + WP_Mock::getDeprecatedListener()->reset(); + } - public function setUp() : void { - WP_Mock::setUp(); - WP_Mock::getDeprecatedListener()->reset(); - } + protected function tearDown(): void + { + WP_Mock::getDeprecatedListener()->reset(); + WP_Mock::tearDown(); + } - protected function tearDown() : void { - WP_Mock::getDeprecatedListener()->reset(); - WP_Mock::tearDown(); - } - - /** - * @covers \WP_Mock\DeprecatedListener::checkCalls() - */ - public function testWpFunctionLogsDeprecationNotice() { - $listener = WP_Mock::getDeprecatedListener(); - $testResult = new \PHPUnit\Framework\TestResult(); - $result = Mockery::mock( $testResult ); - $case = Mockery::mock( '\PHPUnit\Framework\TestCase' ); - $listener->setTestCase( $case ); - $listener->setTestResult( $result ); - $result->shouldReceive( 'addFailure' ) - ->once() - ->with( $case, Mockery::type( '\PHPUnit\Framework\RiskyTestError' ), 0 ); - WP_Mock::wpFunction( 'foobar' ); - $this->assertNull($listener->checkCalls()); - } - - /** - * @covers \WP_Mock\DeprecatedListener::checkCalls() - * - * @return void - */ - public function testWpPassthruFunctionLogsDeprecationNotice() { - $listener = WP_Mock::getDeprecatedListener(); - $testResult = new \PHPUnit\Framework\TestResult(); - $result = Mockery::mock( $testResult ); - $case = Mockery::mock( '\PHPUnit\Framework\TestCase' ); - $listener->setTestCase( $case ); - $listener->setTestResult( $result ); - $result->shouldReceive( 'addFailure' ) - ->once() - ->with( $case, Mockery::type( '\PHPUnit\Framework\RiskyTestError' ), 0 ); - WP_Mock::wpPassthruFunction( 'foobar' ); - $this->assertNull( $listener->checkCalls() ); - } + /** + * @covers \WP_Mock\DeprecatedListener::checkCalls() + */ + public function testWpFunctionLogsDeprecationNotice() + { + $listener = WP_Mock::getDeprecatedListener(); + $testResult = new \PHPUnit\Framework\TestResult(); + $result = Mockery::mock($testResult); + $case = Mockery::mock('\PHPUnit\Framework\TestCase'); + $listener->setTestCase($case); + $listener->setTestResult($result); + $result->shouldReceive('addFailure') + ->once() + ->with($case, Mockery::type('\PHPUnit\Framework\RiskyTestError'), 0); + WP_Mock::wpFunction('foobar'); + $this->assertNull($listener->checkCalls()); + } + /** + * @covers \WP_Mock\DeprecatedListener::checkCalls() + * + * @return void + */ + public function testWpPassthruFunctionLogsDeprecationNotice() + { + $listener = WP_Mock::getDeprecatedListener(); + $testResult = new \PHPUnit\Framework\TestResult(); + $result = Mockery::mock($testResult); + $case = Mockery::mock('\PHPUnit\Framework\TestCase'); + $listener->setTestCase($case); + $listener->setTestResult($result); + $result->shouldReceive('addFailure') + ->once() + ->with($case, Mockery::type('\PHPUnit\Framework\RiskyTestError'), 0); + WP_Mock::wpPassthruFunction('foobar'); + $this->assertNull($listener->checkCalls()); + } } diff --git a/tests/FunctionMocksTest.php b/tests/FunctionMocksTest.php index b809752c..9578465f 100644 --- a/tests/FunctionMocksTest.php +++ b/tests/FunctionMocksTest.php @@ -1,106 +1,112 @@ isInIsolation()) { + WP_Mock::setUp(); + } + } - protected function setUp() : void { - if ( ! $this->isInIsolation() ) { - WP_Mock::setUp(); - } - } + /** + * @covers \WP_Mock::bootstrap() + * + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testCommonFunctionsAreDefined() + { + // First we assert that all common functions get removed from the returned array. If any one of these functions + // doesn't get removed, that means it already exists. + $this->assertEmpty(array_filter($this->common_functions, 'function_exists')); + WP_Mock::bootstrap(); + // Now we assert that the array doesn't lose any items after bootstrap, meaning all expected functions got + // defined correctly. + $this->assertEquals($this->common_functions, array_filter($this->common_functions, 'function_exists')); + } - /** - * @covers \WP_Mock::bootstrap() - * - * @runInSeparateProcess - * @preserveGlobalState disabled - */ - public function testCommonFunctionsAreDefined() { - // First we assert that all common functions get removed from the returned array. If any one of these functions - // doesn't get removed, that means it already exists. - $this->assertEmpty( array_filter( $this->common_functions, 'function_exists' ) ); - WP_Mock::bootstrap(); - // Now we assert that the array doesn't lose any items after bootstrap, meaning all expected functions got - // defined correctly. - $this->assertEquals( $this->common_functions, array_filter( $this->common_functions, 'function_exists' ) ); - } + /** + * @covers \WP_Mock::userFunction() + * @dataProvider dataCommonFunctionsDefaultFunctionality + */ + public function testCommonFunctionsDefaultFunctionality($function, $action) + { + $input = $expected = 'Something Random ' . rand(0, 99); + if ('echo' === $action) { + $this->expectOutputString($input); + $expected = null; + } - /** - * @covers \WP_Mock::userFunction() - * @dataProvider dataCommonFunctionsDefaultFunctionality - */ - public function testCommonFunctionsDefaultFunctionality( $function, $action ) { - $input = $expected = 'Something Random ' . rand( 0, 99 ); - if ( 'echo' === $action ) { - $this->expectOutputString( $input ); - $expected = null; - } + if ('_n' === $function) { + $this->assertEquals($expected, call_user_func($function, $input, 'foo', 1, 'bar')); + } else { + $this->assertEquals($expected, call_user_func($function, $input)); + } + } - if ('_n' === $function) { - $this->assertEquals($expected, call_user_func($function, $input, 'foo', 1, 'bar')); - } else { - $this->assertEquals($expected, call_user_func($function, $input)); - } - } + /** + * @covers \WP_Mock::activateStrictMode() + * @covers \WP_Mock::bootstrap() + * + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testDefaultFailsInStrictMode() + { + $this->expectExceptionMessageMatches('/No handler found for \w+/'); + $this->expectException('\PHPUnit\Framework\ExpectationFailedException'); + WP_Mock::activateStrictMode(); + WP_Mock::bootstrap(); + _e('Test'); + } - /** - * @covers \WP_Mock::activateStrictMode() - * @covers \WP_Mock::bootstrap() - * - * @runInSeparateProcess - * @preserveGlobalState disabled - */ - public function testDefaultFailsInStrictMode() { - $this->expectExceptionMessageMatches('/No handler found for \w+/'); - $this->expectException('\PHPUnit\Framework\ExpectationFailedException'); - WP_Mock::activateStrictMode(); - WP_Mock::bootstrap(); - _e('Test'); - } + public function dataCommonFunctionsDefaultFunctionality() + { + return array_map(function ($function) { + return array( $function, '_e' === substr($function, - 2) ? 'echo' : 'return' ); + }, $this->common_functions); + } - public function dataCommonFunctionsDefaultFunctionality() { - return array_map( function ( $function ) { - return array( $function, '_e' === substr( $function, - 2 ) ? 'echo' : 'return' ); - }, $this->common_functions ); - } - - /** - * @covers \WP_Mock::userFunction() - * - * @return void - */ - public function testMockingOverridesDefaults() { - $this->assertEquals( 'Input', __( 'Input' ) ); - WP_Mock::userFunction( '__' )->andReturn( 'Output' ); - $this->assertEquals( 'Output', __( 'Input' ) ); - } - - /** - * @covers \WP_Mock::userFunction() - * - * @return void - */ - public function testBotchedMocksStillOverrideDefault() { - WP_Mock::userFunction( 'esc_html' ); - $this->assertEmpty( esc_html( 'Input' ) ); - } + /** + * @covers \WP_Mock::userFunction() + * + * @return void + */ + public function testMockingOverridesDefaults() + { + $this->assertEquals('Input', __('Input')); + WP_Mock::userFunction('__')->andReturn('Output'); + $this->assertEquals('Output', __('Input')); + } + /** + * @covers \WP_Mock::userFunction() + * + * @return void + */ + public function testBotchedMocksStillOverrideDefault() + { + WP_Mock::userFunction('esc_html'); + $this->assertEmpty(esc_html('Input')); + } } diff --git a/tests/WP_Mock/DeprecatedListenerTest.php b/tests/WP_Mock/DeprecatedListenerTest.php index bef47638..c1b9e72d 100644 --- a/tests/WP_Mock/DeprecatedListenerTest.php +++ b/tests/WP_Mock/DeprecatedListenerTest.php @@ -11,150 +11,158 @@ /** * @covers \WP_Mock\DeprecatedListener */ -class DeprecatedListenerTest extends \PHPUnit\Framework\TestCase { - - /** @var DeprecatedListener */ - protected $object; - - protected function setUp() : void { - $this->object = new DeprecatedListener(); - } - - public function tearDown() : void { - $this->object->reset(); - } - - /** - * @covers \WP_Mock\DeprecatedListener::logDeprecatedCall() - * - * @return void - */ - public function testLogDeprecatedCall() { - $method = 'Foobar::asdf' . rand( 0, 9 ); - $args = array( rand( 10, 99 ) ); - $this->object->logDeprecatedCall( $method, $args ); - - $this->assertEquals( array( array( $method, $args ) ), $this->getCalls( $this->object ) ); - } - - /** - * @covers \WP_Mock\DeprecatedListener::reset() - * - * @return void - */ - public function testReset() { - $this->object->logDeprecatedCall( 'Asdf', array( 'foobar' ) ); - $this->object->reset(); - - $this->assertEquals( array(), $this->getCalls( $this->object ) ); - } - - /** - * @covers \WP_Mock\DeprecatedListener::checkCalls() - * - * @return void - */ - public function testCheckCallsNoCalls() { - $testResult = new \PHPUnit\Framework\TestResult(); - $result = Mockery::mock( $testResult ); - $result->shouldReceive( 'addFailure' )->never(); - /** @var \\PHPUnit\Framework\TestResult $result */ - $this->object->setTestResult( $result ); - - /** @noinspection PhpVoidFunctionResultUsedInspection */ - $this->assertNull($this->object->checkCalls()); - } - - /** - * @covers \WP_Mock\DeprecatedListener::checkCalls() - * - * @return void - */ - public function testCheckCalls_scalar_only() { - $this->object->logDeprecatedCall( 'FooBar::bazBat', array( 'string', true, 42 ) ); - $this->object->setTestName( 'TestName' ); - $testCase = Mockery::mock( '\PHPUnit\Framework\TestCase' ); - /** @var \PHPUnit\Framework\TestCase $testCase */ - $this->object->setTestCase( $testCase ); - $testResult = new \PHPUnit\Framework\TestResult(); - $result = Mockery::mock( $testResult ); - $result->shouldReceive( 'addFailure' ) - ->once() - ->andReturnUsing( function ( $case, $exception, $int ) use ( $testCase ) { - $int = (int) $int; // It's coming as 0.0 - \PHPUnit\Framework\Assert::assertSame( $testCase, $case ); - \PHPUnit\Framework\Assert::assertTrue( $exception instanceof RiskyTestError ); - $message = <<object = new DeprecatedListener(); + } + + public function tearDown(): void + { + $this->object->reset(); + } + + /** + * @covers \WP_Mock\DeprecatedListener::logDeprecatedCall() + * + * @return void + */ + public function testLogDeprecatedCall() + { + $method = 'Foobar::asdf' . rand(0, 9); + $args = array( rand(10, 99) ); + $this->object->logDeprecatedCall($method, $args); + + $this->assertEquals(array( array( $method, $args ) ), $this->getCalls($this->object)); + } + + /** + * @covers \WP_Mock\DeprecatedListener::reset() + * + * @return void + */ + public function testReset() + { + $this->object->logDeprecatedCall('Asdf', array( 'foobar' )); + $this->object->reset(); + + $this->assertEquals(array(), $this->getCalls($this->object)); + } + + /** + * @covers \WP_Mock\DeprecatedListener::checkCalls() + * + * @return void + */ + public function testCheckCallsNoCalls() + { + $testResult = new \PHPUnit\Framework\TestResult(); + $result = Mockery::mock($testResult); + $result->shouldReceive('addFailure')->never(); + /** @var \\PHPUnit\Framework\TestResult $result */ + $this->object->setTestResult($result); + + /** @noinspection PhpVoidFunctionResultUsedInspection */ + $this->assertNull($this->object->checkCalls()); + } + + /** + * @covers \WP_Mock\DeprecatedListener::checkCalls() + * + * @return void + */ + public function testCheckCalls_scalar_only() + { + $this->object->logDeprecatedCall('FooBar::bazBat', array( 'string', true, 42 )); + $this->object->setTestName('TestName'); + $testCase = Mockery::mock('\PHPUnit\Framework\TestCase'); + /** @var \PHPUnit\Framework\TestCase $testCase */ + $this->object->setTestCase($testCase); + $testResult = new \PHPUnit\Framework\TestResult(); + $result = Mockery::mock($testResult); + $result->shouldReceive('addFailure') + ->once() + ->andReturnUsing(function ($case, $exception, $int) use ($testCase) { + $int = (int) $int; // It's coming as 0.0 + \PHPUnit\Framework\Assert::assertSame($testCase, $case); + \PHPUnit\Framework\Assert::assertTrue($exception instanceof RiskyTestError); + $message = <<getMessage() ); - \PHPUnit\Framework\Assert::assertTrue( 0 === $int ); - } ); - /** @var \\PHPUnit\Framework\TestResult $result */ - $this->object->setTestResult( $result ); - - $this->object->checkCalls(); - } - - /** - * @covers \WP_Mock\DeprecatedListener::checkCalls() - * - * @return void - * @throws Exception - */ - public function testCheckCalls_non_scalars() { - $callback1 = function () { - }; - $object1 = Mockery::mock( 'WP_Query' ); - $range = rand( 5, 10 ); - $resource = fopen( 'php://temp', 'r' ); - $this->object->logDeprecatedCall( 'BazBat::fooBar', array( $callback1 ) ); - $this->object->logDeprecatedCall( 'BazBat::fooBar', array( $object1 ) ); - $this->object->logDeprecatedCall( 'LongerClassName::callback', array( array( $object1, 'shouldReceive' ) ) ); - $this->object->logDeprecatedCall( 'BazBat::fooBar', array( range( 1, $range ), $resource ) ); - $this->object->setTestName( 'OtherTest' ); - $testCase = Mockery::mock( '\PHPUnit\Framework\TestCase' ); - /** @var \PHPUnit\Framework\TestCase $testCase */ - $this->object->setTestCase( $testCase ); - $testResult = new \PHPUnit\Framework\TestResult(); - $result = Mockery::mock( $testResult );; - $testClosure = function ( $case, $exception, $int ) use ( $testCase, $callback1, $object1, $range ) { - $int = (int) $int; // It's coming as 0.0 - $callback1 = get_class( $callback1 ) . ':' . spl_object_hash( $callback1 ); - $object1 = get_class( $object1 ) . ':' . spl_object_hash( $object1 ); - \PHPUnit\Framework\Assert::assertSame( $testCase, $case ); - \PHPUnit\Framework\Assert::assertTrue( $exception instanceof RiskyTestError ); - $message = <<getMessage()); + \PHPUnit\Framework\Assert::assertTrue(0 === $int); + }); + /** @var \\PHPUnit\Framework\TestResult $result */ + $this->object->setTestResult($result); + + $this->object->checkCalls(); + } + + /** + * @covers \WP_Mock\DeprecatedListener::checkCalls() + * + * @return void + * @throws Exception + */ + public function testCheckCalls_non_scalars() + { + $callback1 = function () { + }; + $object1 = Mockery::mock('WP_Query'); + $range = rand(5, 10); + $resource = fopen('php://temp', 'r'); + $this->object->logDeprecatedCall('BazBat::fooBar', array( $callback1 )); + $this->object->logDeprecatedCall('BazBat::fooBar', array( $object1 )); + $this->object->logDeprecatedCall('LongerClassName::callback', array( array( $object1, 'shouldReceive' ) )); + $this->object->logDeprecatedCall('BazBat::fooBar', array( range(1, $range), $resource )); + $this->object->setTestName('OtherTest'); + $testCase = Mockery::mock('\PHPUnit\Framework\TestCase'); + /** @var \PHPUnit\Framework\TestCase $testCase */ + $this->object->setTestCase($testCase); + $testResult = new \PHPUnit\Framework\TestResult(); + $result = Mockery::mock($testResult); + ; + $testClosure = function ($case, $exception, $int) use ($testCase, $callback1, $object1, $range) { + $int = (int) $int; // It's coming as 0.0 + $callback1 = get_class($callback1) . ':' . spl_object_hash($callback1); + $object1 = get_class($object1) . ':' . spl_object_hash($object1); + \PHPUnit\Framework\Assert::assertSame($testCase, $case); + \PHPUnit\Framework\Assert::assertTrue($exception instanceof RiskyTestError); + $message = <<"] ["<$object1>"] ["Array([$range] ...)","Resource"] LongerClassName::callback ["[<$object1>,shouldReceive]"] EOT; - \PHPUnit\Framework\Assert::assertEquals( $message, $exception->getMessage() ); - \PHPUnit\Framework\Assert::assertTrue( 0 === $int ); - }; - $result->shouldReceive( 'addFailure' ) - ->once() - ->andReturnUsing( $testClosure ); - /** @var \\PHPUnit\Framework\TestResult $result */ - $this->object->setTestResult( $result ); - - try { - $this->object->checkCalls(); - } catch ( \Exception $e ) { - fclose( $resource ); - throw $e; - } - fclose( $resource ); - } - - protected function getCalls( $listener ) { - $prop = new ReflectionProperty( $listener, 'calls' ); - $prop->setAccessible( true ); - - return $prop->getValue( $listener ); - } - + \PHPUnit\Framework\Assert::assertEquals($message, $exception->getMessage()); + \PHPUnit\Framework\Assert::assertTrue(0 === $int); + }; + $result->shouldReceive('addFailure') + ->once() + ->andReturnUsing($testClosure); + /** @var \\PHPUnit\Framework\TestResult $result */ + $this->object->setTestResult($result); + + try { + $this->object->checkCalls(); + } catch (\Exception $e) { + fclose($resource); + throw $e; + } + fclose($resource); + } + + protected function getCalls($listener) + { + $prop = new ReflectionProperty($listener, 'calls'); + $prop->setAccessible(true); + + return $prop->getValue($listener); + } } diff --git a/tests/WP_Mock/Matcher/AnyInstanceTest.php b/tests/WP_Mock/Matcher/AnyInstanceTest.php index b6ded470..35f7f18f 100644 --- a/tests/WP_Mock/Matcher/AnyInstanceTest.php +++ b/tests/WP_Mock/Matcher/AnyInstanceTest.php @@ -4,10 +4,9 @@ class AnyInstanceTest extends \PHPUnit\Framework\TestCase { - - /** - * @covers \WP_Mock\Matcher\AnyInstance::match - */ + /** + * @covers \WP_Mock\Matcher\AnyInstance::match + */ public function testExactClassInstanceMatchesTrue() { $sut = new AnyInstance(new SampleClass()); @@ -19,9 +18,9 @@ public function testExactClassInstanceMatchesTrue() $this->assertTrue($result); } - /** - * @covers \WP_Mock\Matcher\AnyInstance::match - */ + /** + * @covers \WP_Mock\Matcher\AnyInstance::match + */ public function testExactClassStringMatchesTrue() { $sut = new AnyInstance(SampleClass::class); @@ -33,9 +32,9 @@ public function testExactClassStringMatchesTrue() $this->assertTrue($result); } - /** - * @covers \WP_Mock\Matcher\AnyInstance::match - */ + /** + * @covers \WP_Mock\Matcher\AnyInstance::match + */ public function testSubClassMatchesTrue() { $sut = new AnyInstance(SampleClass::class); @@ -47,9 +46,9 @@ public function testSubClassMatchesTrue() $this->assertTrue($result); } - /** - * @covers \WP_Mock\Matcher\AnyInstance::match - */ + /** + * @covers \WP_Mock\Matcher\AnyInstance::match + */ public function testWrongClassMatchesFalse() { $sut = new AnyInstance(SampleClass::class); @@ -61,9 +60,9 @@ public function testWrongClassMatchesFalse() $this->assertFalse($result); } - /** - * @covers \WP_Mock\Matcher\AnyInstance::match - */ + /** + * @covers \WP_Mock\Matcher\AnyInstance::match + */ public function testClosureMatchesFalse() { $sut = new AnyInstance(SampleClass::class); @@ -76,9 +75,9 @@ public function testClosureMatchesFalse() $this->assertFalse($result); } - /** - * @covers \WP_Mock\Matcher\AnyInstance::match - */ + /** + * @covers \WP_Mock\Matcher\AnyInstance::match + */ public function testStringFunctionMatchesFalse() { $sut = new AnyInstance(SampleClass::class); @@ -90,10 +89,11 @@ public function testStringFunctionMatchesFalse() $this->assertFalse($result); } - /** - * @covers \WP_Mock\Matcher\AnyInstance::__toString - */ - public function testToString() { + /** + * @covers \WP_Mock\Matcher\AnyInstance::__toString + */ + public function testToString() + { $sut = new AnyInstance(SampleClass::class); $result = "$sut"; @@ -101,13 +101,13 @@ public function testToString() { $this->assertEquals("", $result); } - /** - * @covers \WP_Mock\Matcher\AnyInstance::__construct - */ - public function testCannotConstructWithoutObject() { + /** + * @covers \WP_Mock\Matcher\AnyInstance::__construct + */ + public function testCannotConstructWithoutObject() + { $this->expectException(\Exception::class); - new AnyInstance('NotAClass' ); + new AnyInstance('NotAClass'); } } - diff --git a/tests/WP_Mock/Matcher/SampleClass.php b/tests/WP_Mock/Matcher/SampleClass.php index 595776ad..5fe4d67c 100644 --- a/tests/WP_Mock/Matcher/SampleClass.php +++ b/tests/WP_Mock/Matcher/SampleClass.php @@ -2,6 +2,9 @@ namespace WP_Mock\Matcher; -class SampleClass { - public function action(){} -} \ No newline at end of file +class SampleClass +{ + public function action() + { + } +} diff --git a/tests/WP_Mock/Matcher/SampleSubClass.php b/tests/WP_Mock/Matcher/SampleSubClass.php index b8f0a724..776569fe 100644 --- a/tests/WP_Mock/Matcher/SampleSubClass.php +++ b/tests/WP_Mock/Matcher/SampleSubClass.php @@ -2,6 +2,9 @@ namespace WP_Mock\Matcher; -class SampleSubClass extends SampleClass { - public function action(){} -} \ No newline at end of file +class SampleSubClass extends SampleClass +{ + public function action() + { + } +} diff --git a/tests/WP_MockTest.php b/tests/WP_MockTest.php index 017a8323..8d882590 100644 --- a/tests/WP_MockTest.php +++ b/tests/WP_MockTest.php @@ -1,130 +1,138 @@ assertFalse(WP_Mock::strictMode()); + } - /** - * @covers \WP_Mock::strictMode() - * - * @runInSeparateProcess - */ - public function test_strictMode_off_by_default() { - $this->assertFalse( WP_Mock::strictMode() ); - } + /** + * @covers \WP_Mock::activateStrictMode() + * + * @runInSeparateProcess + */ + public function test_activateStrictMode_turns_strict_mode_on() + { + WP_Mock::activateStrictMode(); + $this->assertTrue(WP_Mock::strictMode()); + } - /** - * @covers \WP_Mock::activateStrictMode() - * - * @runInSeparateProcess - */ - public function test_activateStrictMode_turns_strict_mode_on() { - WP_Mock::activateStrictMode(); - $this->assertTrue( WP_Mock::strictMode() ); - } + /** + * @covers \WP_Mock::strictMode() + * + * @runInSeparateProcess + */ + public function test_activateStrictMode_does_not_work_after_bootstrap() + { + WP_Mock::bootstrap(); + WP_Mock::activateStrictMode(); + $this->assertFalse(WP_Mock::strictMode()); + } - /** - * @covers \WP_Mock::strictMode() - * - * @runInSeparateProcess - */ - public function test_activateStrictMode_does_not_work_after_bootstrap() { - WP_Mock::bootstrap(); - WP_Mock::activateStrictMode(); - $this->assertFalse( WP_Mock::strictMode() ); - } + /** + * @covers \WP_Mock::userFunction() + * + * @runInSeparateProcess + */ + public function test_userFunction_returns_expectation() + { + WP_Mock::bootstrap(); + $this->assertInstanceOf( + '\Mockery\ExpectationInterface', + WP_Mock::userFunction('testWpMockFunction') + ); + } - /** - * @covers \WP_Mock::userFunction() - * - * @runInSeparateProcess - */ - public function test_userFunction_returns_expectation() { - WP_Mock::bootstrap(); - $this->assertInstanceOf( - '\Mockery\ExpectationInterface', - WP_Mock::userFunction( 'testWpMockFunction' ) - ); - } + /** + * @covers \WP_Mock::assertHooksAdded() + * + * @runInSeparateProcess + */ + public function test_assertHooksAdded_for_filters_and_actions() + { + WP_Mock::bootstrap(); + WP_Mock::expectFilterAdded('testFilter', 'testCallback', 10, 1); + WP_Mock::expectActionAdded('testAction', 'testCallback', 10, 1); + add_action('testAction', 'testCallback', 10, 1); + add_filter('testFilter', 'testCallback', 10, 1); + WP_Mock::assertHooksAdded(); + \Mockery::close(); + } - /** - * @covers \WP_Mock::assertHooksAdded() - * - * @runInSeparateProcess - */ - public function test_assertHooksAdded_for_filters_and_actions() { - WP_Mock::bootstrap(); - WP_Mock::expectFilterAdded( 'testFilter', 'testCallback' ,10, 1); - WP_Mock::expectActionAdded( 'testAction', 'testCallback', 10, 1 ); - add_action( 'testAction', 'testCallback',10, 1 ); - add_filter('testFilter','testCallback', 10, 1); - WP_Mock::assertHooksAdded(); - \Mockery::close(); - } + /** + * @covers WP_Mock::assertHooksAdded() + * + * @runInSeparateProcess + */ + public function test_assertHooksAdded_for_filters_and_actions_fails() + { + WP_Mock::bootstrap(); + WP_Mock::expectFilterAdded('testFilter', 'testCallback', 10, 1); + WP_Mock::expectActionAdded('testAction', 'testCallback', 10, 1); + $this->expectException('PHPUnit\Framework\ExpectationFailedException'); + WP_Mock::assertHooksAdded(); + \Mockery::close(); + } - /** - * @covers WP_Mock::assertHooksAdded() - * - * @runInSeparateProcess - */ - public function test_assertHooksAdded_for_filters_and_actions_fails() { - WP_Mock::bootstrap(); - WP_Mock::expectFilterAdded( 'testFilter', 'testCallback', 10, 1 ); - WP_Mock::expectActionAdded( 'testAction', 'testCallback', 10, 1 ); - $this->expectException('PHPUnit\Framework\ExpectationFailedException'); - WP_Mock::assertHooksAdded(); - \Mockery::close(); - } + /** + * @covers \WP_Mock::assertActionsCalled() + * + * @runInSeparateProcess + */ + public function test_assertActionsCalled_actions() + { + WP_Mock::bootstrap(); + WP_Mock::expectAction('testAction'); + do_action('testAction'); + WP_Mock::assertActionsCalled(); + \Mockery::close(); + } - /** - * @covers \WP_Mock::assertActionsCalled() - * - * @runInSeparateProcess - */ - public function test_assertActionsCalled_actions() { - WP_Mock::bootstrap(); - WP_Mock::expectAction( 'testAction' ); - do_action('testAction'); - WP_Mock::assertActionsCalled(); - \Mockery::close(); - } + /** + * @covers \WP_Mock::assertActionsCalled() + * + * @runInSeparateProcess + */ + public function test_assertActionsCalled_actions_fails() + { + WP_Mock::bootstrap(); + WP_Mock::expectAction('testAction'); + $this->expectException('PHPUnit\Framework\ExpectationFailedException'); + WP_Mock::assertActionsCalled(); + \Mockery::close(); + } - /** - * @covers \WP_Mock::assertActionsCalled() - * - * @runInSeparateProcess - */ - public function test_assertActionsCalled_actions_fails() { - WP_Mock::bootstrap(); - WP_Mock::expectAction( 'testAction' ); - $this->expectException( 'PHPUnit\Framework\ExpectationFailedException' ); - WP_Mock::assertActionsCalled(); - \Mockery::close(); - } + /** + * @covers \WP_Mock::assertFiltersCalled() + * + * @runInSeparateProcess + */ + public function test_assertActionsCalled_filters() + { + WP_Mock::bootstrap(); + WP_Mock::expectFilter('testFilter', 'testVal'); + apply_filters('testFilter', 'testVal'); + WP_Mock::assertFiltersCalled(); + \Mockery::close(); + } - /** - * @covers \WP_Mock::assertFiltersCalled() - * - * @runInSeparateProcess - */ - public function test_assertActionsCalled_filters() { + /** + * @covers \WP_Mock::assertFiltersCalled() + * + * @runInSeparateProcess + */ + public function test_assertActionsCalled_filters_fails() + { + WP_Mock::bootstrap(); + WP_Mock::expectFilter('testFilter2', 'testVal'); - WP_Mock::bootstrap(); - WP_Mock::expectFilter( 'testFilter','testVal' ); - apply_filters( 'testFilter','testVal' ); - WP_Mock::assertFiltersCalled(); - \Mockery::close(); - } - - /** - * @covers \WP_Mock::assertFiltersCalled() - * - * @runInSeparateProcess - */ - public function test_assertActionsCalled_filters_fails() { - - WP_Mock::bootstrap(); - WP_Mock::expectFilter( 'testFilter2', 'testVal' ); - - $this->expectException( 'Mockery\Exception\InvalidCountException' ); - \Mockery::close(); - } -} \ No newline at end of file + $this->expectException('Mockery\Exception\InvalidCountException'); + \Mockery::close(); + } +} From aad2d189173be685adea0d606614b9afd554d655 Mon Sep 17 00:00:00 2001 From: Fulvio Notarstefano Date: Tue, 20 Dec 2022 01:29:25 +0800 Subject: [PATCH 6/6] Remove phpcs baseliner --- composer.json | 3 +-- composer.lock | 51 +-------------------------------------------------- 2 files changed, 2 insertions(+), 52 deletions(-) diff --git a/composer.json b/composer.json index f5415b9b..98b69760 100644 --- a/composer.json +++ b/composer.json @@ -20,8 +20,7 @@ "phpstan/phpstan-mockery": "^1.1", "phpcompatibility/php-compatibility": "^9.3", "friendsofphp/php-cs-fixer": "^3.4", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", - "isaac/php-code-sniffer-baseliner": "^2.3" + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 1b87ff94..4eb73b92 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "db1e63489e66a58f3c1eefe202d2f244", + "content-hash": "4fd16463059c0d0c57b88f07666c413a", "packages": [ { "name": "antecedent/patchwork", @@ -3018,55 +3018,6 @@ ], "time": "2022-10-26T14:07:24+00:00" }, - { - "name": "isaac/php-code-sniffer-baseliner", - "version": "v2.3.1", - "source": { - "type": "git", - "url": "https://github.com/isaaceindhoven/php-code-sniffer-baseliner.git", - "reference": "2c4e8ef2763b925cb0bb6aa2a0b3542f107db3b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/isaaceindhoven/php-code-sniffer-baseliner/zipball/2c4e8ef2763b925cb0bb6aa2a0b3542f107db3b2", - "reference": "2c4e8ef2763b925cb0bb6aa2a0b3542f107db3b2", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-simplexml": "*", - "php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "require-dev": { - "isaac/php-code-sniffer-standard": "^28.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.6.8", - "phpstan/phpstan-phpunit": "^1.1.1", - "phpstan/phpstan-strict-rules": "^1.2.3", - "phpunit/phpunit": "^9.5" - }, - "bin": [ - "bin/phpcs-baseliner" - ], - "type": "library", - "autoload": { - "psr-4": { - "ISAAC\\CodeSnifferBaseliner\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "ISAAC PHP Code Sniffer Baseliner", - "support": { - "issues": "https://github.com/isaaceindhoven/php-code-sniffer-baseliner/issues", - "source": "https://github.com/isaaceindhoven/php-code-sniffer-baseliner/tree/v2.3.1" - }, - "time": "2022-11-16T13:51:09+00:00" - }, { "name": "php-coveralls/php-coveralls", "version": "v2.5.3",