diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 35d2ea5..ead22e0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -61,4 +61,11 @@ jobs: - name: Run tests run: | - vendor/bin/phpunit + vendor/bin/phpunit --coverage-clover build/logs/clover.xml + + - name: Upload coverage results to Coveralls + continue-on-error: true + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + php vendor/bin/php-coveralls --coverage_clover=build/logs/clover.xml -v diff --git a/.gitignore b/.gitignore index ce7bff7..ec06cc6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /composer.lock /phpunit.xml /vendor/ +/build/ diff --git a/.php_cs.dist b/.php_cs.dist index 8a2af04..d3a2c6d 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -22,6 +22,7 @@ return PhpCsFixer\Config::create() 'combine_consecutive_unsets' => true, 'comment_to_phpdoc' => true, 'compact_nullable_typehint' => true, + 'declare_strict_types' => false, 'escape_implicit_backslashes' => true, 'explicit_indirect_variable' => true, 'explicit_string_variable' => true, diff --git a/composer.json b/composer.json index 24719e2..10433c0 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.0 || ^9.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2" + "friendsofphp/php-cs-fixer": "^2", + "php-coveralls/php-coveralls": "^2.4" }, "config": { "optimize-autoloader": true, diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c643ce0..0493a2b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,10 @@ + + + src + + tests diff --git a/src/PolyfillTrait.php b/src/PolyfillTrait.php index 7c9e840..0381233 100644 --- a/src/PolyfillTrait.php +++ b/src/PolyfillTrait.php @@ -14,14 +14,7 @@ if (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0') < 0) { trait PolyfillTrait { - public function expectException($exception) - { - if (\is_callable(['parent', 'expectException'])) { - parent::expectException($exception); - } else { - $this->setExpectedException($exception); - } - } + use PolyfillTrait6; } } else { trait PolyfillTrait diff --git a/src/PolyfillTrait6.php b/src/PolyfillTrait6.php new file mode 100644 index 0000000..9cdbbdc --- /dev/null +++ b/src/PolyfillTrait6.php @@ -0,0 +1,137 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PHPUnitGoodPractices\Polyfill; + +/** + * @internal + */ +trait PolyfillTrait6 +{ + public function expectException($exception) + { + if (\is_callable(['parent', 'expectException'])) { + parent::expectException($exception); + } else { + $this->setExpectedException($exception); + } + } + + public function expectExceptionMessageMatches($regexp) + { + if (\is_callable(['parent', 'expectExceptionMessageMatches'])) { + parent::expectExceptionMessageMatches($regexp); + + return; + } + + // In some PHPUnit versions just setting an expectation for specific + // expection message won't trigger exception handler. Therefore we need + // to set the expected type, but trying to keep the type. + if (\is_callable(['parent', 'getExpectedException'])) { + $expectedException = parent::getExpectedException(); // This is an @internal method. + } + + if (null === $expectedException) { + $expectedException = \Exception::class; + } + + $this->expectException($expectedException); + + if (\is_callable(['parent', 'expectExceptionMessageRegExp'])) { + // Method available since Release 5.2.0 + $this->expectExceptionMessageRegExp($regexp); + } else { + $this->setExpectedExceptionRegExp($expectedException, $regexp); + } + } + + public static function assertIsArray($actual, $message = '') + { + if (\is_callable(['parent', 'assertIsArray'])) { + parent::assertIsArray($actual, $message); + } else { + static::assertInternalType('array', $actual, $message); + } + } + + public static function assertIsString($actual, $message = '') + { + if (\is_callable(['parent', 'assertIsString'])) { + parent::assertIsString($actual, $message); + } else { + static::assertInternalType('string', $actual, $message); + } + } + + public static function assertIsBool($actual, $message = '') + { + if (\is_callable(['parent', 'assertIsBool'])) { + parent::assertIsBool($actual, $message); + } else { + static::assertInternalType('bool', $actual, $message); + } + } + + public static function assertIsCallable($actual, $message = '') + { + if (\is_callable(['parent', 'assertIsCallable'])) { + parent::assertIsCallable($actual, $message); + } else { + static::assertInternalType('callable', $actual, $message); + } + } + + public static function assertIsInt($actual, $message = '') + { + if (\is_callable(['parent', 'assertIsInt'])) { + parent::assertIsInt($actual, $message); + } else { + static::assertInternalType('int', $actual, $message); + } + } + + public static function assertMatchesRegularExpression($pattern, $string, $message = '') + { + if (\is_callable(['parent', 'assertMatchesRegularExpression'])) { + parent::assertMatchesRegularExpression($pattern, $string, $message); + } else { + static::assertRegExp($pattern, $string, $message); + } + } + + public static function assertStringContainsString($needle, $haystack, $message = '') + { + if (\is_callable(['parent', 'assertStringContainsString'])) { + parent::assertStringContainsString($needle, $haystack, $message); + } else { + static::assertContains($needle, $haystack, $message); + } + } + + public static function assertStringNotContainsString($needle, $haystack, $message = '') + { + if (\is_callable(['parent', 'assertStringNotContainsString'])) { + parent::assertStringNotContainsString($needle, $haystack, $message); + } else { + static::assertNotContains($needle, $haystack, $message); + } + } + + public static function assertFileDoesNotExist($filename, $message = '') + { + if (\is_callable(['parent', 'assertFileDoesNotExist'])) { + parent::assertFileDoesNotExist($filename, $message); + } else { + static::assertFileNotExists($filename, $message); + } + } +} diff --git a/src/PolyfillTrait7.php b/src/PolyfillTrait7.php index a023381..7157399 100644 --- a/src/PolyfillTrait7.php +++ b/src/PolyfillTrait7.php @@ -26,4 +26,31 @@ public function expectException(string $exception): void $this->setExpectedException($exception); } } + + public function expectExceptionMessageMatches(string $regexp): void + { + if (\is_callable(['parent', 'expectExceptionMessageMatches'])) { + parent::expectExceptionMessageMatches($regexp); + } else { + $this->expectExceptionMessageRegExp($regexp); + } + } + + public static function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void + { + if (\is_callable(['parent', 'assertMatchesRegularExpression'])) { + parent::assertMatchesRegularExpression($pattern, $string, $message); + } else { + static::assertRegExp($pattern, $string, $message); + } + } + + public static function assertFileDoesNotExist(string $filename, string $message = ''): void + { + if (\is_callable(['parent', 'assertFileDoesNotExist'])) { + parent::assertFileDoesNotExist($filename, $message); + } else { + static::assertFileNotExists($filename, $message); + } + } } diff --git a/tests/PolyfillTest.php b/tests/PolyfillTest.php index 45e73bb..aa60544 100644 --- a/tests/PolyfillTest.php +++ b/tests/PolyfillTest.php @@ -23,6 +23,57 @@ public function testExpectException() $this->expectException(\RuntimeException::class); throw new \RuntimeException(); - $this->fail(); + } + + public function testExpectExceptionMessageMatches() + { + $this->expectExceptionMessageMatches('/example/'); + + throw new \RuntimeException('example'); + } + + public function testAssertIsArray() + { + $this->assertIsArray([]); + } + + public function testAssertIsString() + { + $this->assertIsString(''); + } + + public function testAssertIsBool() + { + $this->assertIsBool(true); + } + + public function testAssertIsCallable() + { + $this->assertIsCallable([$this, 'testAssertIsCallable']); + } + + public function testAssertIsInt() + { + $this->assertIsInt(1); + } + + public function testAssertMatchesRegularExpression() + { + $this->assertMatchesRegularExpression('/\d/', '123'); + } + + public function testAssertStringContainsString() + { + $this->assertStringContainsString('test', 'testing'); + } + + public function testAssertStringNotContainsString() + { + $this->assertStringNotContainsString('foobar', 'testing'); + } + + public function testAssertFileDoesNotExist() + { + $this->assertFileDoesNotExist('invalid'); } }