├── .github └── workflows │ ├── ci.yaml │ └── cs.yaml ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml.dist ├── src ├── PolyfillTrait.php ├── PolyfillTrait6.php ├── PolyfillTrait7.php └── aliases.php └── tests └── PolyfillTest.php /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | # yamllint disable rule:line-length 2 | # yamllint disable rule:braces 3 | 4 | name: Continuous Integration 5 | 6 | on: 7 | pull_request: 8 | push: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | tests: 14 | runs-on: ${{ matrix.operating-system }} 15 | 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | operating-system: 20 | - ubuntu-latest 21 | php-version: 22 | - 5.5 23 | - 5.6 24 | - 7.0 25 | - 7.1 26 | - 7.2 27 | - 7.3 28 | - 7.4 29 | - 8.0 30 | - 8.1 31 | - 8.2 32 | 33 | name: PHP ${{ matrix.php-version }} CI on ${{ matrix.operating-system }} 34 | 35 | steps: 36 | - name: Checkout code 37 | uses: actions/checkout@v2 38 | 39 | - name: Setup PHP 40 | uses: shivammathur/setup-php@v2 41 | with: 42 | php-version: ${{ matrix.php-version }} 43 | tools: composer:v2 44 | 45 | - name: Get composer cache directory 46 | id: composer-cache 47 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 48 | 49 | - name: Cache dependencies 50 | uses: actions/cache@v2 51 | with: 52 | path: ${{ steps.composer-cache.outputs.dir }} 53 | key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-${{ matrix.composer-flags }} 54 | restore-keys: | 55 | composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}- 56 | composer-${{ runner.os }}-${{ matrix.php-version }}- 57 | composer-${{ runner.os }}- 58 | composer- 59 | 60 | - name: Install dependencies 61 | run: | 62 | composer update --optimize-autoloader --no-interaction --no-progress ${{ matrix.composer-flags }} 63 | 64 | - name: Run tests 65 | run: | 66 | vendor/bin/phpunit --coverage-clover build/logs/clover.xml 67 | 68 | - name: Upload coverage results to Coveralls 69 | continue-on-error: true 70 | env: 71 | COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} 72 | run: | 73 | php vendor/bin/php-coveralls --coverage_clover=build/logs/clover.xml -v 74 | -------------------------------------------------------------------------------- /.github/workflows/cs.yaml: -------------------------------------------------------------------------------- 1 | # yamllint disable rule:line-length 2 | # yamllint disable rule:braces 3 | 4 | name: Code Style 5 | 6 | on: 7 | pull_request: 8 | push: 9 | branches: 10 | - master 11 | - main 12 | 13 | jobs: 14 | tests: 15 | runs-on: ${{ matrix.operating-system }} 16 | 17 | strategy: 18 | matrix: 19 | operating-system: 20 | - ubuntu-latest 21 | php-version: 22 | - 7.4 23 | 24 | name: PHP CS Fixer 25 | 26 | steps: 27 | - name: Checkout code 28 | uses: actions/checkout@v2 29 | 30 | - name: Setup PHP 31 | uses: shivammathur/setup-php@v2 32 | with: 33 | php-version: ${{ matrix.php-version }} 34 | tools: composer:v2 35 | 36 | - name: Get composer cache directory 37 | id: composer-cache 38 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 39 | 40 | - name: Cache dependencies 41 | uses: actions/cache@v2 42 | with: 43 | path: ${{ steps.composer-cache.outputs.dir }} 44 | key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-${{ matrix.composer-flags }} 45 | restore-keys: | 46 | composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}- 47 | composer-${{ runner.os }}-${{ matrix.php-version }}- 48 | composer-${{ runner.os }}- 49 | composer- 50 | 51 | - name: Install dependencies 52 | run: | 53 | composer update --optimize-autoloader --no-interaction --no-progress ${{ matrix.composer-flags }} 54 | 55 | - name: Run PHP CS Fixer 56 | run: | 57 | php vendor/bin/php-cs-fixer --diff --dry-run -v fix 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018-present Dariusz Rumiński 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is furnished 10 | to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ❗ THIS PACKAGE IS DEPRECATED ❗ 2 | 3 | With the great shape of PHPUnit, stable release process and no need to support multiple different versions of PHPUnit, there is no need for this package anymore. 4 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phpunitgoodpractices/polyfill", 3 | "type": "library", 4 | "description": "Lacking future-compat polyfills for PHPUnit.", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Dariusz Rumiński", 9 | "email": "dariusz.ruminski@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": "^5.5 || ^7.0 || ^8.0", 14 | "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.0 || ^9.0 || ^10.0" 15 | }, 16 | "require-dev": { 17 | "friendsofphp/php-cs-fixer": "^2", 18 | "php-coveralls/php-coveralls": "^2.4" 19 | }, 20 | "config": { 21 | "optimize-autoloader": true, 22 | "sort-packages": true 23 | }, 24 | "autoload": { 25 | "files": [ "src/aliases.php" ], 26 | "psr-4": { "PHPUnitGoodPractices\\Polyfill\\": "src/" } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | ./src 10 | 11 | 12 | 13 | 14 | tests 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/PolyfillTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace PHPUnitGoodPractices\Polyfill; 13 | 14 | if (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0') < 0) { 15 | trait PolyfillTrait 16 | { 17 | use PolyfillTrait6; 18 | } 19 | } elseif (version_compare(\PHPUnit\Runner\Version::id(), '10.0.0') < 0) { 20 | trait PolyfillTrait 21 | { 22 | use PolyfillTrait7; 23 | } 24 | } else { 25 | trait PolyfillTrait 26 | { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/PolyfillTrait6.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace PHPUnitGoodPractices\Polyfill; 13 | 14 | /** 15 | * @internal 16 | */ 17 | trait PolyfillTrait6 18 | { 19 | public function expectException($exception) 20 | { 21 | if (\is_callable([parent::class, 'expectException'])) { 22 | parent::expectException($exception); 23 | } else { 24 | $this->setExpectedException($exception); 25 | } 26 | } 27 | 28 | public function expectExceptionMessageMatches($regexp) 29 | { 30 | if (\is_callable([parent::class, 'expectExceptionMessageMatches'])) { 31 | parent::expectExceptionMessageMatches($regexp); 32 | 33 | return; 34 | } 35 | 36 | // In some PHPUnit versions just setting an expectation for specific 37 | // expection message won't trigger exception handler. Therefore we need 38 | // to set the expected type, but trying to keep the type. 39 | if (\is_callable([parent::class, 'getExpectedException'])) { 40 | $expectedException = parent::getExpectedException(); // This is an @internal method. 41 | } 42 | 43 | if (null === $expectedException) { 44 | $expectedException = \Exception::class; 45 | } 46 | 47 | $this->expectException($expectedException); 48 | 49 | if (\is_callable([parent::class, 'expectExceptionMessageRegExp'])) { 50 | // Method available since Release 5.2.0 51 | $this->expectExceptionMessageRegExp($regexp); 52 | } else { 53 | $this->setExpectedExceptionRegExp($expectedException, $regexp); 54 | } 55 | } 56 | 57 | public static function assertIsArray($actual, $message = '') 58 | { 59 | if (\is_callable([parent::class, 'assertIsArray'])) { 60 | parent::assertIsArray($actual, $message); 61 | } else { 62 | static::assertInternalType('array', $actual, $message); 63 | } 64 | } 65 | 66 | public static function assertIsString($actual, $message = '') 67 | { 68 | if (\is_callable([parent::class, 'assertIsString'])) { 69 | parent::assertIsString($actual, $message); 70 | } else { 71 | static::assertInternalType('string', $actual, $message); 72 | } 73 | } 74 | 75 | public static function assertIsBool($actual, $message = '') 76 | { 77 | if (\is_callable([parent::class, 'assertIsBool'])) { 78 | parent::assertIsBool($actual, $message); 79 | } else { 80 | static::assertInternalType('bool', $actual, $message); 81 | } 82 | } 83 | 84 | public static function assertIsCallable($actual, $message = '') 85 | { 86 | if (\is_callable([parent::class, 'assertIsCallable'])) { 87 | parent::assertIsCallable($actual, $message); 88 | } else { 89 | static::assertInternalType('callable', $actual, $message); 90 | } 91 | } 92 | 93 | public static function assertIsInt($actual, $message = '') 94 | { 95 | if (\is_callable([parent::class, 'assertIsInt'])) { 96 | parent::assertIsInt($actual, $message); 97 | } else { 98 | static::assertInternalType('int', $actual, $message); 99 | } 100 | } 101 | 102 | public static function assertMatchesRegularExpression($pattern, $string, $message = '') 103 | { 104 | if (\is_callable([parent::class, 'assertMatchesRegularExpression'])) { 105 | parent::assertMatchesRegularExpression($pattern, $string, $message); 106 | } else { 107 | static::assertRegExp($pattern, $string, $message); 108 | } 109 | } 110 | 111 | public static function assertStringContainsString($needle, $haystack, $message = '') 112 | { 113 | if (\is_callable([parent::class, 'assertStringContainsString'])) { 114 | parent::assertStringContainsString($needle, $haystack, $message); 115 | } else { 116 | static::assertContains($needle, $haystack, $message); 117 | } 118 | } 119 | 120 | public static function assertStringNotContainsString($needle, $haystack, $message = '') 121 | { 122 | if (\is_callable([parent::class, 'assertStringNotContainsString'])) { 123 | parent::assertStringNotContainsString($needle, $haystack, $message); 124 | } else { 125 | static::assertNotContains($needle, $haystack, $message); 126 | } 127 | } 128 | 129 | public static function assertFileDoesNotExist($filename, $message = '') 130 | { 131 | if (\is_callable([parent::class, 'assertFileDoesNotExist'])) { 132 | parent::assertFileDoesNotExist($filename, $message); 133 | } else { 134 | static::assertFileNotExists($filename, $message); 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/PolyfillTrait7.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * This source file is subject to the MIT license that is bundled 11 | * with this source code in the file LICENSE. 12 | */ 13 | 14 | namespace PHPUnitGoodPractices\Polyfill; 15 | 16 | /** 17 | * @internal 18 | */ 19 | trait PolyfillTrait7 20 | { 21 | public function expectException(string $exception): void 22 | { 23 | if (\is_callable([parent::class, 'expectException'])) { 24 | parent::expectException($exception); 25 | } else { 26 | $this->setExpectedException($exception); 27 | } 28 | } 29 | 30 | public function expectExceptionMessageMatches(string $regexp): void 31 | { 32 | if (\is_callable([parent::class, 'expectExceptionMessageMatches'])) { 33 | parent::expectExceptionMessageMatches($regexp); 34 | } else { 35 | $this->expectExceptionMessageRegExp($regexp); 36 | } 37 | } 38 | 39 | public static function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void 40 | { 41 | if (\is_callable([parent::class, 'assertMatchesRegularExpression'])) { 42 | parent::assertMatchesRegularExpression($pattern, $string, $message); 43 | } else { 44 | static::assertRegExp($pattern, $string, $message); 45 | } 46 | } 47 | 48 | public static function assertFileDoesNotExist(string $filename, string $message = ''): void 49 | { 50 | if (\is_callable([parent::class, 'assertFileDoesNotExist'])) { 51 | parent::assertFileDoesNotExist($filename, $message); 52 | } else { 53 | static::assertFileNotExists($filename, $message); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/aliases.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | foreach ([ 13 | 'PHPUnit_Framework_Error_Warning' => 'PHPUnit\Framework\Error\Warning', 14 | 'PHPUnit_Framework_ExpectationFailedException' => 'PHPUnit\Framework\ExpectationFailedException', 15 | 'PHPUnit_Framework_TestCase' => 'PHPUnit\Framework\TestCase', 16 | 'PHPUnit_Runner_Version' => 'PHPUnit\Runner\Version', 17 | ] as $old => $new) { 18 | if (!class_exists($new) && class_exists($old)) { 19 | class_alias($old, $new); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/PolyfillTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace PHPUnitGoodPractices\Tests\Polyfill; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use PHPUnitGoodPractices\Polyfill\PolyfillTrait; 16 | 17 | class PolyfillTest extends TestCase 18 | { 19 | use PolyfillTrait; 20 | 21 | public function testExpectException() 22 | { 23 | $this->expectException(\RuntimeException::class); 24 | 25 | throw new \RuntimeException(); 26 | } 27 | 28 | public function testExpectExceptionMessageMatches() 29 | { 30 | $this->expectExceptionMessageMatches('/example/'); 31 | 32 | throw new \RuntimeException('example'); 33 | } 34 | 35 | public function testAssertIsArray() 36 | { 37 | $this->assertIsArray([]); 38 | } 39 | 40 | public function testAssertIsString() 41 | { 42 | $this->assertIsString(''); 43 | } 44 | 45 | public function testAssertIsBool() 46 | { 47 | $this->assertIsBool(true); 48 | } 49 | 50 | public function testAssertIsCallable() 51 | { 52 | $this->assertIsCallable([$this, 'testAssertIsCallable']); 53 | } 54 | 55 | public function testAssertIsInt() 56 | { 57 | $this->assertIsInt(1); 58 | } 59 | 60 | public function testAssertMatchesRegularExpression() 61 | { 62 | $this->assertMatchesRegularExpression('/\d/', '123'); 63 | } 64 | 65 | public function testAssertStringContainsString() 66 | { 67 | $this->assertStringContainsString('test', 'testing'); 68 | } 69 | 70 | public function testAssertStringNotContainsString() 71 | { 72 | $this->assertStringNotContainsString('foobar', 'testing'); 73 | } 74 | 75 | public function testAssertFileDoesNotExist() 76 | { 77 | $this->assertFileDoesNotExist('invalid'); 78 | } 79 | } 80 | --------------------------------------------------------------------------------