From acad8e7dc8cbc7e1e0a5dbcc10722165d01cc37a Mon Sep 17 00:00:00 2001 From: TavoNiievez Date: Sun, 17 Oct 2021 12:26:04 -0500 Subject: [PATCH 01/13] Support for Codeception 5 --- .github/workflows/main.yml | 2 +- composer.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8ab4cff..91c9599 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - php: [7.4, 8.0, 8.1] + php: [8.0, 8.1] steps: - name: Checkout code diff --git a/composer.json b/composer.json index e401645..a2a09a0 100644 --- a/composer.json +++ b/composer.json @@ -17,14 +17,14 @@ "homepage": "https://medium.com/@ganieves" } ], - "minimum-stability": "RC", + "minimum-stability": "dev", "require": { - "php": "^7.4 | ^8.0", + "php": "^8.0", "codeception/lib-asserts": "^2.0", - "codeception/codeception": "^4.1 | *@dev" + "codeception/codeception": "^5.0.0-alpha1" }, "conflict": { - "codeception/codeception": "<4.1" + "codeception/codeception": "<5.0" }, "autoload": { "classmap": [ From b9286242cbacd09f48d3fb0456874bba3b293ba0 Mon Sep 17 00:00:00 2001 From: Dan Barrett Date: Sat, 12 Feb 2022 14:18:33 +1100 Subject: [PATCH 02/13] Normalise and cleanup of composer.json --- composer.json | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index a2a09a0..09c4fba 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,13 @@ { "name": "codeception/module-asserts", "description": "Codeception module containing various assertions", - "keywords": [ "codeception", "asserts", "assertions" ], - "homepage": "https://codeception.com/", - "type": "library", "license": "MIT", + "type": "library", + "keywords": [ + "codeception", + "asserts", + "assertions" + ], "authors": [ { "name": "Michael Bodnarchuk" @@ -17,15 +20,16 @@ "homepage": "https://medium.com/@ganieves" } ], - "minimum-stability": "dev", + "homepage": "https://codeception.com/", "require": { "php": "^8.0", - "codeception/lib-asserts": "^2.0", - "codeception/codeception": "^5.0.0-alpha1" + "codeception/codeception": "dev-5.0-interfaces as 5.0.0", + "codeception/lib-asserts": "^2.0" }, "conflict": { "codeception/codeception": "<5.0" }, + "minimum-stability": "dev", "autoload": { "classmap": [ "src/" From 190d9ff139638055e84cc2bb0ff47f70732ab051 Mon Sep 17 00:00:00 2001 From: Dan Barrett Date: Sat, 12 Feb 2022 14:18:48 +1100 Subject: [PATCH 03/13] Removed redundant line in .gitattributes file --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 87f3679..2d44cfe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,6 +2,5 @@ /tests export-ignore /.gitattributes export-ignore /.gitignore export-ignore -/Robofile.php export-ignore /*.md export-ignore /*.yml export-ignore From 0c83f4ee00b8ae7bfebeda358858e13167d84d5f Mon Sep 17 00:00:00 2001 From: Dan Barrett Date: Sat, 12 Feb 2022 14:19:05 +1100 Subject: [PATCH 04/13] Improved support for Codeception 5/PHP 8 --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index df23ddd..6abd2f9 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ A Codeception module containing various assertions. ## Requirements -* `PHP 7.4` or higher. +* `PHP 8.0` or higher. ## Installation From 4beb1478e6fde9e6fc8096d6e8addea53f45f145 Mon Sep 17 00:00:00 2001 From: Gintautas Miselis Date: Wed, 16 Feb 2022 21:45:48 +0200 Subject: [PATCH 05/13] Fix Codeception version constraint --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 09c4fba..7f24489 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "homepage": "https://codeception.com/", "require": { "php": "^8.0", - "codeception/codeception": "dev-5.0-interfaces as 5.0.0", + "codeception/codeception": "*@dev", "codeception/lib-asserts": "^2.0" }, "conflict": { From 536ec69ffd98d67d66035b7bbea68cd802e641c6 Mon Sep 17 00:00:00 2001 From: Gintautas Miselis Date: Fri, 3 Feb 2023 21:41:23 +0200 Subject: [PATCH 06/13] Run tests on PHP 8.2 --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 91c9599..cefff8d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,11 +8,11 @@ jobs: strategy: matrix: - php: [8.0, 8.1] + php: [8.0, 8.1, 8.2] steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 From 823c4ba327378a2b21929a89cc50e2ec33450b71 Mon Sep 17 00:00:00 2001 From: Dieter Beck Date: Wed, 2 Apr 2025 09:12:24 +0200 Subject: [PATCH 07/13] Test against PHP 8.3 + 8.4, drop PHP 8.0 (#28) * Test against PHP 8.3 + 8.4 * Bump actions/checkout dependency * PHP 8.4: Do not use the deprecated constant E_STRICT * Drop support for PHP 8.0 --- .github/workflows/main.yml | 4 ++-- composer.json | 2 +- readme.md | 2 +- tests/unit.suite.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cefff8d..d273d49 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,11 +8,11 @@ jobs: strategy: matrix: - php: [8.0, 8.1, 8.2] + php: [8.1, 8.2, 8.3, 8.4] steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/composer.json b/composer.json index 7f24489..5370628 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ ], "homepage": "https://codeception.com/", "require": { - "php": "^8.0", + "php": "^8.1", "codeception/codeception": "*@dev", "codeception/lib-asserts": "^2.0" }, diff --git a/readme.md b/readme.md index 6abd2f9..0a4ab33 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ A Codeception module containing various assertions. ## Requirements -* `PHP 8.0` or higher. +* `PHP 8.1` or higher. ## Installation diff --git a/tests/unit.suite.yml b/tests/unit.suite.yml index 5399cf4..1c448f5 100644 --- a/tests/unit.suite.yml +++ b/tests/unit.suite.yml @@ -1,5 +1,5 @@ # Codeception Test Suite Configuration # suite for unit (internal) tests. -error_level: "E_ALL | E_STRICT" +error_level: "E_ALL" class_name: UnitTester From c58281f3d741599c81676bcb92996cf1e22d9ffd Mon Sep 17 00:00:00 2001 From: Dieter Beck Date: Thu, 24 Apr 2025 19:18:25 +0200 Subject: [PATCH 08/13] Add missing tests (#29) --- tests/_data/DummyClass.php | 10 + tests/_data/data1.json | 1 + tests/_data/data1.txt | 1 + tests/_data/data1.xml | 1 + tests/_data/data2.json | 1 + tests/_data/data2.txt | 1 + tests/_data/data2.xml | 1 + tests/_data/data3.txt | 1 + tests/_data/expectedFileFormat.txt | 1 + tests/unit/Codeception/Module/AssertsTest.php | 184 ++++++++++-------- 10 files changed, 126 insertions(+), 76 deletions(-) create mode 100644 tests/_data/DummyClass.php create mode 100644 tests/_data/data1.json create mode 100644 tests/_data/data1.txt create mode 100644 tests/_data/data1.xml create mode 100644 tests/_data/data2.json create mode 100644 tests/_data/data2.txt create mode 100644 tests/_data/data2.xml create mode 100644 tests/_data/data3.txt create mode 100644 tests/_data/expectedFileFormat.txt diff --git a/tests/_data/DummyClass.php b/tests/_data/DummyClass.php new file mode 100644 index 0000000..85d2a2c --- /dev/null +++ b/tests/_data/DummyClass.php @@ -0,0 +1,10 @@ +foo \ No newline at end of file diff --git a/tests/_data/data2.json b/tests/_data/data2.json new file mode 100644 index 0000000..0d0c31f --- /dev/null +++ b/tests/_data/data2.json @@ -0,0 +1 @@ +["bar", "foo"] \ No newline at end of file diff --git a/tests/_data/data2.txt b/tests/_data/data2.txt new file mode 100644 index 0000000..1b4afc6 --- /dev/null +++ b/tests/_data/data2.txt @@ -0,0 +1 @@ +Foo bar foo \ No newline at end of file diff --git a/tests/_data/data2.xml b/tests/_data/data2.xml new file mode 100644 index 0000000..954791b --- /dev/null +++ b/tests/_data/data2.xml @@ -0,0 +1 @@ +bar \ No newline at end of file diff --git a/tests/_data/data3.txt b/tests/_data/data3.txt new file mode 100644 index 0000000..5bbe253 --- /dev/null +++ b/tests/_data/data3.txt @@ -0,0 +1 @@ +bar foo foo \ No newline at end of file diff --git a/tests/_data/expectedFileFormat.txt b/tests/_data/expectedFileFormat.txt new file mode 100644 index 0000000..d96c7ef --- /dev/null +++ b/tests/_data/expectedFileFormat.txt @@ -0,0 +1 @@ +FOO \ No newline at end of file diff --git a/tests/unit/Codeception/Module/AssertsTest.php b/tests/unit/Codeception/Module/AssertsTest.php index 21b3c76..11d833f 100644 --- a/tests/unit/Codeception/Module/AssertsTest.php +++ b/tests/unit/Codeception/Module/AssertsTest.php @@ -10,6 +10,9 @@ use Codeception\Stub; use Exception; use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Constraint\IsEqual; +use PHPUnit\Framework\IncompleteTestError; +use PHPUnit\Framework\SkippedWithMessageException; use RuntimeException; use stdClass; @@ -19,6 +22,8 @@ final class AssertsTest extends TestCase public function _setUp() { + require_once codecept_data_dir().'/DummyClass.php'; + /** @var ModuleContainer $container */ $container = Stub::make(ModuleContainer::class); $this->module = new Asserts($container); @@ -27,151 +32,154 @@ public function _setUp() public function testCodeceptionAsserts() { $this->module->assertFileNotExists(__FILE__ . '.notExist'); - // assertGreaterOrEquals - // assertIsEmpty - // assertLessOrEquals + $this->module->assertGreaterOrEquals(2, 2); + $this->module->assertGreaterOrEquals(2, 3); + $this->module->assertIsEmpty([]); + $this->module->assertLessOrEquals(2, 1); + $this->module->assertLessOrEquals(2, 2); $this->module->assertNotRegExp('/^[a-z]$/', '1'); $this->module->assertRegExp('/^[\d]$/', '1'); - // assertThatItsNot + $this->module->assertThatItsNot(3, new IsEqual(4)); } public function testPHPUnitAsserts() { $this->module->assertArrayHasKey('one', ['one' => 1, 'two' => 2]); - // assertArrayNotHasKey - // assertClassHasAttribute - // assertClassHasStaticAttribute - // assertClassNotHasAttribute - // assertClassNotHasStaticAttribute + $this->module->assertArrayNotHasKey('three', ['one' => 1, 'two' => 2]); + $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]); - // assertContainsEquals - // assertContainsOnly - // assertContainsOnlyInstancesOf + $this->module->assertContainsEquals(2, [1, 2]); + $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]); - // assertDirectoryDoesNotExist - // assertDirectoryExists + $this->module->assertDirectoryDoesNotExist(__DIR__.'notExist'); + $this->module->assertDirectoryExists(__DIR__); // assertDirectoryIsNotReadable // assertDirectoryIsNotWritable - // assertDirectoryIsReadable - // assertDirectoryIsWritable + $this->module->assertDirectoryIsReadable(__DIR__); + $this->module->assertDirectoryIsWritable(__DIR__); $this->module->assertDoesNotMatchRegularExpression('/^[a-z]$/', '1'); $this->module->assertEmpty([]); + $this->module->assertEmpty(0); $this->module->assertEquals(1, 1); $this->module->assertEqualsCanonicalizing([3, 2, 1], [1, 2, 3]); $this->module->assertEqualsIgnoringCase('foo', 'FOO'); $this->module->assertEqualsWithDelta(1.0, 1.01, 0.1); $this->module->assertFalse(false); $this->module->assertFileDoesNotExist(__FILE__ . '.notExist'); - // assertFileEquals - // assertFileEqualsCanonicalizing - // assertFileEqualsIgnoringCase + $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 - // assertFileIsReadable - // assertFileIsWritable - // assertFileNotEquals - // assertFileNotEqualsCanonicalizing - // assertFileNotEqualsIgnoringCase - // assertFinite - // assertGreaterThan - // assertGreaterThanOrEqual - // assertInfinite + $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->assertFinite(2); + $this->module->assertGreaterThan(5, 6); + $this->module->assertGreaterThanOrEqual(5, 5); + $this->module->assertInfinite(1e308 * 2); $this->module->assertInstanceOf('Exception', new Exception()); $this->module->assertIsArray([1, 2, 3]); $this->module->assertIsBool(true); $this->module->assertIsCallable(function() {}); - // assertIsClosedResource + $closedResource = fopen(__FILE__, 'r'); + fclose($closedResource); + $this->module->assertIsClosedResource($closedResource); $this->module->assertIsFloat(1.2); $this->module->assertIsInt(2); - // assertIsIterable + $this->module->assertIsIterable([]); $this->module->assertIsNotArray(false); $this->module->assertIsNotBool([1, 2, 3]); $this->module->assertIsNotCallable('test'); - // assertIsNotClosedResource + $openendResource = fopen(__FILE__, 'r'); + $this->module->assertIsNotClosedResource($openendResource); $this->module->assertIsNotFloat(false); $this->module->assertIsNotInt(false); - // assertIsNotIterable + $this->module->assertIsNotIterable('test'); $this->module->assertIsNotNumeric(false); $this->module->assertIsNotObject(false); - // assertIsNotReadable + $this->module->assertIsNotReadable(__FILE__.'.notExist'); $this->module->assertIsNotResource(false); $this->module->assertIsNotScalar(function() {}); $this->module->assertIsNotString(false); - // assertIsNotWritable + $this->module->assertIsNotWritable(__FILE__.'.notExist'); $this->module->assertIsNumeric('12.34'); $this->module->assertIsObject(new stdClass()); - // assertIsReadable + $this->module->assertIsReadable(__FILE__); $this->module->assertIsResource(fopen(__FILE__, 'r')); $this->module->assertIsScalar('test'); $this->module->assertIsString('test'); - // assertIsWritable - // assertJson - // assertJsonFileEqualsJsonFile - // assertJsonFileNotEqualsJsonFile - // assertJsonStringEqualsJsonFile - // assertJsonStringEqualsJsonString - // assertJsonStringNotEqualsJsonFile - // assertJsonStringNotEqualsJsonString - // assertLessThan - // assertLessThanOrEqual + $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->assertJsonStringEqualsJsonString('["foo", "bar"]', '[ "foo" , "bar" ]'); + $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); $this->module->assertMatchesRegularExpression('/^[\d]$/', '1'); - // assertNan - // assertNotContains - // assertNotContainsEquals - // assertNotContainsOnly - // assertNotCount + $this->module->assertNan(sqrt(-1)); + $this->module->assertNotContains('three', ['one', 'two']); + $this->module->assertNotContainsEquals(3, [1, 2]); + $this->module->assertNotContainsOnly(\DummyClass::class, [new \DummyClass(), new Exception()]); + $this->module->assertNotCount(1, ['one', 'two']); $this->module->assertNotEmpty([1]); - // assertNotEquals + $this->module->assertNotEquals(true, false); $this->module->assertNotEqualsCanonicalizing([3, 2, 1], [2, 3, 0, 1]); $this->module->assertNotEqualsIgnoringCase('foo', 'BAR'); $this->module->assertNotEqualsWithDelta(1.0, 1.5, 0.1); $this->module->assertNotFalse(true); $this->module->assertNotFalse(null); $this->module->assertNotFalse('foo'); - // assertNotInstanceOf + $this->module->assertNotInstanceOf(RuntimeException::class, new Exception()); $this->module->assertNotNull(''); $this->module->assertNotNull(false); $this->module->assertNotNull(0); $this->module->assertNotSame(1, '1'); - // assertNotSameSize + $this->module->assertNotSameSize([1, 2, 3], [1, 1, 2, 3]); $this->module->assertNotTrue(false); $this->module->assertNotTrue(null); $this->module->assertNotTrue('foo'); $this->module->assertNull(null); - // assertObjectHasAttribute - // assertObjectNotHasAttribute + $this->module->assertObjectHasAttribute('foo', new \DummyClass()); + $this->module->assertObjectNotHasAttribute('bar', new \DummyClass()); $this->module->assertSame(1, 1); - // assertSameSize + $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'); - // assertStringEqualsFile - // assertStringEqualsFileCanonicalizing - // assertStringEqualsFileIgnoringCase - // assertStringMatchesFormat - // assertStringMatchesFormatFile + $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->assertStringNotContainsString('baz', 'foobar'); $this->module->assertStringNotContainsStringIgnoringCase('baz', 'FooBar'); - // assertStringNotEqualsFile - // assertStringNotEqualsFileCanonicalizing - // assertStringNotEqualsFileIgnoringCase - // assertStringNotMatchesFormat - // assertStringNotMatchesFormatFile + $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->assertStringStartsNotWith('ba', 'foo'); $this->module->assertStringStartsWith('fo', 'foo'); - // assertThat + $this->module->assertThat(4, new IsEqual(4)); $this->module->assertTrue(true); - // assertXmlFileEqualsXmlFile - // assertXmlFileNotEqualsXmlFile - // assertXmlStringEqualsXmlFile - // assertXmlStringEqualsXmlString - // assertXmlStringNotEqualsXmlFile - // assertXmlStringNotEqualsXmlString - // fail - // markTestIncomplete - // markTestSkipped + $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->assertXmlStringNotEqualsXmlString('foo', 'bar'); } public function testExceptions() @@ -253,4 +261,28 @@ public function testExpectThrowableFailOnNothingCaught() $this->module->expectThrowable(RuntimeException::class, function () { }); } + + public function testFail() + { + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('foobar'); + + $this->module->fail('foobar'); + } + + public function testMarkTestIncomplete() + { + $this->expectException(IncompleteTestError::class); + $this->expectExceptionMessage('foobar'); + + $this->module->markTestIncomplete('foobar'); + } + + public function testMarkTestSkipped() + { + $this->expectException(SkippedWithMessageException::class); + $this->expectExceptionMessage('foobar'); + + $this->module->markTestSkipped('foobar'); + } } From a49935274fa21507238cff58c78c71c52377c0f0 Mon Sep 17 00:00:00 2001 From: Dieter Beck Date: Fri, 25 Apr 2025 06:37:21 +0200 Subject: [PATCH 09/13] Use version of lib-asserts which fixes the assertions for newer phpunit versions (#30) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5370628..b0f7f69 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "require": { "php": "^8.1", "codeception/codeception": "*@dev", - "codeception/lib-asserts": "^2.0" + "codeception/lib-asserts": "^2.2" }, "conflict": { "codeception/codeception": "<5.0" From 70c2f6d1ee27b66134634f064d19a183ce6ac30d Mon Sep 17 00:00:00 2001 From: TavoNiievez Date: Thu, 1 May 2025 21:10:29 -0500 Subject: [PATCH 10/13] Update codebase to PHP 8.2 --- .github/workflows/main.yml | 2 +- composer.json | 2 +- readme.md | 2 +- src/Codeception/Module/Asserts.php | 13 +++++++------ 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d273d49..79314d3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - php: [8.1, 8.2, 8.3, 8.4] + php: [8.2, 8.3, 8.4] steps: - name: Checkout code diff --git a/composer.json b/composer.json index b0f7f69..3f7cd00 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ ], "homepage": "https://codeception.com/", "require": { - "php": "^8.1", + "php": "^8.2", "codeception/codeception": "*@dev", "codeception/lib-asserts": "^2.2" }, diff --git a/readme.md b/readme.md index 0a4ab33..aadb37e 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ A Codeception module containing various assertions. ## Requirements -* `PHP 8.1` or higher. +* `PHP 8.2` or higher. ## Installation diff --git a/src/Codeception/Module/Asserts.php b/src/Codeception/Module/Asserts.php index 869faa3..707db6a 100644 --- a/src/Codeception/Module/Asserts.php +++ b/src/Codeception/Module/Asserts.php @@ -4,6 +4,9 @@ namespace Codeception\Module; +use Throwable; +use function get_debug_type; + /** * Special module for using asserts in your tests. */ @@ -31,10 +34,8 @@ class Asserts extends AbstractAsserts * $this->doSomethingBad(); * }); * ``` - * - * @param \Throwable|string $throwable */ - public function expectThrowable($throwable, callable $callback): void + public function expectThrowable(string|Throwable $throwable, callable $callback): void { if (is_object($throwable)) { $class = get_class($throwable); @@ -48,7 +49,7 @@ public function expectThrowable($throwable, callable $callback): void try { $callback(); - } catch (\Throwable $t) { + } catch (Throwable $t) { $this->checkThrowable($t, $class, $msg, $code); return; } @@ -60,13 +61,13 @@ public function expectThrowable($throwable, callable $callback): void * Check if the given throwable matches the expected data, * fail (throws an exception) if it does not. */ - protected function checkThrowable(\Throwable $throwable, string $expectedClass, ?string $expectedMsg, $expectedCode = null): void + protected function checkThrowable(Throwable $throwable, string $expectedClass, ?string $expectedMsg, int|null $expectedCode = null): void { if (!($throwable instanceof $expectedClass)) { $this->fail(sprintf( "Exception of class '%s' expected to be thrown, but class '%s' was caught", $expectedClass, - get_class($throwable) + get_debug_type($throwable) )); } From 3aac619402b37207178f8702a11d9888c0aaeb35 Mon Sep 17 00:00:00 2001 From: TavoNiievez Date: Thu, 1 May 2025 21:11:05 -0500 Subject: [PATCH 11/13] Update tests to Codeception 5 dir structure --- codeception.yml | 13 +++++++++---- tests/{_data => Support/Data}/DummyClass.php | 4 +++- tests/{_data => Support/Data}/data1.json | 0 tests/{_data => Support/Data}/data1.txt | 0 tests/{_data => Support/Data}/data1.xml | 0 tests/{_data => Support/Data}/data2.json | 0 tests/{_data => Support/Data}/data2.txt | 0 tests/{_data => Support/Data}/data2.xml | 0 tests/{_data => Support/Data}/data3.txt | 0 .../{_data => Support/Data}/expectedFileFormat.txt | 0 tests/{_support => Support}/UnitTester.php | 13 ++++++++----- tests/Support/_generated/.gitignore | 2 ++ tests/_support/_generated/.gitignore | 1 - tests/unit.suite.yml | 9 ++++----- 14 files changed, 26 insertions(+), 16 deletions(-) rename tests/{_data => Support/Data}/DummyClass.php (80%) rename tests/{_data => Support/Data}/data1.json (100%) rename tests/{_data => Support/Data}/data1.txt (100%) rename tests/{_data => Support/Data}/data1.xml (100%) rename tests/{_data => Support/Data}/data2.json (100%) rename tests/{_data => Support/Data}/data2.txt (100%) rename tests/{_data => Support/Data}/data2.xml (100%) rename tests/{_data => Support/Data}/data3.txt (100%) rename tests/{_data => Support/Data}/expectedFileFormat.txt (100%) rename tests/{_support => Support}/UnitTester.php (77%) create mode 100644 tests/Support/_generated/.gitignore delete mode 100644 tests/_support/_generated/.gitignore diff --git a/codeception.yml b/codeception.yml index 779d777..a2ad109 100644 --- a/codeception.yml +++ b/codeception.yml @@ -1,7 +1,12 @@ +namespace: Tests +support_namespace: Support + +settings: + shuffle: true + lint: true paths: tests: tests output: tests/_output - data: tests/_data - support: tests/_support - envs: tests/_envs -actor_suffix: Tester + support: tests/Support + data: tests/Support/Data + \ No newline at end of file diff --git a/tests/_data/DummyClass.php b/tests/Support/Data/DummyClass.php similarity index 80% rename from tests/_data/DummyClass.php rename to tests/Support/Data/DummyClass.php index 85d2a2c..6967cfd 100644 --- a/tests/_data/DummyClass.php +++ b/tests/Support/Data/DummyClass.php @@ -2,9 +2,11 @@ declare(strict_types=1); +namespace Support\Data; + class DummyClass { private int $foo; - + private static int $staticFoo; } \ No newline at end of file diff --git a/tests/_data/data1.json b/tests/Support/Data/data1.json similarity index 100% rename from tests/_data/data1.json rename to tests/Support/Data/data1.json diff --git a/tests/_data/data1.txt b/tests/Support/Data/data1.txt similarity index 100% rename from tests/_data/data1.txt rename to tests/Support/Data/data1.txt diff --git a/tests/_data/data1.xml b/tests/Support/Data/data1.xml similarity index 100% rename from tests/_data/data1.xml rename to tests/Support/Data/data1.xml diff --git a/tests/_data/data2.json b/tests/Support/Data/data2.json similarity index 100% rename from tests/_data/data2.json rename to tests/Support/Data/data2.json diff --git a/tests/_data/data2.txt b/tests/Support/Data/data2.txt similarity index 100% rename from tests/_data/data2.txt rename to tests/Support/Data/data2.txt diff --git a/tests/_data/data2.xml b/tests/Support/Data/data2.xml similarity index 100% rename from tests/_data/data2.xml rename to tests/Support/Data/data2.xml diff --git a/tests/_data/data3.txt b/tests/Support/Data/data3.txt similarity index 100% rename from tests/_data/data3.txt rename to tests/Support/Data/data3.txt diff --git a/tests/_data/expectedFileFormat.txt b/tests/Support/Data/expectedFileFormat.txt similarity index 100% rename from tests/_data/expectedFileFormat.txt rename to tests/Support/Data/expectedFileFormat.txt diff --git a/tests/_support/UnitTester.php b/tests/Support/UnitTester.php similarity index 77% rename from tests/_support/UnitTester.php rename to tests/Support/UnitTester.php index e19544a..710bfbd 100644 --- a/tests/_support/UnitTester.php +++ b/tests/Support/UnitTester.php @@ -1,10 +1,13 @@ Date: Thu, 1 May 2025 21:11:19 -0500 Subject: [PATCH 12/13] Fix testMarkTestSkipped compatibility --- tests/unit/Codeception/Module/AssertsTest.php | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/tests/unit/Codeception/Module/AssertsTest.php b/tests/unit/Codeception/Module/AssertsTest.php index 11d833f..12ce769 100644 --- a/tests/unit/Codeception/Module/AssertsTest.php +++ b/tests/unit/Codeception/Module/AssertsTest.php @@ -12,7 +12,9 @@ use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\Constraint\IsEqual; use PHPUnit\Framework\IncompleteTestError; +use PHPUnit\Framework\SkippedTestError; use PHPUnit\Framework\SkippedWithMessageException; +use PHPUnit\Runner\Version as PHPUnitVersion; use RuntimeException; use stdClass; @@ -46,14 +48,14 @@ public function testPHPUnitAsserts() { $this->module->assertArrayHasKey('one', ['one' => 1, 'two' => 2]); $this->module->assertArrayNotHasKey('three', ['one' => 1, 'two' => 2]); - $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->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->assertContains(1, [1, 2]); $this->module->assertContainsEquals(2, [1, 2]); - $this->module->assertContainsOnly(\DummyClass::class, [new \DummyClass(), new \DummyClass()]); - $this->module->assertContainsOnlyInstancesOf(\DummyClass::class, [new \DummyClass(), new \DummyClass()]); + $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->assertDirectoryExists(__DIR__); @@ -130,7 +132,7 @@ public function testPHPUnitAsserts() $this->module->assertNan(sqrt(-1)); $this->module->assertNotContains('three', ['one', 'two']); $this->module->assertNotContainsEquals(3, [1, 2]); - $this->module->assertNotContainsOnly(\DummyClass::class, [new \DummyClass(), new Exception()]); + $this->module->assertNotContainsOnly(\Support\Data\DummyClass::class, [new \Support\Data\DummyClass(), new Exception()]); $this->module->assertNotCount(1, ['one', 'two']); $this->module->assertNotEmpty([1]); $this->module->assertNotEquals(true, false); @@ -150,8 +152,8 @@ public function testPHPUnitAsserts() $this->module->assertNotTrue(null); $this->module->assertNotTrue('foo'); $this->module->assertNull(null); - $this->module->assertObjectHasAttribute('foo', new \DummyClass()); - $this->module->assertObjectNotHasAttribute('bar', new \DummyClass()); + $this->module->assertObjectHasAttribute('foo', new \Support\Data\DummyClass()); + $this->module->assertObjectNotHasAttribute('bar', new \Support\Data\DummyClass()); $this->module->assertSame(1, 1); $this->module->assertSameSize([1, 2, 3], [1, 2, 3]); $this->module->assertStringContainsString('bar', 'foobar'); @@ -280,8 +282,12 @@ public function testMarkTestIncomplete() public function testMarkTestSkipped() { - $this->expectException(SkippedWithMessageException::class); $this->expectExceptionMessage('foobar'); + if (PHPUnitVersion::series() < 10) { + $this->expectException(SkippedTestError::class); + } else { + $this->expectException(SkippedWithMessageException::class); + } $this->module->markTestSkipped('foobar'); } From b05b62865ccd320046cae47900c711b9bf126a2d Mon Sep 17 00:00:00 2001 From: TavoNiievez Date: Thu, 1 May 2025 21:23:39 -0500 Subject: [PATCH 13/13] Add PHPStan and PHP Code Sniffer --- .github/workflows/main.yml | 33 +++++++++++++--------- src/Codeception/Module/AbstractAsserts.php | 2 +- src/Codeception/Module/Asserts.php | 12 ++++++-- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 79314d3..e8c6cc8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,20 +11,27 @@ jobs: php: [8.2, 8.3, 8.4] steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - coverage: none + - 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: Validate composer.json and composer.lock + run: composer validate - - name: Install dependencies - run: composer install --prefer-dist --no-progress --no-interaction --no-suggest + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-interaction --no-suggest - - name: Run test suite - run: php vendor/bin/codecept run + - name: Run PHPStan + run: phpstan analyse src + + - name: Run PHPCS + run: phpcs --standard=PSR12 src + + - name: Run test suite + run: php vendor/bin/codecept run diff --git a/src/Codeception/Module/AbstractAsserts.php b/src/Codeception/Module/AbstractAsserts.php index 6855f3a..da1fb93 100644 --- a/src/Codeception/Module/AbstractAsserts.php +++ b/src/Codeception/Module/AbstractAsserts.php @@ -147,4 +147,4 @@ abstract class AbstractAsserts extends Module markTestIncomplete as public; markTestSkipped as public; } -} \ No newline at end of file +} diff --git a/src/Codeception/Module/Asserts.php b/src/Codeception/Module/Asserts.php index 707db6a..24cf98e 100644 --- a/src/Codeception/Module/Asserts.php +++ b/src/Codeception/Module/Asserts.php @@ -5,6 +5,7 @@ namespace Codeception\Module; use Throwable; + use function get_debug_type; /** @@ -26,6 +27,7 @@ class Asserts extends AbstractAsserts * $this->doSomethingBad(); * }); * ``` + * * If you want to check message or throwable code, you can pass them with throwable instance: * ```php * getMessage(); - $code = $throwable->getCode(); + $code = (int) $throwable->getCode(); } else { $class = $throwable; $msg = null; @@ -61,8 +63,12 @@ public function expectThrowable(string|Throwable $throwable, callable $callback) * Check if the given throwable matches the expected data, * fail (throws an exception) if it does not. */ - protected function checkThrowable(Throwable $throwable, string $expectedClass, ?string $expectedMsg, int|null $expectedCode = null): void - { + protected function checkThrowable( + Throwable $throwable, + string $expectedClass, + ?string $expectedMsg, + int|null $expectedCode = null + ): void { if (!($throwable instanceof $expectedClass)) { $this->fail(sprintf( "Exception of class '%s' expected to be thrown, but class '%s' was caught",