From fb4067efc45b20984c692d7ad5f873986e89459c Mon Sep 17 00:00:00 2001 From: Sam Mousa Date: Thu, 4 Sep 2025 15:38:18 +0200 Subject: [PATCH 1/6] feat!: import lib-asserts, drop it as a dependency, require phpunit 11.5 automated releases --- .github/workflows/main.yml | 2 +- .github/workflows/release.yml | 62 + .releaserc.json | 11 + composer.json | 6 +- phpstan.neon | 5 + src/Codeception/Util/Shared/Asserts.php | 111 ++ .../Util/Shared/InheritedAsserts.php | 1339 +++++++++++++++++ tests/Support/Data/DummyClass.php | 6 + tests/unit/Codeception/Module/AssertsTest.php | 48 +- 9 files changed, 1562 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 .releaserc.json create mode 100644 phpstan.neon create mode 100644 src/Codeception/Util/Shared/Asserts.php create mode 100644 src/Codeception/Util/Shared/InheritedAsserts.php diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e8c6cc8..bd17774 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: run: composer install --prefer-dist --no-progress --no-interaction --no-suggest - name: Run PHPStan - run: phpstan analyse src + run: phpstan - name: Run PHPCS run: phpcs --standard=PSR12 src diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..11382e3 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,62 @@ +name: Automated release +on: + push: + branches: + - master +jobs: + tests: + runs-on: ubuntu-latest + strategy: + matrix: + php: [ 8.2, 8.3, 8.4 ] + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + tools: phpstan, phpcs + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-interaction --no-suggest + + - name: Run PHPStan + run: phpstan + + - name: Run PHPCS + run: phpcs --standard=PSR12 src + + - name: Run test suite + run: php vendor/bin/codecept run + release: + name: Automated release + needs: + - tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-node@v4 + with: + node-version: 22 + - run: > + npx + -p "@semantic-release/commit-analyzer" + -p "@semantic-release/release-notes-generator" + -p conventional-changelog-conventionalcommits + -p semantic-release + -- semantic-release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +permissions: + packages: write + contents: write + pull-requests: write \ No newline at end of file diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..8492546 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,11 @@ +{ + "branches": ["master"], + "tagFormat": "${version}", + "plugins": [ + ["@semantic-release/commit-analyzer", { + "preset": "conventionalcommits", + "presetConfig": {} + }], + "@semantic-release/github", + "@semantic-release/release-notes-generator"] +} \ No newline at end of file diff --git a/composer.json b/composer.json index 3f7cd00..9030299 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,7 @@ "description": "Codeception module containing various assertions", "license": "MIT", "type": "library", + "prefer-stable": true, "keywords": [ "codeception", "asserts", @@ -24,11 +25,14 @@ "require": { "php": "^8.2", "codeception/codeception": "*@dev", - "codeception/lib-asserts": "^2.2" + "phpunit/phpunit": "^11.5 | ^12" }, "conflict": { "codeception/codeception": "<5.0" }, + "provide": { + "codeception/lib-asserts": "^2.2" + }, "minimum-stability": "dev", "autoload": { "classmap": [ diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..c7dfed4 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,5 @@ +parameters: + level: 9 + paths: + - tests/ + - src/ \ No newline at end of file diff --git a/src/Codeception/Util/Shared/Asserts.php b/src/Codeception/Util/Shared/Asserts.php new file mode 100644 index 0000000..3e647ef --- /dev/null +++ b/src/Codeception/Util/Shared/Asserts.php @@ -0,0 +1,111 @@ +hasMethod($fullMethod) && $rc->getMethod($fullMethod)->isStatic()) { + $rc->getMethod($fullMethod)->invokeArgs(null, $arguments); + } else { + throw new \RuntimeException("Method Assert::{$fullMethod} does not exist"); + } + } + + /** + * @param array{0: string} $arguments + * @return void + */ + protected function assertNot(array $arguments): void + { + $this->assert($arguments, true); + } + + /** + * Asserts that a file does not exist. + */ + protected function assertFileNotExists(string $filename, string $message = ''): void + { + Assert::assertFileDoesNotExist($filename, $message); + } + + /** + * Asserts that a value is greater than or equal to another value. + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertGreaterOrEquals($expected, $actual, string $message = ''): void + { + Assert::assertGreaterThanOrEqual($expected, $actual, $message); + } + + /** + * Asserts that a variable is empty. + */ + protected function assertIsEmpty(mixed $actual, string $message = ''): void + { + Assert::assertEmpty($actual, $message); + } + + /** + * Asserts that a value is smaller than or equal to another value. + */ + protected function assertLessOrEquals(mixed $expected, mixed $actual, string $message = ''): void + { + Assert::assertLessThanOrEqual($expected, $actual, $message); + } + + /** + * Asserts that a string does not match a given regular expression. + */ + protected function assertNotRegExp(string $pattern, string $string, string $message = ''): void + { + Assert::assertDoesNotMatchRegularExpression($pattern, $string, $message); + } + + /** + * Asserts that a string matches a given regular expression. + */ + protected function assertRegExp(string $pattern, string $string, string $message = ''): void + { + Assert::assertMatchesRegularExpression($pattern, $string, $message); + } + + /** + * Evaluates a PHPUnit\Framework\Constraint matcher object. + */ + protected function assertThatItsNot(mixed $value, PHPUnitConstraint $constraint, string $message = ''): void + { + $constraint = new LogicalNot($constraint); + Assert::assertThat($value, $constraint, $message); + } +} diff --git a/src/Codeception/Util/Shared/InheritedAsserts.php b/src/Codeception/Util/Shared/InheritedAsserts.php new file mode 100644 index 0000000..ea098db --- /dev/null +++ b/src/Codeception/Util/Shared/InheritedAsserts.php @@ -0,0 +1,1339 @@ +|ArrayAccess $array + */ + protected function assertArrayHasKey(int|string $key, array|ArrayAccess $array, string $message = ''): void + { + Assert::assertArrayHasKey($key, $array, $message); + } + + /** + * Asserts that an array does not have a specified key. + * @param array|ArrayAccess $array + */ + protected function assertArrayNotHasKey(int|string $key, array|\ArrayAccess $array, string $message = ''): void + { + Assert::assertArrayNotHasKey($key, $array, $message); + } + + /** + * Asserts that a class has a specified attribute. + * @param class-string $className + */ + protected function assertClassHasAttribute(string $attributeName, string $className, string $message = ''): void + { + trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); + Assert::assertTrue(property_exists($className, $attributeName), $message); + } + + /** + * Asserts that a class has a specified static attribute. + * @param class-string $className + */ + protected function assertClassHasStaticAttribute(string $attributeName, string $className, string $message = ''): void + { + trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); + + Assert::assertTrue(self::hasStaticAttribute($attributeName, $className), $message); + } + + /** + * Asserts that a class does not have a specified attribute. + * @param class-string $className + */ + protected function assertClassNotHasAttribute(string $attributeName, string $className, string $message = ''): void + { + trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); + Assert::assertFalse(property_exists($className, $attributeName), $message); + } + + /** + * Asserts that a class does not have a specified static attribute. + * @param class-string $className + */ + protected function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = ''): void + { + trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); + Assert::assertFalse(self::hasStaticAttribute($attributeName, $className), $message); + } + + /** + * Asserts that a haystack contains a needle. + * + * @param iterable $haystack + */ + protected function assertContains(mixed $needle, iterable $haystack, string $message = ''): void + { + Assert::assertContains($needle, $haystack, $message); + } + + /** + * @param iterable $haystack + */ + protected function assertContainsEquals(mixed $needle, iterable $haystack, string $message = ''): void + { + Assert::assertContainsEquals($needle, $haystack, $message); + } + + /** + * Asserts that a haystack contains only values of a given type. + * @param 'array'|'bool'|'boolean'|'callable'|'double'|'float'|'int'|'integer'|'iterable'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'scalar'|'string'|class-string $type + * @param iterable $haystack + */ + protected function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void + { + /** @phpstan-ignore-next-line */ + Assert::assertContainsOnly($type, $haystack, $isNativeType, $message); + } + + /** + * Asserts that a haystack contains only instances of a given class name. + * @param class-string $className + * @param iterable $haystack + */ + protected function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void + { + Assert::assertContainsOnlyInstancesOf($className, $haystack, $message); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param \Countable|iterable $haystack + */ + protected function assertCount(int $expectedCount, \Countable|iterable $haystack, string $message = ''): void + { + Assert::assertCount($expectedCount, $haystack, $message); + } + + /** + * Asserts that a directory does not exist. + */ + protected function assertDirectoryDoesNotExist(string $directory, string $message = ''): void + { + Assert::assertDirectoryDoesNotExist($directory, $message); + } + + /** + * Asserts that a directory exists. + */ + protected function assertDirectoryExists(string $directory, string $message = ''): void + { + Assert::assertDirectoryExists($directory, $message); + } + + /** + * Asserts that a directory exists and is not readable. + */ + protected function assertDirectoryIsNotReadable(string $directory, string $message = ''): void + { + Assert::assertDirectoryIsNotReadable($directory, $message); + } + + /** + * Asserts that a directory exists and is not writable. + */ + protected function assertDirectoryIsNotWritable(string $directory, string $message = ''): void + { + Assert::assertDirectoryIsNotWritable($directory, $message); + } + + /** + * Asserts that a directory exists and is readable. + */ + protected function assertDirectoryIsReadable(string $directory, string $message = ''): void + { + Assert::assertDirectoryIsReadable($directory, $message); + } + + /** + * Asserts that a directory exists and is writable. + */ + protected function assertDirectoryIsWritable(string $directory, string $message = ''): void + { + Assert::assertDirectoryIsWritable($directory, $message); + } + + /** + * Asserts that a string does not match a given regular expression. + */ + protected function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = ''): void + { + Assert::assertDoesNotMatchRegularExpression($pattern, $string, $message); + } + + /** + * Asserts that a variable is empty. + * + * @param mixed $actual + * + * @phpstan-assert empty $actual + */ + protected function assertEmpty($actual, string $message = ''): void + { + Assert::assertEmpty($actual, $message); + } + + /** + * Asserts that two variables are equal. + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertEquals($expected, $actual, string $message = ''): void + { + Assert::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two variables are equal (canonicalizing). + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertEqualsCanonicalizing($expected, $actual, string $message = ''): void + { + Assert::assertEqualsCanonicalizing($expected, $actual, $message); + } + + /** + * Asserts that two variables are equal (ignoring case). + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertEqualsIgnoringCase($expected, $actual, string $message = ''): void + { + Assert::assertEqualsIgnoringCase($expected, $actual, $message); + } + + /** + * Asserts that two variables are equal (with delta). + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void + { + Assert::assertEqualsWithDelta($expected, $actual, $delta, $message); + } + + /** + * Asserts that a condition is false. + * + * @param mixed $condition + * + * @phpstan-assert false $condition + */ + protected function assertFalse($condition, string $message = ''): void + { + Assert::assertFalse($condition, $message); + } + + /** + * Asserts that a file does not exist. + */ + protected function assertFileDoesNotExist(string $filename, string $message = ''): void + { + Assert::assertFileDoesNotExist($filename, $message); + } + + /** + * Asserts that the contents of one file is equal to the contents of another file. + */ + protected function assertFileEquals(string $expected, string $actual, string $message = ''): void + { + Assert::assertFileEquals($expected, $actual, $message); + } + + /** + * Asserts that the contents of one file is equal to the contents of another file (canonicalizing). + */ + protected function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void + { + Assert::assertFileEqualsCanonicalizing($expected, $actual, $message); + } + + /** + * Asserts that the contents of one file is equal to the contents of another file (ignoring case). + */ + protected function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void + { + Assert::assertFileEqualsIgnoringCase($expected, $actual, $message); + } + + /** + * Asserts that a file exists. + */ + protected function assertFileExists(string $filename, string $message = ''): void + { + Assert::assertFileExists($filename, $message); + } + + /** + * Asserts that a file exists and is not readable. + */ + protected function assertFileIsNotReadable(string $file, string $message = ''): void + { + Assert::assertFileIsNotReadable($file, $message); + } + + /** + * Asserts that a file exists and is not writable. + */ + protected function assertFileIsNotWritable(string $file, string $message = ''): void + { + Assert::assertFileIsNotWritable($file, $message); + } + + /** + * Asserts that a file exists and is readable. + */ + protected function assertFileIsReadable(string $file, string $message = ''): void + { + Assert::assertFileIsReadable($file, $message); + } + + /** + * Asserts that a file exists and is writable. + */ + protected function assertFileIsWritable(string $file, string $message = ''): void + { + Assert::assertFileIsWritable($file, $message); + } + + /** + * Asserts that the contents of one file is not equal to the contents of another file. + */ + protected function assertFileNotEquals(string $expected, string $actual, string $message = ''): void + { + Assert::assertFileNotEquals($expected, $actual, $message); + } + + /** + * Asserts that the contents of one file is not equal to the contents of another file (canonicalizing). + */ + protected function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void + { + Assert::assertFileNotEqualsCanonicalizing($expected, $actual, $message); + } + + /** + * Asserts that the contents of one file is not equal to the contents of another file (ignoring case). + */ + protected function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void + { + Assert::assertFileNotEqualsIgnoringCase($expected, $actual, $message); + } + + /** + * Asserts that a variable is finite. + * + * @param mixed $actual + */ + protected function assertFinite($actual, string $message = ''): void + { + Assert::assertFinite($actual, $message); + } + + /** + * Asserts that a value is greater than another value. + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertGreaterThan($expected, $actual, string $message = ''): void + { + Assert::assertGreaterThan($expected, $actual, $message); + } + + /** + * Asserts that a value is greater than or equal to another value. + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertGreaterThanOrEqual($expected, $actual, string $message = ''): void + { + Assert::assertGreaterThanOrEqual($expected, $actual, $message); + } + + /** + * Asserts that a variable is infinite. + * + * @param mixed $actual + */ + protected function assertInfinite($actual, string $message = ''): void + { + Assert::assertInfinite($actual, $message); + } + + /** + * Asserts that a variable is of a given type. + * + * @template ExpectedType of object + * + * @param mixed $actual + * @param class-string $expected + * + * @phpstan-assert =ExpectedType $actual + */ + protected function assertInstanceOf(string $expected, $actual, string $message = ''): void + { + Assert::assertInstanceOf($expected, $actual, $message); + } + + /** + * Asserts that a variable is of type array. + * + * @param mixed $actual + * @phpstan-assert array $actual + */ + protected function assertIsArray($actual, string $message = ''): void + { + Assert::assertIsArray($actual, $message); + } + + /** + * Asserts that a variable is of type bool. + * + * @param mixed $actual + * + * @phpstan-assert bool $actual + */ + protected function assertIsBool($actual, string $message = ''): void + { + Assert::assertIsBool($actual, $message); + } + + /** + * Asserts that a variable is of type callable. + * + * @param mixed $actual + * + * @phpstan-assert callable $actual + */ + protected function assertIsCallable($actual, string $message = ''): void + { + Assert::assertIsCallable($actual, $message); + } + + /** + * Asserts that a variable is of type resource and is closed. + * + * @param mixed $actual + * + * @phpstan-assert resource $actual + */ + protected function assertIsClosedResource($actual, string $message = ''): void + { + Assert::assertIsClosedResource($actual, $message); + } + + /** + * Asserts that a variable is of type float. + * + * @param mixed $actual + * + * @phpstan-assert float $actual + */ + protected function assertIsFloat($actual, string $message = ''): void + { + Assert::assertIsFloat($actual, $message); + } + + /** + * Asserts that a variable is of type int. + * + * @param mixed $actual + * + * @phpstan-assert int $actual + */ + protected function assertIsInt($actual, string $message = ''): void + { + Assert::assertIsInt($actual, $message); + } + + /** + * Asserts that a variable is of type iterable. + * + * @param mixed $actual + * + * @phpstan-assert iterable $actual + */ + protected function assertIsIterable($actual, string $message = ''): void + { + Assert::assertIsIterable($actual, $message); + } + + /** + * Asserts that a variable is not of type array. + * + * @param mixed $actual + * + * @phpstan-assert !array $actual + */ + protected function assertIsNotArray($actual, string $message = ''): void + { + Assert::assertIsNotArray($actual, $message); + } + + /** + * Asserts that a variable is not of type bool. + * + * @param mixed $actual + * + * @phpstan-assert !bool $actual + */ + protected function assertIsNotBool($actual, string $message = ''): void + { + Assert::assertIsNotBool($actual, $message); + } + + /** + * Asserts that a variable is not of type callable. + * + * @param mixed $actual + * + * @phpstan-assert !callable $actual + */ + protected function assertIsNotCallable($actual, string $message = ''): void + { + Assert::assertIsNotCallable($actual, $message); + } + + /** + * Asserts that a variable is not of type resource. + * + * @param mixed $actual + * + * @phpstan-assert !resource $actual + */ + protected function assertIsNotClosedResource($actual, string $message = ''): void + { + Assert::assertIsNotClosedResource($actual, $message); + } + + /** + * Asserts that a variable is not of type float. + * + * @param mixed $actual + * + * @phpstan-assert !float $actual + */ + protected function assertIsNotFloat($actual, string $message = ''): void + { + Assert::assertIsNotFloat($actual, $message); + } + + /** + * Asserts that a variable is not of type int. + * + * @param mixed $actual + * + * @phpstan-assert !int $actual + */ + protected function assertIsNotInt($actual, string $message = ''): void + { + Assert::assertIsNotInt($actual, $message); + } + + /** + * Asserts that a variable is not of type iterable. + * + * @param mixed $actual + * + * @phpstan-assert !iterable $actual + */ + protected function assertIsNotIterable($actual, string $message = ''): void + { + Assert::assertIsNotIterable($actual, $message); + } + + /** + * Asserts that a variable is not of type numeric. + * + * @param mixed $actual + * + * @phpstan-assert !numeric $actual + */ + protected function assertIsNotNumeric($actual, string $message = ''): void + { + Assert::assertIsNotNumeric($actual, $message); + } + + /** + * Asserts that a variable is not of type object. + * + * @param mixed $actual + * + * @phpstan-assert !object $actual + */ + protected function assertIsNotObject($actual, string $message = ''): void + { + Assert::assertIsNotObject($actual, $message); + } + + /** + * Asserts that a file/dir exists and is not readable. + */ + protected function assertIsNotReadable(string $filename, string $message = ''): void + { + Assert::assertIsNotReadable($filename, $message); + } + + /** + * Asserts that a variable is not of type resource. + * + * @param mixed $actual + * + * @phpstan-assert !resource $actual + */ + protected function assertIsNotResource($actual, string $message = ''): void + { + Assert::assertIsNotResource($actual, $message); + } + + /** + * Asserts that a variable is not of type scalar. + * + * @param mixed $actual + * + * @psalm-assert !scalar $actual + */ + protected function assertIsNotScalar($actual, string $message = ''): void + { + Assert::assertIsNotScalar($actual, $message); + } + + /** + * Asserts that a variable is not of type string. + * + * @param mixed $actual + * + * @phpstan-assert !string $actual + */ + protected function assertIsNotString($actual, string $message = ''): void + { + Assert::assertIsNotString($actual, $message); + } + + /** + * Asserts that a file/dir exists and is not writable. + */ + protected function assertIsNotWritable(string $filename, string $message = ''): void + { + Assert::assertIsNotWritable($filename, $message); + } + + /** + * Asserts that a variable is of type numeric. + * + * @param mixed $actual + * + * @phpstan-assert numeric $actual + */ + protected function assertIsNumeric($actual, string $message = ''): void + { + Assert::assertIsNumeric($actual, $message); + } + + /** + * Asserts that a variable is of type object. + * + * @param mixed $actual + * + * @phpstan-assert object $actual + */ + protected function assertIsObject($actual, string $message = ''): void + { + Assert::assertIsObject($actual, $message); + } + + /** + * Asserts that a file/dir is readable. + */ + protected function assertIsReadable(string $filename, string $message = ''): void + { + Assert::assertIsReadable($filename, $message); + } + + /** + * Asserts that a variable is of type resource. + * + * @param mixed $actual + * + * @phpstan-assert resource $actual + */ + protected function assertIsResource($actual, string $message = ''): void + { + Assert::assertIsResource($actual, $message); + } + + /** + * Asserts that a variable is of type scalar. + * + * @param mixed $actual + * + * @phpstan-assert scalar $actual + */ + protected function assertIsScalar($actual, string $message = ''): void + { + Assert::assertIsScalar($actual, $message); + } + + /** + * Asserts that a variable is of type string. + * + * @param mixed $actual + * + * @phpstan-assert string $actual + */ + protected function assertIsString($actual, string $message = ''): void + { + Assert::assertIsString($actual, $message); + } + + /** + * Asserts that a file/dir exists and is writable. + */ + protected function assertIsWritable(string $filename, string $message = ''): void + { + Assert::assertIsWritable($filename, $message); + } + + /** + * Asserts that a string is a valid JSON string. + */ + protected function assertJson(string $actualJson, string $message = ''): void + { + Assert::assertJson($actualJson, $message); + } + + /** + * Asserts that two JSON files are equal. + */ + protected function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void + { + Assert::assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message); + } + + /** + * Asserts that two JSON files are not equal. + */ + protected function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void + { + Assert::assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message); + } + + /** + * Asserts that the generated JSON encoded object and the content of the given file are equal. + */ + protected function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void + { + Assert::assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message); + } + + /** + * Asserts that two given JSON encoded objects or arrays are equal. + */ + protected function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void + { + Assert::assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message); + } + + /** + * Asserts that the generated JSON encoded object and the content of the given file are not equal. + */ + protected function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void + { + Assert::assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message); + } + + /** + * Asserts that two given JSON encoded objects or arrays are not equal. + */ + protected function assertJsonStringNotEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void + { + Assert::assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message); + } + + /** + * Asserts that a value is smaller than another value. + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertLessThan($expected, $actual, string $message = ''): void + { + Assert::assertLessThan($expected, $actual, $message); + } + + /** + * Asserts that a value is smaller than or equal to another value. + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertLessThanOrEqual($expected, $actual, string $message = ''): void + { + Assert::assertLessThanOrEqual($expected, $actual, $message); + } + + /** + * Asserts that a string matches a given regular expression. + */ + protected function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void + { + Assert::assertMatchesRegularExpression($pattern, $string, $message); + } + + /** + * Asserts that a variable is nan. + * + * @param mixed $actual + */ + protected function assertNan($actual, string $message = ''): void + { + Assert::assertNan($actual, $message); + } + + /** + * Asserts that a haystack does not contain a needle. + * + * @param iterable $haystack + */ + protected function assertNotContains(mixed $needle, iterable $haystack, string $message = ''): void + { + Assert::assertNotContains($needle, $haystack, $message); + } + + /** + * Asserts that a haystack does not contain only values of a given type. + * @param 'array'|'bool'|'boolean'|'callable'|'double'|'float'|'int'|'integer'|'iterable'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'scalar'|'string'|class-string $type + * @param iterable $haystack + */ + protected function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void + { + /** @phpstan-ignore-next-line */ + Assert::assertNotContainsOnly($type, $haystack, $isNativeType, $message); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param \Countable|iterable $haystack + */ + protected function assertNotCount(int $expectedCount, \Countable|iterable $haystack, string $message = ''): void + { + Assert::assertNotCount($expectedCount, $haystack, $message); + } + + /** + * Asserts that a variable is not empty. + * + * @param mixed $actual + * + * @phpstan-assert !empty $actual + */ + protected function assertNotEmpty($actual, string $message = ''): void + { + Assert::assertNotEmpty($actual, $message); + } + + /** + * Asserts that two variables are not equal. + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertNotEquals($expected, $actual, string $message = ''): void + { + Assert::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that two variables are not equal (canonicalizing). + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertNotEqualsCanonicalizing($expected, $actual, string $message = ''): void + { + Assert::assertNotEqualsCanonicalizing($expected, $actual, $message); + } + + /** + * Asserts that two variables are not equal (ignoring case). + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertNotEqualsIgnoringCase($expected, $actual, string $message = ''): void + { + Assert::assertNotEqualsIgnoringCase($expected, $actual, $message); + } + + /** + * Asserts that two variables are not equal (with delta). + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertNotEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void + { + Assert::assertNotEqualsWithDelta($expected, $actual, $delta, $message); + } + + /** + * Asserts that a condition is not false. + * + * @param mixed $condition + * + * @phpstan-assert !false $condition + */ + protected function assertNotFalse($condition, string $message = ''): void + { + Assert::assertNotFalse($condition, $message); + } + + /** + * Asserts that a variable is not of a given type. + * + * @template ExpectedType of object + * + * @param mixed $actual + * @param class-string $expected + * + * @phpstan-assert !ExpectedType $actual + */ + protected function assertNotInstanceOf(string $expected, $actual, string $message = ''): void + { + Assert::assertNotInstanceOf($expected, $actual, $message); + } + + /** + * Asserts that a variable is not null. + * + * @param mixed $actual + * + * @phpstan-assert !null $actual + */ + protected function assertNotNull($actual, string $message = ''): void + { + Assert::assertNotNull($actual, $message); + } + + /** + * Asserts that two variables do not have the same type and value. + * + * @param mixed $expected + * @param mixed $actual + */ + protected function assertNotSame($expected, $actual, string $message = ''): void + { + Assert::assertNotSame($expected, $actual, $message); + } + + /** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) is not the same. + * + * @param \Countable|iterable $expected + * @param \Countable|iterable $actual + */ + protected function assertNotSameSize(\Countable|iterable $expected, \Countable|iterable $actual, string $message = ''): void + { + Assert::assertNotSameSize($expected, $actual, $message); + } + + /** + * Asserts that a condition is not true. + * + * @param mixed $condition + * + * @phpstan-assert !true $condition + */ + protected function assertNotTrue($condition, string $message = ''): void + { + Assert::assertNotTrue($condition, $message); + } + + /** + * Asserts that a variable is null. + * + * @param mixed $actual + * + * @phpstan-assert null $actual + */ + protected function assertNull($actual, string $message = ''): void + { + Assert::assertNull($actual, $message); + } + + /** + * Asserts that an object has a specified attribute. + */ + protected function assertObjectHasAttribute(string $attributeName, object $object, string $message = ''): void + { + trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); + + if (method_exists(Assert::class, 'assertObjectHasAttribute')) { + Assert::assertObjectHasAttribute($attributeName, $object, $message); + } else { + Assert::assertTrue(property_exists($object, $attributeName), $message); + } + } + + /** + * Asserts that an object does not have a specified attribute. + */ + protected function assertObjectNotHasAttribute(string $attributeName, object $object, string $message = ''): void + { + trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); + + if (method_exists(Assert::class, 'assertObjectNotHasAttribute')) { + Assert::assertObjectNotHasAttribute($attributeName, $object, $message); + } else { + Assert::assertFalse(property_exists($object, $attributeName), $message); + } + } + + /** + * Asserts that two variables have the same type and value. + * Used on objects, it asserts that two variables reference + * the same object. + * + * @template ExpectedType + * + * @param ExpectedType $expected + * + * @phpstan-assert =ExpectedType $actual + */ + protected function assertSame(mixed $expected, mixed $actual, string $message = ''): void + { + Assert::assertSame($expected, $actual, $message); + } + + /** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) is the same. + * @param \Countable|iterable $expected + * @param \Countable|iterable $actual + */ + protected function assertSameSize(\Countable|iterable $expected, \Countable|iterable $actual, string $message = ''): void + { + Assert::assertSameSize($expected, $actual, $message); + } + + protected function assertStringContainsString(string $needle, string $haystack, string $message = ''): void + { + Assert::assertStringContainsString($needle, $haystack, $message); + } + + protected function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void + { + Assert::assertStringContainsStringIgnoringCase($needle, $haystack, $message); + } + + /** + * Asserts that a string ends not with a given suffix. + * @param non-empty-string $suffix + */ + protected function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void + { + Assert::assertStringEndsNotWith($suffix, $string, $message); + } + + /** + * Asserts that a string ends with a given suffix. + * @param non-empty-string $suffix + */ + protected function assertStringEndsWith(string $suffix, string $string, string $message = ''): void + { + Assert::assertStringEndsWith($suffix, $string, $message); + } + + /** + * Asserts that the contents of a string is equal to the contents of a file. + */ + protected function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = ''): void + { + Assert::assertStringEqualsFile($expectedFile, $actualString, $message); + } + + /** + * Asserts that the contents of a string is equal to the contents of a file (canonicalizing). + */ + protected function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void + { + Assert::assertStringEqualsFileCanonicalizing($expectedFile, $actualString, $message); + } + + /** + * Asserts that the contents of a string is equal to the contents of a file (ignoring case). + */ + protected function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void + { + Assert::assertStringEqualsFileIgnoringCase($expectedFile, $actualString, $message); + } + + /** + * Asserts that a string matches a given format string. + */ + protected function assertStringMatchesFormat(string $format, string $string, string $message = ''): void + { + Assert::assertStringMatchesFormat($format, $string, $message); + } + + /** + * Asserts that a string matches a given format file. + */ + protected function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void + { + Assert::assertStringMatchesFormatFile($formatFile, $string, $message); + } + + protected function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void + { + Assert::assertStringNotContainsString($needle, $haystack, $message); + } + + protected function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void + { + Assert::assertStringNotContainsStringIgnoringCase($needle, $haystack, $message); + } + + /** + * Asserts that the contents of a string is not equal to the contents of a file. + */ + protected function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = ''): void + { + Assert::assertStringNotEqualsFile($expectedFile, $actualString, $message); + } + + /** + * Asserts that the contents of a string is not equal to the contents of a file (canonicalizing). + */ + protected function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void + { + Assert::assertStringNotEqualsFileCanonicalizing($expectedFile, $actualString, $message); + } + + /** + * Asserts that the contents of a string is not equal to the contents of a file (ignoring case). + */ + protected function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void + { + Assert::assertStringNotEqualsFileIgnoringCase($expectedFile, $actualString, $message); + } + + /** + * Asserts that a string does not match a given format string. + */ + protected function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void + { + trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 12', E_USER_DEPRECATED); + $constraint = new LogicalNot(new StringMatchesFormatDescription($format)); + Assert::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string does not match a given format string. + */ + protected function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void + { + trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 12', E_USER_DEPRECATED); + $content = file_get_contents($formatFile); + if ($content === false) { + Assert::fail(sprintf('Failed to read format file "%s"', $formatFile)); + } + $constraint = new LogicalNot(new StringMatchesFormatDescription($content)); + Assert::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string starts not with a given prefix. + * @param non-empty-string $prefix + */ + protected function assertStringStartsNotWith(string $prefix, string $string, string $message = ''): void + { + Assert::assertStringStartsNotWith($prefix, $string, $message); + } + + /** + * Asserts that a string starts with a given prefix. + * @param non-empty-string $prefix + */ + protected function assertStringStartsWith(string $prefix, string $string, string $message = ''): void + { + Assert::assertStringStartsWith($prefix, $string, $message); + } + + /** + * Evaluates a PHPUnit\Framework\Constraint matcher object. + * + * @param mixed $value + */ + protected function assertThat($value, PHPUnitConstraint $constraint, string $message = ''): void + { + Assert::assertThat($value, $constraint, $message); + } + + /** + * Asserts that a condition is true. + * + * @param mixed $condition + * + * @phpstan-assert true $condition + */ + protected function assertTrue($condition, string $message = ''): void + { + Assert::assertTrue($condition, $message); + } + + /** + * Asserts that two XML files are equal. + */ + protected function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void + { + Assert::assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message); + } + + /** + * Asserts that two XML files are not equal. + */ + protected function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void + { + Assert::assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message); + } + + /** + * Asserts that two XML documents are equal. + */ + protected function assertXmlStringEqualsXmlFile(string $expectedFile, \DOMDocument|string $actualXml, string $message = ''): void + { + if ($actualXml instanceof \DOMDocument) { + $actualXml = $actualXml->saveXML(); + if ($actualXml === false) { + throw new \RuntimeException('Failed to transform XML document to string'); + } + } + Assert::assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message); + } + + /** + * Asserts that two XML documents are equal. + */ + protected function assertXmlStringEqualsXmlString(\DOMDocument|string $expectedXml, \DOMDocument|string $actualXml, string $message = ''): void + { + if ($actualXml instanceof \DOMDocument) { + $actualXml = $actualXml->saveXML(); + if ($actualXml === false) { + throw new \RuntimeException('Failed to transform XML document to string'); + } + } + if ($expectedXml instanceof \DOMDocument) { + $expectedXml = $expectedXml->saveXML(); + if ($expectedXml === false) { + throw new \RuntimeException('Failed to transform XML document to string'); + } + } + Assert::assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message); + } + + /** + * Asserts that two XML documents are not equal. + * + * @param \DOMDocument|string $actualXml + */ + protected function assertXmlStringNotEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void + { + if ($actualXml instanceof \DOMDocument) { + $actualXml = $actualXml->saveXML(); + if ($actualXml === false) { + throw new \RuntimeException('Failed to transform XML document to string'); + } + } + Assert::assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message); + } + + /** + * Asserts that two XML documents are not equal. + * + * @param \DOMDocument|string $expectedXml + * @param \DOMDocument|string $actualXml + */ + protected function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, string $message = ''): void + { + if ($actualXml instanceof \DOMDocument) { + $actualXml = $actualXml->saveXML(); + if ($actualXml === false) { + throw new \RuntimeException('Failed to transform XML document to string'); + } + } + if ($expectedXml instanceof \DOMDocument) { + $expectedXml = $expectedXml->saveXML(); + if ($expectedXml === false) { + throw new \RuntimeException('Failed to transform XML document to string'); + } + } + Assert::assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message); + } + + /** + * Fails a test with the given message. + */ + protected function fail(string $message = ''): never + { + Assert::fail($message); + } + + /** + * Mark the test as incomplete. + */ + protected function markTestIncomplete(string $message = ''): never + { + Assert::markTestIncomplete($message); + } + + /** + * Mark the test as skipped. + */ + protected function markTestSkipped(string $message = ''): never + { + Assert::markTestSkipped($message); + } + + /** + * @see https://github.com/sebastianbergmann/phpunit/blob/9.6/src/Framework/Constraint/Object/ClassHasStaticAttribute.php + * @param class-string $className + */ + private static function hasStaticAttribute(string $attributeName, string $className): bool + { + try { + $class = new \ReflectionClass($className); + + if ($class->hasProperty($attributeName)) { + return $class->getProperty($attributeName)->isStatic(); + } + } catch (ReflectionException $e) { + } + + return false; + } +} diff --git a/tests/Support/Data/DummyClass.php b/tests/Support/Data/DummyClass.php index 6967cfd..036b162 100644 --- a/tests/Support/Data/DummyClass.php +++ b/tests/Support/Data/DummyClass.php @@ -6,7 +6,13 @@ class DummyClass { + /** + * @phpstan-ignore-next-line + */ private int $foo; + /** + * @phpstan-ignore-next-line + */ private static int $staticFoo; } \ No newline at end of file diff --git a/tests/unit/Codeception/Module/AssertsTest.php b/tests/unit/Codeception/Module/AssertsTest.php index 12ce769..303244b 100644 --- a/tests/unit/Codeception/Module/AssertsTest.php +++ b/tests/unit/Codeception/Module/AssertsTest.php @@ -9,20 +9,20 @@ use Codeception\PHPUnit\TestCase; use Codeception\Stub; use Exception; +use PHPUnit\Framework\Assert; use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\Constraint\IsEqual; use PHPUnit\Framework\IncompleteTestError; +use PHPUnit\Framework\SkippedTest; use PHPUnit\Framework\SkippedTestError; -use PHPUnit\Framework\SkippedWithMessageException; -use PHPUnit\Runner\Version as PHPUnitVersion; use RuntimeException; use stdClass; final class AssertsTest extends TestCase { - protected ?Asserts $module = null; + private Asserts $module; - public function _setUp() + public function _setUp(): void { require_once codecept_data_dir().'/DummyClass.php'; @@ -31,7 +31,7 @@ public function _setUp() $this->module = new Asserts($container); } - public function testCodeceptionAsserts() + public function testCodeceptionAsserts(): void { $this->module->assertFileNotExists(__FILE__ . '.notExist'); $this->module->assertGreaterOrEquals(2, 2); @@ -44,7 +44,7 @@ public function testCodeceptionAsserts() $this->module->assertThatItsNot(3, new IsEqual(4)); } - public function testPHPUnitAsserts() + public function testPHPUnitAsserts(): void { $this->module->assertArrayHasKey('one', ['one' => 1, 'two' => 2]); $this->module->assertArrayNotHasKey('three', ['one' => 1, 'two' => 2]); @@ -91,7 +91,8 @@ public function testPHPUnitAsserts() $this->module->assertIsArray([1, 2, 3]); $this->module->assertIsBool(true); $this->module->assertIsCallable(function() {}); - $closedResource = fopen(__FILE__, 'r'); + $closedResource = fopen('php://temp', 'r'); + Assert::assertNotFalse($closedResource); fclose($closedResource); $this->module->assertIsClosedResource($closedResource); $this->module->assertIsFloat(1.2); @@ -100,7 +101,8 @@ public function testPHPUnitAsserts() $this->module->assertIsNotArray(false); $this->module->assertIsNotBool([1, 2, 3]); $this->module->assertIsNotCallable('test'); - $openendResource = fopen(__FILE__, 'r'); + $openendResource = fopen('php://temp', 'r'); + Assert::assertNotFalse($openendResource); $this->module->assertIsNotClosedResource($openendResource); $this->module->assertIsNotFloat(false); $this->module->assertIsNotInt(false); @@ -131,7 +133,6 @@ public function testPHPUnitAsserts() $this->module->assertMatchesRegularExpression('/^[\d]$/', '1'); $this->module->assertNan(sqrt(-1)); $this->module->assertNotContains('three', ['one', 'two']); - $this->module->assertNotContainsEquals(3, [1, 2]); $this->module->assertNotContainsOnly(\Support\Data\DummyClass::class, [new \Support\Data\DummyClass(), new Exception()]); $this->module->assertNotCount(1, ['one', 'two']); $this->module->assertNotEmpty([1]); @@ -184,7 +185,7 @@ public function testPHPUnitAsserts() $this->module->assertXmlStringNotEqualsXmlString('foo', 'bar'); } - public function testExceptions() + public function testExceptions(): void { $this->module->expectThrowable('Exception', function () { throw new Exception; @@ -197,7 +198,7 @@ public function testExceptions() }); } - public function testExceptionFails() + public function testExceptionFails(): void { $this->expectException(AssertionFailedError::class); @@ -206,7 +207,7 @@ public function testExceptionFails() }); } - public function testOutputExceptionTimeWhenNothingCaught() + public function testOutputExceptionTimeWhenNothingCaught(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessageRegExp('/RuntimeException/'); @@ -215,7 +216,7 @@ public function testOutputExceptionTimeWhenNothingCaught() }); } - public function testExpectThrowable() + public function testExpectThrowable(): void { $this->module->expectThrowable('Exception', function () { throw new Exception(); @@ -228,7 +229,7 @@ public function testExpectThrowable() }); } - public function testExpectThrowableFailOnDifferentClass() + public function testExpectThrowableFailOnDifferentClass(): void { $this->expectException(AssertionFailedError::class); @@ -237,7 +238,7 @@ public function testExpectThrowableFailOnDifferentClass() }); } - public function testExpectThrowableFailOnDifferentMessage() + public function testExpectThrowableFailOnDifferentMessage(): void { $this->expectException(AssertionFailedError::class); @@ -246,7 +247,7 @@ public function testExpectThrowableFailOnDifferentMessage() }); } - public function testExpectThrowableFailOnDifferentCode() + public function testExpectThrowableFailOnDifferentCode(): void { $this->expectException(AssertionFailedError::class); @@ -255,7 +256,7 @@ public function testExpectThrowableFailOnDifferentCode() }); } - public function testExpectThrowableFailOnNothingCaught() + public function testExpectThrowableFailOnNothingCaught(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessageRegExp('/RuntimeException/'); @@ -264,7 +265,7 @@ public function testExpectThrowableFailOnNothingCaught() }); } - public function testFail() + public function testFail(): void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage('foobar'); @@ -272,7 +273,7 @@ public function testFail() $this->module->fail('foobar'); } - public function testMarkTestIncomplete() + public function testMarkTestIncomplete(): void { $this->expectException(IncompleteTestError::class); $this->expectExceptionMessage('foobar'); @@ -280,15 +281,10 @@ public function testMarkTestIncomplete() $this->module->markTestIncomplete('foobar'); } - public function testMarkTestSkipped() + public function testMarkTestSkipped(): void { $this->expectExceptionMessage('foobar'); - if (PHPUnitVersion::series() < 10) { - $this->expectException(SkippedTestError::class); - } else { - $this->expectException(SkippedWithMessageException::class); - } - + $this->expectException(SkippedTest::class); $this->module->markTestSkipped('foobar'); } } From e54f22a1121e40a35fafc3887a9088936379e2b3 Mon Sep 17 00:00:00 2001 From: Sam Mousa Date: Thu, 4 Sep 2025 15:40:06 +0200 Subject: [PATCH 2/6] chore(ci): add codecept build step before phpstan --- .github/workflows/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bd17774..eded2bb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,6 +27,9 @@ jobs: - name: Install dependencies run: composer install --prefer-dist --no-progress --no-interaction --no-suggest + - name: Build test actors + run: php vendor/bin/codecept build + - name: Run PHPStan run: phpstan From ef797a13e8c70767f427e55b2f2197d01bdeb427 Mon Sep 17 00:00:00 2001 From: Sam Mousa Date: Thu, 4 Sep 2025 15:47:22 +0200 Subject: [PATCH 3/6] chore: remove import that did not exist --- .github/workflows/main.yml | 3 ++- src/Codeception/Module/AbstractAsserts.php | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index eded2bb..366148c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,7 @@ name: CI -on: [push, pull_request] +on: + pull_request: jobs: tests: diff --git a/src/Codeception/Module/AbstractAsserts.php b/src/Codeception/Module/AbstractAsserts.php index da1fb93..3c8e7de 100644 --- a/src/Codeception/Module/AbstractAsserts.php +++ b/src/Codeception/Module/AbstractAsserts.php @@ -95,7 +95,6 @@ abstract class AbstractAsserts extends Module assertMatchesRegularExpression as public; assertNan as public; assertNotContains as public; - assertNotContainsEquals as public; assertNotContainsOnly as public; assertNotCount as public; assertNotEmpty as public; From 26c929db322657035b6210b642bf446325c62f02 Mon Sep 17 00:00:00 2001 From: Sam Mousa Date: Thu, 4 Sep 2025 16:11:15 +0200 Subject: [PATCH 4/6] chore(ci): ignore known evaluation errors from phpstan --- phpstan.neon | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index c7dfed4..b57fa13 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,4 +2,6 @@ parameters: level: 9 paths: - tests/ - - src/ \ No newline at end of file + - src/ + ignoreErrors: + - '#^Call to method Codeception\\Module\\AbstractAsserts::.*\(\) .*will always evaluate to.*$#' \ No newline at end of file From 1e3ea64f1acb18794c8a0630aa756748a3ae94ec Mon Sep 17 00:00:00 2001 From: Sam Mousa Date: Thu, 4 Sep 2025 16:37:31 +0200 Subject: [PATCH 5/6] chore: fix phpstan and phpcs errors --- .github/workflows/main.yml | 2 +- composer.json | 3 +- .../Util/Shared/InheritedAsserts.php | 166 ++++++++++++------ tests/Support/Data/DummyClass.php | 2 +- tests/unit/Codeception/Module/AssertsTest.php | 63 +++---- 5 files changed, 152 insertions(+), 84 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 366148c..0448c8a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,7 +35,7 @@ jobs: run: phpstan - name: Run PHPCS - run: phpcs --standard=PSR12 src + run: phpcs --standard=PSR12 src tests - name: Run test suite run: php vendor/bin/codecept run diff --git a/composer.json b/composer.json index 9030299..1de5946 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,8 @@ "require": { "php": "^8.2", "codeception/codeception": "*@dev", - "phpunit/phpunit": "^11.5 | ^12" + "phpunit/phpunit": "^11.5 | ^12", + "ext-dom": "*" }, "conflict": { "codeception/codeception": "<5.0" diff --git a/src/Codeception/Util/Shared/InheritedAsserts.php b/src/Codeception/Util/Shared/InheritedAsserts.php index ea098db..6e3f91d 100644 --- a/src/Codeception/Util/Shared/InheritedAsserts.php +++ b/src/Codeception/Util/Shared/InheritedAsserts.php @@ -46,8 +46,11 @@ protected function assertClassHasAttribute(string $attributeName, string $classN * Asserts that a class has a specified static attribute. * @param class-string $className */ - protected function assertClassHasStaticAttribute(string $attributeName, string $className, string $message = ''): void - { + protected function assertClassHasStaticAttribute( + string $attributeName, + string $className, + string $message = '' + ): void { trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); Assert::assertTrue(self::hasStaticAttribute($attributeName, $className), $message); @@ -67,8 +70,11 @@ protected function assertClassNotHasAttribute(string $attributeName, string $cla * Asserts that a class does not have a specified static attribute. * @param class-string $className */ - protected function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = ''): void - { + protected function assertClassNotHasStaticAttribute( + string $attributeName, + string $className, + string $message = '' + ): void { trigger_error(__FUNCTION__ . ' was removed from PHPUnit since PHPUnit 10', E_USER_DEPRECATED); Assert::assertFalse(self::hasStaticAttribute($attributeName, $className), $message); } @@ -93,11 +99,16 @@ protected function assertContainsEquals(mixed $needle, iterable $haystack, strin /** * Asserts that a haystack contains only values of a given type. - * @param 'array'|'bool'|'boolean'|'callable'|'double'|'float'|'int'|'integer'|'iterable'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'scalar'|'string'|class-string $type + * @param 'array'|'bool'|'boolean'|'callable'|'double'|'float'|'int'|'integer'|'iterable' + * |'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'scalar'|'string'|class-string $type * @param iterable $haystack */ - protected function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void - { + protected function assertContainsOnly( + string $type, + iterable $haystack, + ?bool $isNativeType = null, + string $message = '' + ): void { /** @phpstan-ignore-next-line */ Assert::assertContainsOnly($type, $haystack, $isNativeType, $message); } @@ -729,48 +740,65 @@ protected function assertJson(string $actualJson, string $message = ''): void /** * Asserts that two JSON files are equal. */ - protected function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void - { + protected function assertJsonFileEqualsJsonFile( + string $expectedFile, + string $actualFile, + string $message = '' + ): void { Assert::assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message); } - /** * Asserts that two JSON files are not equal. */ - protected function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void - { + protected function assertJsonFileNotEqualsJsonFile( + string $expectedFile, + string $actualFile, + string $message = '' + ): void { Assert::assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message); } /** * Asserts that the generated JSON encoded object and the content of the given file are equal. */ - protected function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void - { + protected function assertJsonStringEqualsJsonFile( + string $expectedFile, + string $actualJson, + string $message = '' + ): void { Assert::assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message); } /** * Asserts that two given JSON encoded objects or arrays are equal. */ - protected function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void - { + protected function assertJsonStringEqualsJsonString( + string $expectedJson, + string $actualJson, + string $message = '' + ): void { Assert::assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message); } /** * Asserts that the generated JSON encoded object and the content of the given file are not equal. */ - protected function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void - { + protected function assertJsonStringNotEqualsJsonFile( + string $expectedFile, + string $actualJson, + string $message = '' + ): void { Assert::assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message); } /** * Asserts that two given JSON encoded objects or arrays are not equal. */ - protected function assertJsonStringNotEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void - { + protected function assertJsonStringNotEqualsJsonString( + string $expectedJson, + string $actualJson, + string $message = '' + ): void { Assert::assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message); } @@ -826,11 +854,16 @@ protected function assertNotContains(mixed $needle, iterable $haystack, string $ /** * Asserts that a haystack does not contain only values of a given type. - * @param 'array'|'bool'|'boolean'|'callable'|'double'|'float'|'int'|'integer'|'iterable'|'null'|'numeric'|'object'|'real'|'resource'|'resource (closed)'|'scalar'|'string'|class-string $type + * @param 'array'|'bool'|'boolean'|'callable'|'double'|'float'|'int'|'integer'|'iterable'|'null' + * |'numeric'|'object'|'real'|'resource'|'resource (closed)'|'scalar'|'string'|class-string $type * @param iterable $haystack */ - protected function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void - { + protected function assertNotContainsOnly( + string $type, + iterable $haystack, + ?bool $isNativeType = null, + string $message = '' + ): void { /** @phpstan-ignore-next-line */ Assert::assertNotContainsOnly($type, $haystack, $isNativeType, $message); } @@ -957,8 +990,11 @@ protected function assertNotSame($expected, $actual, string $message = ''): void * @param \Countable|iterable $expected * @param \Countable|iterable $actual */ - protected function assertNotSameSize(\Countable|iterable $expected, \Countable|iterable $actual, string $message = ''): void - { + protected function assertNotSameSize( + \Countable|iterable $expected, + \Countable|iterable $actual, + string $message = '' + ): void { Assert::assertNotSameSize($expected, $actual, $message); } @@ -1035,8 +1071,11 @@ protected function assertSame(mixed $expected, mixed $actual, string $message = * @param \Countable|iterable $expected * @param \Countable|iterable $actual */ - protected function assertSameSize(\Countable|iterable $expected, \Countable|iterable $actual, string $message = ''): void - { + protected function assertSameSize( + \Countable|iterable $expected, + \Countable|iterable $actual, + string $message = '' + ): void { Assert::assertSameSize($expected, $actual, $message); } @@ -1045,8 +1084,11 @@ protected function assertStringContainsString(string $needle, string $haystack, Assert::assertStringContainsString($needle, $haystack, $message); } - protected function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void - { + protected function assertStringContainsStringIgnoringCase( + string $needle, + string $haystack, + string $message = '' + ): void { Assert::assertStringContainsStringIgnoringCase($needle, $haystack, $message); } @@ -1079,25 +1121,31 @@ protected function assertStringEqualsFile(string $expectedFile, string $actualSt /** * Asserts that the contents of a string is equal to the contents of a file (canonicalizing). */ - protected function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void - { + protected function assertStringEqualsFileCanonicalizing( + string $expectedFile, + string $actualString, + string $message = '' + ): void { Assert::assertStringEqualsFileCanonicalizing($expectedFile, $actualString, $message); } /** - * Asserts that the contents of a string is equal to the contents of a file (ignoring case). + * Asserts that a string matches a given format string. */ - protected function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void + protected function assertStringMatchesFormat(string $format, string $string, string $message = ''): void { - Assert::assertStringEqualsFileIgnoringCase($expectedFile, $actualString, $message); + Assert::assertStringMatchesFormat($format, $string, $message); } /** - * Asserts that a string matches a given format string. + * Asserts that the contents of a string is equal to the contents of a file (ignoring case). */ - protected function assertStringMatchesFormat(string $format, string $string, string $message = ''): void - { - Assert::assertStringMatchesFormat($format, $string, $message); + protected function assertStringEqualsFileIgnoringCase( + string $expectedFile, + string $actualString, + string $message = '' + ): void { + Assert::assertStringEqualsFileIgnoringCase($expectedFile, $actualString, $message); } /** @@ -1113,8 +1161,11 @@ protected function assertStringNotContainsString(string $needle, string $haystac Assert::assertStringNotContainsString($needle, $haystack, $message); } - protected function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void - { + protected function assertStringNotContainsStringIgnoringCase( + string $needle, + string $haystack, + string $message = '' + ): void { Assert::assertStringNotContainsStringIgnoringCase($needle, $haystack, $message); } @@ -1129,16 +1180,22 @@ protected function assertStringNotEqualsFile(string $expectedFile, string $actua /** * Asserts that the contents of a string is not equal to the contents of a file (canonicalizing). */ - protected function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void - { + protected function assertStringNotEqualsFileCanonicalizing( + string $expectedFile, + string $actualString, + string $message = '' + ): void { Assert::assertStringNotEqualsFileCanonicalizing($expectedFile, $actualString, $message); } /** * Asserts that the contents of a string is not equal to the contents of a file (ignoring case). */ - protected function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void - { + protected function assertStringNotEqualsFileIgnoringCase( + string $expectedFile, + string $actualString, + string $message = '' + ): void { Assert::assertStringNotEqualsFileIgnoringCase($expectedFile, $actualString, $message); } @@ -1217,16 +1274,22 @@ protected function assertXmlFileEqualsXmlFile(string $expectedFile, string $actu /** * Asserts that two XML files are not equal. */ - protected function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void - { + protected function assertXmlFileNotEqualsXmlFile( + string $expectedFile, + string $actualFile, + string $message = '' + ): void { Assert::assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message); } /** * Asserts that two XML documents are equal. */ - protected function assertXmlStringEqualsXmlFile(string $expectedFile, \DOMDocument|string $actualXml, string $message = ''): void - { + protected function assertXmlStringEqualsXmlFile( + string $expectedFile, + \DOMDocument|string $actualXml, + string $message = '' + ): void { if ($actualXml instanceof \DOMDocument) { $actualXml = $actualXml->saveXML(); if ($actualXml === false) { @@ -1239,8 +1302,11 @@ protected function assertXmlStringEqualsXmlFile(string $expectedFile, \DOMDocume /** * Asserts that two XML documents are equal. */ - protected function assertXmlStringEqualsXmlString(\DOMDocument|string $expectedXml, \DOMDocument|string $actualXml, string $message = ''): void - { + protected function assertXmlStringEqualsXmlString( + \DOMDocument|string $expectedXml, + \DOMDocument|string $actualXml, + string $message = '' + ): void { if ($actualXml instanceof \DOMDocument) { $actualXml = $actualXml->saveXML(); if ($actualXml === false) { diff --git a/tests/Support/Data/DummyClass.php b/tests/Support/Data/DummyClass.php index 036b162..6b9481c 100644 --- a/tests/Support/Data/DummyClass.php +++ b/tests/Support/Data/DummyClass.php @@ -15,4 +15,4 @@ class DummyClass * @phpstan-ignore-next-line */ private static int $staticFoo; -} \ No newline at end of file +} diff --git a/tests/unit/Codeception/Module/AssertsTest.php b/tests/unit/Codeception/Module/AssertsTest.php index 303244b..de0dbb2 100644 --- a/tests/unit/Codeception/Module/AssertsTest.php +++ b/tests/unit/Codeception/Module/AssertsTest.php @@ -14,7 +14,6 @@ use PHPUnit\Framework\Constraint\IsEqual; use PHPUnit\Framework\IncompleteTestError; use PHPUnit\Framework\SkippedTest; -use PHPUnit\Framework\SkippedTestError; use RuntimeException; use stdClass; @@ -22,9 +21,9 @@ final class AssertsTest extends TestCase { private Asserts $module; - public function _setUp(): void + protected function setUp(): void { - require_once codecept_data_dir().'/DummyClass.php'; + require_once codecept_data_dir() . '/DummyClass.php'; /** @var ModuleContainer $container */ $container = Stub::make(ModuleContainer::class); @@ -57,7 +56,7 @@ public function testPHPUnitAsserts(): void $this->module->assertContainsOnly(\Support\Data\DummyClass::class, [new \Support\Data\DummyClass(), new \Support\Data\DummyClass()]); $this->module->assertContainsOnlyInstancesOf(\Support\Data\DummyClass::class, [new \Support\Data\DummyClass(), new \Support\Data\DummyClass()]); $this->module->assertCount(3, [1, 2, 3]); - $this->module->assertDirectoryDoesNotExist(__DIR__.'notExist'); + $this->module->assertDirectoryDoesNotExist(__DIR__ . 'notExist'); $this->module->assertDirectoryExists(__DIR__); // assertDirectoryIsNotReadable // assertDirectoryIsNotWritable @@ -72,17 +71,17 @@ public function testPHPUnitAsserts(): void $this->module->assertEqualsWithDelta(1.0, 1.01, 0.1); $this->module->assertFalse(false); $this->module->assertFileDoesNotExist(__FILE__ . '.notExist'); - $this->module->assertFileEquals(codecept_data_dir().'/data1.txt', codecept_data_dir().'/data1.txt'); - $this->module->assertFileEqualsCanonicalizing(codecept_data_dir().'/data1.txt', codecept_data_dir().'/data1.txt'); - $this->module->assertFileEqualsIgnoringCase(codecept_data_dir().'/data1.txt', codecept_data_dir().'/data2.txt'); + $this->module->assertFileEquals(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data1.txt'); + $this->module->assertFileEqualsCanonicalizing(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data1.txt'); + $this->module->assertFileEqualsIgnoringCase(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data2.txt'); $this->module->assertFileExists(__FILE__); // assertFileIsNotReadable // assertFileIsNotWritable $this->module->assertFileIsReadable(__FILE__); $this->module->assertFileIsWritable(__FILE__); - $this->module->assertFileNotEquals(codecept_data_dir().'/data1.json', codecept_data_dir().'/data1.txt'); - $this->module->assertFileNotEqualsCanonicalizing(codecept_data_dir().'/data1.txt', codecept_data_dir().'/data3.txt'); - $this->module->assertFileNotEqualsIgnoringCase(codecept_data_dir().'/data1.txt', codecept_data_dir().'/data3.txt'); + $this->module->assertFileNotEquals(codecept_data_dir() . '/data1.json', codecept_data_dir() . '/data1.txt'); + $this->module->assertFileNotEqualsCanonicalizing(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data3.txt'); + $this->module->assertFileNotEqualsIgnoringCase(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data3.txt'); $this->module->assertFinite(2); $this->module->assertGreaterThan(5, 6); $this->module->assertGreaterThanOrEqual(5, 5); @@ -90,7 +89,8 @@ public function testPHPUnitAsserts(): void $this->module->assertInstanceOf('Exception', new Exception()); $this->module->assertIsArray([1, 2, 3]); $this->module->assertIsBool(true); - $this->module->assertIsCallable(function() {}); + $this->module->assertIsCallable(function () { + }); $closedResource = fopen('php://temp', 'r'); Assert::assertNotFalse($closedResource); fclose($closedResource); @@ -109,11 +109,12 @@ public function testPHPUnitAsserts(): void $this->module->assertIsNotIterable('test'); $this->module->assertIsNotNumeric(false); $this->module->assertIsNotObject(false); - $this->module->assertIsNotReadable(__FILE__.'.notExist'); + $this->module->assertIsNotReadable(__FILE__ . '.notExist'); $this->module->assertIsNotResource(false); - $this->module->assertIsNotScalar(function() {}); + $this->module->assertIsNotScalar(function () { + }); $this->module->assertIsNotString(false); - $this->module->assertIsNotWritable(__FILE__.'.notExist'); + $this->module->assertIsNotWritable(__FILE__ . '.notExist'); $this->module->assertIsNumeric('12.34'); $this->module->assertIsObject(new stdClass()); $this->module->assertIsReadable(__FILE__); @@ -122,11 +123,11 @@ public function testPHPUnitAsserts(): void $this->module->assertIsString('test'); $this->module->assertIsWritable(__FILE__); $this->module->assertJson('[]'); - $this->module->assertJsonFileEqualsJsonFile(codecept_data_dir().'/data1.json', codecept_data_dir().'/data1.json'); - $this->module->assertJsonFileNotEqualsJsonFile(codecept_data_dir().'/data1.json', codecept_data_dir().'/data2.json'); - $this->module->assertJsonStringEqualsJsonFile(codecept_data_dir().'/data1.json', '["foo", "bar"]'); + $this->module->assertJsonFileEqualsJsonFile(codecept_data_dir() . '/data1.json', codecept_data_dir() . '/data1.json'); + $this->module->assertJsonFileNotEqualsJsonFile(codecept_data_dir() . '/data1.json', codecept_data_dir() . '/data2.json'); + $this->module->assertJsonStringEqualsJsonFile(codecept_data_dir() . '/data1.json', '["foo", "bar"]'); $this->module->assertJsonStringEqualsJsonString('["foo", "bar"]', '[ "foo" , "bar" ]'); - $this->module->assertJsonStringNotEqualsJsonFile(codecept_data_dir().'/data1.json', '["bar", "foo"]'); + $this->module->assertJsonStringNotEqualsJsonFile(codecept_data_dir() . '/data1.json', '["bar", "foo"]'); $this->module->assertJsonStringNotEqualsJsonString('["foo", "bar"]', '["bar", "foo"]'); $this->module->assertLessThan(4, 3); $this->module->assertLessThanOrEqual(3, 3); @@ -161,34 +162,34 @@ public function testPHPUnitAsserts(): void $this->module->assertStringContainsStringIgnoringCase('bar', 'FooBar'); $this->module->assertStringEndsNotWith('fo', 'foo'); $this->module->assertStringEndsWith('oo', 'foo'); - $this->module->assertStringEqualsFile(codecept_data_dir().'/data1.txt', 'foo bar foo'); - $this->module->assertStringEqualsFileCanonicalizing(codecept_data_dir().'/data1.txt', 'foo bar foo'); - $this->module->assertStringEqualsFileIgnoringCase(codecept_data_dir().'/data1.txt', 'foo bAr foo'); + $this->module->assertStringEqualsFile(codecept_data_dir() . '/data1.txt', 'foo bar foo'); + $this->module->assertStringEqualsFileCanonicalizing(codecept_data_dir() . '/data1.txt', 'foo bar foo'); + $this->module->assertStringEqualsFileIgnoringCase(codecept_data_dir() . '/data1.txt', 'foo bAr foo'); $this->module->assertStringMatchesFormat('*%s*', '***'); - $this->module->assertStringMatchesFormatFile(codecept_data_dir().'/expectedFileFormat.txt', "FOO\n"); + $this->module->assertStringMatchesFormatFile(codecept_data_dir() . '/expectedFileFormat.txt', "FOO\n"); $this->module->assertStringNotContainsString('baz', 'foobar'); $this->module->assertStringNotContainsStringIgnoringCase('baz', 'FooBar'); - $this->module->assertStringNotEqualsFile(codecept_data_dir().'/data2.txt', 'foo bar foo'); - $this->module->assertStringNotEqualsFileCanonicalizing(codecept_data_dir().'/data3.txt', 'foo bar foo'); - $this->module->assertStringNotEqualsFileIgnoringCase(codecept_data_dir().'/data3.txt', 'foo bar foo'); + $this->module->assertStringNotEqualsFile(codecept_data_dir() . '/data2.txt', 'foo bar foo'); + $this->module->assertStringNotEqualsFileCanonicalizing(codecept_data_dir() . '/data3.txt', 'foo bar foo'); + $this->module->assertStringNotEqualsFileIgnoringCase(codecept_data_dir() . '/data3.txt', 'foo bar foo'); $this->module->assertStringNotMatchesFormat('*%s*', '**'); - $this->module->assertStringNotMatchesFormatFile(codecept_data_dir().'/expectedFileFormat.txt', "FO"); + $this->module->assertStringNotMatchesFormatFile(codecept_data_dir() . '/expectedFileFormat.txt', "FO"); $this->module->assertStringStartsNotWith('ba', 'foo'); $this->module->assertStringStartsWith('fo', 'foo'); $this->module->assertThat(4, new IsEqual(4)); $this->module->assertTrue(true); - $this->module->assertXmlFileEqualsXmlFile(codecept_data_dir().'/data1.xml', codecept_data_dir().'/data1.xml'); - $this->module->assertXmlFileNotEqualsXmlFile(codecept_data_dir().'/data1.xml', codecept_data_dir().'/data2.xml'); - $this->module->assertXmlStringEqualsXmlFile(codecept_data_dir().'/data1.xml', ' foo '); + $this->module->assertXmlFileEqualsXmlFile(codecept_data_dir() . '/data1.xml', codecept_data_dir() . '/data1.xml'); + $this->module->assertXmlFileNotEqualsXmlFile(codecept_data_dir() . '/data1.xml', codecept_data_dir() . '/data2.xml'); + $this->module->assertXmlStringEqualsXmlFile(codecept_data_dir() . '/data1.xml', ' foo '); $this->module->assertXmlStringEqualsXmlString('foo', ' foo '); - $this->module->assertXmlStringNotEqualsXmlFile(codecept_data_dir().'/data1.xml', 'bar'); + $this->module->assertXmlStringNotEqualsXmlFile(codecept_data_dir() . '/data1.xml', 'bar'); $this->module->assertXmlStringNotEqualsXmlString('foo', 'bar'); } public function testExceptions(): void { $this->module->expectThrowable('Exception', function () { - throw new Exception; + throw new Exception(); }); $this->module->expectThrowable(new Exception('here'), function () { throw new Exception('here'); From fa054e78e155211c5a3442ec2312a71b97a00f40 Mon Sep 17 00:00:00 2001 From: Sam Mousa Date: Thu, 4 Sep 2025 16:40:32 +0200 Subject: [PATCH 6/6] chore: more cs fixes --- tests/unit/Codeception/Module/AssertsTest.php | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/tests/unit/Codeception/Module/AssertsTest.php b/tests/unit/Codeception/Module/AssertsTest.php index de0dbb2..2582d34 100644 --- a/tests/unit/Codeception/Module/AssertsTest.php +++ b/tests/unit/Codeception/Module/AssertsTest.php @@ -16,6 +16,7 @@ use PHPUnit\Framework\SkippedTest; use RuntimeException; use stdClass; +use Support\Data\DummyClass; final class AssertsTest extends TestCase { @@ -45,16 +46,17 @@ public function testCodeceptionAsserts(): void public function testPHPUnitAsserts(): void { + $dir = codecept_data_dir(); $this->module->assertArrayHasKey('one', ['one' => 1, 'two' => 2]); $this->module->assertArrayNotHasKey('three', ['one' => 1, 'two' => 2]); - $this->module->assertClassHasAttribute('foo', \Support\Data\DummyClass::class); - $this->module->assertClassHasStaticAttribute('staticFoo', \Support\Data\DummyClass::class); - $this->module->assertClassNotHasAttribute('bar', \Support\Data\DummyClass::class); - $this->module->assertClassNotHasStaticAttribute('staticBar', \Support\Data\DummyClass::class); + $this->module->assertClassHasAttribute('foo', DummyClass::class); + $this->module->assertClassHasStaticAttribute('staticFoo', DummyClass::class); + $this->module->assertClassNotHasAttribute('bar', DummyClass::class); + $this->module->assertClassNotHasStaticAttribute('staticBar', DummyClass::class); $this->module->assertContains(1, [1, 2]); $this->module->assertContainsEquals(2, [1, 2]); - $this->module->assertContainsOnly(\Support\Data\DummyClass::class, [new \Support\Data\DummyClass(), new \Support\Data\DummyClass()]); - $this->module->assertContainsOnlyInstancesOf(\Support\Data\DummyClass::class, [new \Support\Data\DummyClass(), new \Support\Data\DummyClass()]); + $this->module->assertContainsOnly(DummyClass::class, [new DummyClass(), new DummyClass()]); + $this->module->assertContainsOnlyInstancesOf(DummyClass::class, [new DummyClass(), new DummyClass()]); $this->module->assertCount(3, [1, 2, 3]); $this->module->assertDirectoryDoesNotExist(__DIR__ . 'notExist'); $this->module->assertDirectoryExists(__DIR__); @@ -71,17 +73,17 @@ public function testPHPUnitAsserts(): void $this->module->assertEqualsWithDelta(1.0, 1.01, 0.1); $this->module->assertFalse(false); $this->module->assertFileDoesNotExist(__FILE__ . '.notExist'); - $this->module->assertFileEquals(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data1.txt'); - $this->module->assertFileEqualsCanonicalizing(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data1.txt'); - $this->module->assertFileEqualsIgnoringCase(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data2.txt'); + $this->module->assertFileEquals($dir . '/data1.txt', $dir . '/data1.txt'); + $this->module->assertFileEqualsCanonicalizing($dir . '/data1.txt', $dir . '/data1.txt'); + $this->module->assertFileEqualsIgnoringCase($dir . '/data1.txt', $dir . '/data2.txt'); $this->module->assertFileExists(__FILE__); // assertFileIsNotReadable // assertFileIsNotWritable $this->module->assertFileIsReadable(__FILE__); $this->module->assertFileIsWritable(__FILE__); - $this->module->assertFileNotEquals(codecept_data_dir() . '/data1.json', codecept_data_dir() . '/data1.txt'); - $this->module->assertFileNotEqualsCanonicalizing(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data3.txt'); - $this->module->assertFileNotEqualsIgnoringCase(codecept_data_dir() . '/data1.txt', codecept_data_dir() . '/data3.txt'); + $this->module->assertFileNotEquals($dir . '/data1.json', $dir . '/data1.txt'); + $this->module->assertFileNotEqualsCanonicalizing($dir . '/data1.txt', $dir . '/data3.txt'); + $this->module->assertFileNotEqualsIgnoringCase($dir . '/data1.txt', $dir . '/data3.txt'); $this->module->assertFinite(2); $this->module->assertGreaterThan(5, 6); $this->module->assertGreaterThanOrEqual(5, 5); @@ -123,18 +125,18 @@ public function testPHPUnitAsserts(): void $this->module->assertIsString('test'); $this->module->assertIsWritable(__FILE__); $this->module->assertJson('[]'); - $this->module->assertJsonFileEqualsJsonFile(codecept_data_dir() . '/data1.json', codecept_data_dir() . '/data1.json'); - $this->module->assertJsonFileNotEqualsJsonFile(codecept_data_dir() . '/data1.json', codecept_data_dir() . '/data2.json'); - $this->module->assertJsonStringEqualsJsonFile(codecept_data_dir() . '/data1.json', '["foo", "bar"]'); + $this->module->assertJsonFileEqualsJsonFile($dir . '/data1.json', $dir . '/data1.json'); + $this->module->assertJsonFileNotEqualsJsonFile($dir . '/data1.json', $dir . '/data2.json'); + $this->module->assertJsonStringEqualsJsonFile($dir . '/data1.json', '["foo", "bar"]'); $this->module->assertJsonStringEqualsJsonString('["foo", "bar"]', '[ "foo" , "bar" ]'); - $this->module->assertJsonStringNotEqualsJsonFile(codecept_data_dir() . '/data1.json', '["bar", "foo"]'); + $this->module->assertJsonStringNotEqualsJsonFile($dir . '/data1.json', '["bar", "foo"]'); $this->module->assertJsonStringNotEqualsJsonString('["foo", "bar"]', '["bar", "foo"]'); $this->module->assertLessThan(4, 3); $this->module->assertLessThanOrEqual(3, 3); $this->module->assertMatchesRegularExpression('/^[\d]$/', '1'); $this->module->assertNan(sqrt(-1)); $this->module->assertNotContains('three', ['one', 'two']); - $this->module->assertNotContainsOnly(\Support\Data\DummyClass::class, [new \Support\Data\DummyClass(), new Exception()]); + $this->module->assertNotContainsOnly(DummyClass::class, [new DummyClass(), new Exception()]); $this->module->assertNotCount(1, ['one', 'two']); $this->module->assertNotEmpty([1]); $this->module->assertNotEquals(true, false); @@ -154,35 +156,35 @@ public function testPHPUnitAsserts(): void $this->module->assertNotTrue(null); $this->module->assertNotTrue('foo'); $this->module->assertNull(null); - $this->module->assertObjectHasAttribute('foo', new \Support\Data\DummyClass()); - $this->module->assertObjectNotHasAttribute('bar', new \Support\Data\DummyClass()); + $this->module->assertObjectHasAttribute('foo', new DummyClass()); + $this->module->assertObjectNotHasAttribute('bar', new DummyClass()); $this->module->assertSame(1, 1); $this->module->assertSameSize([1, 2, 3], [1, 2, 3]); $this->module->assertStringContainsString('bar', 'foobar'); $this->module->assertStringContainsStringIgnoringCase('bar', 'FooBar'); $this->module->assertStringEndsNotWith('fo', 'foo'); $this->module->assertStringEndsWith('oo', 'foo'); - $this->module->assertStringEqualsFile(codecept_data_dir() . '/data1.txt', 'foo bar foo'); - $this->module->assertStringEqualsFileCanonicalizing(codecept_data_dir() . '/data1.txt', 'foo bar foo'); - $this->module->assertStringEqualsFileIgnoringCase(codecept_data_dir() . '/data1.txt', 'foo bAr foo'); + $this->module->assertStringEqualsFile($dir . '/data1.txt', 'foo bar foo'); + $this->module->assertStringEqualsFileCanonicalizing($dir . '/data1.txt', 'foo bar foo'); + $this->module->assertStringEqualsFileIgnoringCase($dir . '/data1.txt', 'foo bAr foo'); $this->module->assertStringMatchesFormat('*%s*', '***'); - $this->module->assertStringMatchesFormatFile(codecept_data_dir() . '/expectedFileFormat.txt', "FOO\n"); + $this->module->assertStringMatchesFormatFile($dir . '/expectedFileFormat.txt', "FOO\n"); $this->module->assertStringNotContainsString('baz', 'foobar'); $this->module->assertStringNotContainsStringIgnoringCase('baz', 'FooBar'); - $this->module->assertStringNotEqualsFile(codecept_data_dir() . '/data2.txt', 'foo bar foo'); - $this->module->assertStringNotEqualsFileCanonicalizing(codecept_data_dir() . '/data3.txt', 'foo bar foo'); - $this->module->assertStringNotEqualsFileIgnoringCase(codecept_data_dir() . '/data3.txt', 'foo bar foo'); + $this->module->assertStringNotEqualsFile($dir . '/data2.txt', 'foo bar foo'); + $this->module->assertStringNotEqualsFileCanonicalizing($dir . '/data3.txt', 'foo bar foo'); + $this->module->assertStringNotEqualsFileIgnoringCase($dir . '/data3.txt', 'foo bar foo'); $this->module->assertStringNotMatchesFormat('*%s*', '**'); - $this->module->assertStringNotMatchesFormatFile(codecept_data_dir() . '/expectedFileFormat.txt', "FO"); + $this->module->assertStringNotMatchesFormatFile($dir . '/expectedFileFormat.txt', "FO"); $this->module->assertStringStartsNotWith('ba', 'foo'); $this->module->assertStringStartsWith('fo', 'foo'); $this->module->assertThat(4, new IsEqual(4)); $this->module->assertTrue(true); - $this->module->assertXmlFileEqualsXmlFile(codecept_data_dir() . '/data1.xml', codecept_data_dir() . '/data1.xml'); - $this->module->assertXmlFileNotEqualsXmlFile(codecept_data_dir() . '/data1.xml', codecept_data_dir() . '/data2.xml'); - $this->module->assertXmlStringEqualsXmlFile(codecept_data_dir() . '/data1.xml', ' foo '); + $this->module->assertXmlFileEqualsXmlFile($dir . '/data1.xml', $dir . '/data1.xml'); + $this->module->assertXmlFileNotEqualsXmlFile($dir . '/data1.xml', $dir . '/data2.xml'); + $this->module->assertXmlStringEqualsXmlFile($dir . '/data1.xml', ' foo '); $this->module->assertXmlStringEqualsXmlString('foo', ' foo '); - $this->module->assertXmlStringNotEqualsXmlFile(codecept_data_dir() . '/data1.xml', 'bar'); + $this->module->assertXmlStringNotEqualsXmlFile($dir . '/data1.xml', 'bar'); $this->module->assertXmlStringNotEqualsXmlString('foo', 'bar'); }