Skip to content

Update to PHP 8.2, Codeception 5 and static analysis #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 21 additions & 14 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,30 @@ jobs:

strategy:
matrix:
php: [8.1, 8.2, 8.3, 8.4]
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
13 changes: 9 additions & 4 deletions codeception.yml
Original file line number Diff line number Diff line change
@@ -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

2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
],
"homepage": "https://codeception.com/",
"require": {
"php": "^8.1",
"php": "^8.2",
"codeception/codeception": "*@dev",
"codeception/lib-asserts": "^2.2"
},
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A Codeception module containing various assertions.

## Requirements

* `PHP 8.1` or higher.
* `PHP 8.2` or higher.

## Installation

Expand Down
2 changes: 1 addition & 1 deletion src/Codeception/Module/AbstractAsserts.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,4 @@ abstract class AbstractAsserts extends Module
markTestIncomplete as public;
markTestSkipped as public;
}
}
}
23 changes: 15 additions & 8 deletions src/Codeception/Module/Asserts.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

namespace Codeception\Module;

use Throwable;

use function get_debug_type;

/**
* Special module for using asserts in your tests.
*/
Expand All @@ -23,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
* <?php
Expand All @@ -31,15 +36,13 @@ 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);
$msg = $throwable->getMessage();
$code = $throwable->getCode();
$code = (int) $throwable->getCode();
} else {
$class = $throwable;
$msg = null;
Expand All @@ -48,7 +51,7 @@ public function expectThrowable($throwable, callable $callback): void

try {
$callback();
} catch (\Throwable $t) {
} catch (Throwable $t) {
$this->checkThrowable($t, $class, $msg, $code);
return;
}
Expand All @@ -60,13 +63,17 @@ 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)
));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

declare(strict_types=1);

namespace Support\Data;

class DummyClass
{
private int $foo;

private static int $staticFoo;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 8 additions & 5 deletions tests/_support/UnitTester.php → tests/Support/UnitTester.php
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
<?php

declare(strict_types=1);

namespace Tests\Support;

/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void wantToTest($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method void pause()
* @method void pause($vars = [])
*
* @SuppressWarnings(PHPMD)
*/
class UnitTester extends \Codeception\Actor
{
use _generated\UnitTesterActions;

/**
* Define custom actions here
*/
/**
* Define custom actions here
*/
}
2 changes: 2 additions & 0 deletions tests/Support/_generated/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
1 change: 0 additions & 1 deletion tests/_support/_generated/.gitignore

This file was deleted.

9 changes: 4 additions & 5 deletions tests/unit.suite.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Codeception Test Suite Configuration

# suite for unit (internal) tests.
error_level: "E_ALL"
class_name: UnitTester
actor: UnitTester
suite_namespace: Tests\Unit
modules:
enabled: []
26 changes: 16 additions & 10 deletions tests/unit/Codeception/Module/AssertsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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__);
Expand Down Expand Up @@ -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);
Expand All @@ -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');
Expand Down Expand Up @@ -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');
}
Expand Down