mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 15:57:21 +01:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a55da85dd2 | |||
| f291cd1603 | |||
| 5de0c2254a | |||
| b98ce0ced3 | |||
| 28772c2609 | |||
| 452ffaf8df | |||
| e8338405b5 |
13
.github/workflows/tests.yml
vendored
13
.github/workflows/tests.yml
vendored
@ -13,8 +13,8 @@ jobs:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
symfony: ['7.0']
|
||||
php: ['8.2', '8.3']
|
||||
symfony: ['7.1']
|
||||
php: ['8.2', '8.3', '8.4']
|
||||
dependency_version: [prefer-lowest, prefer-stable]
|
||||
|
||||
name: PHP ${{ matrix.php }} - Symfony ^${{ matrix.symfony }} - ${{ matrix.os }} - ${{ matrix.dependency_version }}
|
||||
@ -36,7 +36,13 @@ jobs:
|
||||
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||
|
||||
- name: Install PHP dependencies
|
||||
run: composer update --${{ matrix.dependency_version }} --no-interaction --no-progress --ansi --with="symfony/console:~${{ matrix.symfony }}"
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ matrix.php }}" == "8.4" ]]; then
|
||||
composer update --${{ matrix.dependency_version }} --no-interaction --no-progress --ansi --with="symfony/console:^${{ matrix.symfony }}" --ignore-platform-req=php
|
||||
else
|
||||
composer update --${{ matrix.dependency_version }} --no-interaction --no-progress --ansi --with="symfony/console:^${{ matrix.symfony }}"
|
||||
fi
|
||||
|
||||
- name: Unit Tests
|
||||
run: composer test:unit
|
||||
@ -45,4 +51,5 @@ jobs:
|
||||
run: composer test:parallel
|
||||
|
||||
- name: Integration Tests
|
||||
if: ${{ matrix.php != '8.4' }}
|
||||
run: composer test:integration
|
||||
|
||||
@ -18,12 +18,12 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.2.0",
|
||||
"brianium/paratest": "^7.5.4",
|
||||
"brianium/paratest": "^7.5.5",
|
||||
"nunomaduro/collision": "^8.4.0",
|
||||
"nunomaduro/termwind": "^2.1.0",
|
||||
"pestphp/pest-plugin": "^3.0.0",
|
||||
"pestphp/pest-plugin-arch": "^3.0.0",
|
||||
"pestphp/pest-plugin-mutate": "^3.0.3",
|
||||
"pestphp/pest-plugin-mutate": "^3.0.5",
|
||||
"phpunit/phpunit": "^11.3.6"
|
||||
},
|
||||
"conflict": {
|
||||
@ -54,7 +54,7 @@
|
||||
"require-dev": {
|
||||
"pestphp/pest-dev-tools": "^3.0.0",
|
||||
"pestphp/pest-plugin-type-coverage": "^3.0.0",
|
||||
"symfony/process": "^7.1.3"
|
||||
"symfony/process": "^7.1.5"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
|
||||
@ -21,6 +21,7 @@ final class Strict extends AbstractPreset
|
||||
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toHaveProtectedMethods(),
|
||||
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toBeAbstract(),
|
||||
fn (Expectation $namespace): ArchExpectation => $namespace->toUseStrictTypes(),
|
||||
fn (Expectation $namespace): ArchExpectation => $namespace->toUseStrictEquality(),
|
||||
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->toBeFinal(),
|
||||
);
|
||||
|
||||
|
||||
@ -223,7 +223,7 @@ final class Expectation
|
||||
throw new BadMethodCallException('Expectation value is not iterable.');
|
||||
}
|
||||
|
||||
if (count($callbacks) == 0) {
|
||||
if ($callbacks === []) {
|
||||
throw new InvalidArgumentException('No sequence expectations defined.');
|
||||
}
|
||||
|
||||
@ -515,6 +515,19 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target uses strict equality.
|
||||
*/
|
||||
public function toUseStrictEquality(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => ! str_contains((string) file_get_contents($object->path), ' == '), // @pest-arch-ignore-line
|
||||
'to use strict equality',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, ' == ')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is final.
|
||||
*/
|
||||
|
||||
@ -152,6 +152,19 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not use the strict equality operator.
|
||||
*/
|
||||
public function toUseStrictEquality(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this->original,
|
||||
fn (ObjectDescription $object): bool => ! str_contains((string) file_get_contents($object->path), ' === '),
|
||||
'to use strict equality',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, ' === ')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not final.
|
||||
*/
|
||||
|
||||
@ -217,7 +217,7 @@ if (! function_exists('afterAll')) {
|
||||
|
||||
if (! function_exists('covers')) {
|
||||
/**
|
||||
* Specifies which classes, or functions, a test method covers.
|
||||
* Specifies which classes, or functions, a test case covers.
|
||||
*
|
||||
* @param array<int, string>|string $classesOrFunctions
|
||||
*/
|
||||
@ -243,3 +243,38 @@ if (! function_exists('covers')) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('mutates')) {
|
||||
/**
|
||||
* Specifies which classes, enums, or traits a test case mutates.
|
||||
*
|
||||
* @param array<int, string>|string $targets
|
||||
*/
|
||||
function mutates(array|string ...$targets): void
|
||||
{
|
||||
$filename = Backtrace::file();
|
||||
|
||||
$beforeEachCall = (new BeforeEachCall(TestSuite::getInstance(), $filename));
|
||||
$beforeEachCall->group('__pest_mutate_only');
|
||||
|
||||
/** @var MutationTestRunner $runner */
|
||||
$runner = Container::getInstance()->get(MutationTestRunner::class);
|
||||
/** @var \Pest\Mutate\Repositories\ConfigurationRepository $configurationRepository */
|
||||
$configurationRepository = Container::getInstance()->get(ConfigurationRepository::class);
|
||||
$everything = $configurationRepository->cliConfiguration->toArray()['everything'] ?? false;
|
||||
$classes = $configurationRepository->cliConfiguration->toArray()['classes'] ?? false;
|
||||
$paths = $configurationRepository->cliConfiguration->toArray()['paths'] ?? false;
|
||||
|
||||
if ($runner->isEnabled() && ! $everything && ! is_array($classes) && ! is_array($paths)) {
|
||||
$beforeEachCall->only('__pest_mutate_only');
|
||||
}
|
||||
|
||||
/** @var ConfigurationRepository $configurationRepository */
|
||||
$configurationRepository = Container::getInstance()->get(ConfigurationRepository::class);
|
||||
$paths = $configurationRepository->cliConfiguration->toArray()['paths'] ?? false;
|
||||
|
||||
if (! is_array($paths)) {
|
||||
$configurationRepository->globalConfiguration('default')->class(...$targets); // @phpstan-ignore-line
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,7 +178,7 @@ final readonly class Converter
|
||||
public function getTestSuiteLocation(TestSuite $testSuite): ?string
|
||||
{
|
||||
$firstTest = $this->getFirstTest($testSuite);
|
||||
if ($firstTest == null) {
|
||||
if (! $firstTest instanceof \PHPUnit\Event\Code\TestMethod) {
|
||||
return null;
|
||||
}
|
||||
$path = $firstTest->testDox()->prettifiedClassName();
|
||||
|
||||
@ -6,7 +6,7 @@ namespace Pest;
|
||||
|
||||
function version(): string
|
||||
{
|
||||
return '3.0.8';
|
||||
return '3.2.0';
|
||||
}
|
||||
|
||||
function testDirectory(string $file = ''): string
|
||||
|
||||
@ -20,13 +20,13 @@ final class Closure
|
||||
*/
|
||||
public static function bind(?BaseClosure $closure, ?object $newThis, object|string|null $newScope = 'static'): BaseClosure
|
||||
{
|
||||
if ($closure == null) {
|
||||
if (! $closure instanceof \Closure) {
|
||||
throw ShouldNotHappen::fromMessage('Could not bind null closure.');
|
||||
}
|
||||
|
||||
$closure = BaseClosure::bind($closure, $newThis, $newScope);
|
||||
|
||||
if ($closure == false) {
|
||||
if ($closure === null) {
|
||||
throw ShouldNotHappen::fromMessage('Could not bind closure.');
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
Pest Testing Framework 3.0.8.
|
||||
Pest Testing Framework 3.2.0.
|
||||
|
||||
USAGE: pest <file> [options]
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
|
||||
Pest Testing Framework 3.0.8.
|
||||
Pest Testing Framework 3.2.0.
|
||||
|
||||
|
||||
@ -968,6 +968,12 @@
|
||||
✓ it can handle a non-defined exception
|
||||
✓ it can handle a class not found Error
|
||||
|
||||
PASS Tests\Features\Expect\toUseStrictEquality
|
||||
✓ missing strict equality
|
||||
✓ has strict equality
|
||||
✓ opposite missing strict equality
|
||||
✓ opposite has strict equality
|
||||
|
||||
PASS Tests\Features\Expect\toUseTrait
|
||||
✓ pass
|
||||
✓ failures
|
||||
@ -1574,4 +1580,4 @@
|
||||
WARN Tests\Visual\Version
|
||||
- visual snapshot of help command output
|
||||
|
||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 28 skipped, 1089 passed (2637 assertions)
|
||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 28 skipped, 1093 passed (2644 assertions)
|
||||
21
tests/Features/Expect/toUseStrictEquality.php
Normal file
21
tests/Features/Expect/toUseStrictEquality.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
use Pest\Arch\Exceptions\ArchExpectationFailedException;
|
||||
|
||||
test('missing strict equality')
|
||||
->throws(ArchExpectationFailedException::class)
|
||||
->expect('Tests\\Fixtures\\Arch\\ToUseStrictEquality\\NotStrictEquality')
|
||||
->toUseStrictEquality();
|
||||
|
||||
test('has strict equality')
|
||||
->expect('Tests\\Fixtures\\Arch\\ToUseStrictEquality\\StrictEquality')
|
||||
->toUseStrictEquality();
|
||||
|
||||
test('opposite missing strict equality')
|
||||
->throws(ArchExpectationFailedException::class)
|
||||
->expect('Tests\\Fixtures\\Arch\\ToUseStrictEquality\\StrictEquality')
|
||||
->not->toUseStrictEquality();
|
||||
|
||||
test('opposite has strict equality')
|
||||
->expect('Tests\\Fixtures\\Arch\\ToUseStrictEquality\\NotStrictEquality')
|
||||
->not->toUseStrictEquality();
|
||||
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Fixtures\Arch\ToUseStrictEquality;
|
||||
|
||||
class NotStrictEquality
|
||||
{
|
||||
public function test(): void
|
||||
{
|
||||
$a = 1;
|
||||
$b = '1';
|
||||
|
||||
if ($a == $b) {
|
||||
echo 'Equal';
|
||||
}
|
||||
}
|
||||
}
|
||||
18
tests/Fixtures/Arch/ToUseStrictEquality/StrictEquality.php
Normal file
18
tests/Fixtures/Arch/ToUseStrictEquality/StrictEquality.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Fixtures\Arch\ToUseStrictEquality;
|
||||
|
||||
class StrictEquality
|
||||
{
|
||||
public function test(): void
|
||||
{
|
||||
$a = 1;
|
||||
$b = '1';
|
||||
|
||||
if ($a === $b) {
|
||||
echo 'Equal';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@ $run = function () {
|
||||
|
||||
test('parallel', function () use ($run) {
|
||||
expect($run('--exclude-group=integration'))
|
||||
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 19 skipped, 1079 passed (2613 assertions)')
|
||||
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 19 skipped, 1083 passed (2620 assertions)')
|
||||
->toContain('Parallel: 3 processes');
|
||||
})->skipOnWindows();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user