mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 15:57:21 +01:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 72cf695554 | |||
| 027f4e4832 | |||
| 165c879fe6 | |||
| 4c8bf4b2fd | |||
| 1b0a846a81 | |||
| f692be3637 | |||
| 127ad618d3 | |||
| 55218bcf78 | |||
| 2a47b514ec | |||
| 7d77bbf1bb | |||
| 97c136cd94 | |||
| d6cbd12d8b | |||
| c6244a8712 | |||
| eed68f2840 | |||
| a5317c5640 | |||
| 1ac594bdf0 |
@ -35,16 +35,15 @@ We cannot thank our sponsors enough for their incredible support in funding Pest
|
||||
### Gold Sponsors
|
||||
|
||||
- **[CodeRabbit](https://coderabbit.ai/?ref=pestphp)**
|
||||
- **[LaraJobs](https://larajobs.com/?ref=pestphp)**
|
||||
- **[Brokerchooser](https://brokerchooser.com/?ref=pestphp)**
|
||||
- **[Forge](https://forge.laravel.com/?ref=pestphp)**
|
||||
- **[NativePHP](https://nativephp.com/mobile?ref=pestphp.com)**
|
||||
- **[CMS Max](https://cmsmax.com/?ref=pestphp)**
|
||||
|
||||
### Premium Sponsors
|
||||
|
||||
- [Akaunting](https://akaunting.com/?ref=pestphp)
|
||||
- [Codecourse](https://codecourse.com/?ref=pestphp)
|
||||
- [DocuWriter.ai](https://www.docuwriter.ai/?ref=pestphp)
|
||||
- [Localazy](https://localazy.com/?ref=pestphp)
|
||||
- [Forge](https://forge.laravel.com/?ref=pestphp)
|
||||
- [Route4Me](https://www.route4me.com/?ref=pestphp)
|
||||
- [Spatie](https://spatie.be/?ref=pestphp)
|
||||
- [Worksome](https://www.worksome.com/?ref=pestphp)
|
||||
|
||||
@ -18,17 +18,17 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.2.0",
|
||||
"brianium/paratest": "^7.8.3",
|
||||
"nunomaduro/collision": "^8.8.0",
|
||||
"nunomaduro/termwind": "^2.3.0",
|
||||
"brianium/paratest": "^7.8.4",
|
||||
"nunomaduro/collision": "^8.8.2",
|
||||
"nunomaduro/termwind": "^2.3.1",
|
||||
"pestphp/pest-plugin": "^3.0.0",
|
||||
"pestphp/pest-plugin-arch": "^3.1.0",
|
||||
"pestphp/pest-plugin-arch": "^3.1.1",
|
||||
"pestphp/pest-plugin-mutate": "^3.0.5",
|
||||
"phpunit/phpunit": "^11.5.15"
|
||||
"phpunit/phpunit": "^11.5.33"
|
||||
},
|
||||
"conflict": {
|
||||
"filp/whoops": "<2.16.0",
|
||||
"phpunit/phpunit": ">11.5.15",
|
||||
"phpunit/phpunit": ">11.5.33",
|
||||
"sebastian/exporter": "<6.0.0",
|
||||
"webmozart/assert": "<1.11.0"
|
||||
},
|
||||
@ -54,8 +54,8 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"pestphp/pest-dev-tools": "^3.4.0",
|
||||
"pestphp/pest-plugin-type-coverage": "^3.5.0",
|
||||
"symfony/process": "^7.2.5"
|
||||
"pestphp/pest-plugin-type-coverage": "^3.6.1",
|
||||
"symfony/process": "^7.3.0"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
|
||||
@ -49,7 +49,7 @@ use const DIRECTORY_SEPARATOR;
|
||||
use const LOCK_EX;
|
||||
|
||||
use PHPUnit\Framework\TestStatus\TestStatus;
|
||||
use PHPUnit\Runner\DirectoryCannotBeCreatedException;
|
||||
use PHPUnit\Runner\DirectoryDoesNotExistException;
|
||||
use PHPUnit\Runner\Exception;
|
||||
use PHPUnit\Util\Filesystem;
|
||||
|
||||
@ -98,28 +98,28 @@ final class DefaultResultCache implements ResultCache
|
||||
$this->cacheFilename = $filepath ?? $_ENV['PHPUNIT_RESULT_CACHE'] ?? self::DEFAULT_RESULT_CACHE_FILENAME;
|
||||
}
|
||||
|
||||
public function setStatus(string $id, TestStatus $status): void
|
||||
public function setStatus(ResultCacheId $id, TestStatus $status): void
|
||||
{
|
||||
if ($status->isSuccess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->defects[$id] = $status;
|
||||
$this->defects[$id->asString()] = $status;
|
||||
}
|
||||
|
||||
public function status(string $id): TestStatus
|
||||
public function status(ResultCacheId $id): TestStatus
|
||||
{
|
||||
return $this->defects[$id] ?? TestStatus::unknown();
|
||||
return $this->defects[$id->asString()] ?? TestStatus::unknown();
|
||||
}
|
||||
|
||||
public function setTime(string $id, float $time): void
|
||||
public function setTime(ResultCacheId $id, float $time): void
|
||||
{
|
||||
$this->times[$id] = $time;
|
||||
$this->times[$id->asString()] = $time;
|
||||
}
|
||||
|
||||
public function time(string $id): float
|
||||
public function time(ResultCacheId $id): float
|
||||
{
|
||||
return $this->times[$id] ?? 0.0;
|
||||
return $this->times[$id->asString()] ?? 0.0;
|
||||
}
|
||||
|
||||
public function mergeWith(self $other): void
|
||||
@ -179,7 +179,7 @@ final class DefaultResultCache implements ResultCache
|
||||
public function persist(): void
|
||||
{
|
||||
if (! Filesystem::createDirectory(dirname($this->cacheFilename))) {
|
||||
throw new DirectoryCannotBeCreatedException($this->cacheFilename);
|
||||
throw new DirectoryDoesNotExistException(dirname($this->cacheFilename));
|
||||
}
|
||||
|
||||
$data = [
|
||||
|
||||
@ -35,7 +35,8 @@ final class Laravel extends AbstractPreset
|
||||
->ignoring('App\Features\Concerns');
|
||||
|
||||
$this->expectations[] = expect('App\Features')
|
||||
->toHaveMethod('resolve');
|
||||
->toHaveMethod('resolve')
|
||||
->ignoring('App\Features\Concerns');
|
||||
|
||||
$this->expectations[] = expect('App\Exceptions')
|
||||
->classes()
|
||||
@ -166,5 +167,11 @@ final class Laravel extends AbstractPreset
|
||||
$this->expectations[] = expect('App\Policies')
|
||||
->classes()
|
||||
->toHaveSuffix('Policy');
|
||||
|
||||
$this->expectations[] = expect('App\Attributes')
|
||||
->classes()
|
||||
->toImplement('Illuminate\Contracts\Container\ContextualAttribute')
|
||||
->toHaveAttribute('Attribute')
|
||||
->toHaveMethod('resolve');
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ final class ShouldNotHappen extends RuntimeException
|
||||
$message = $exception->getMessage();
|
||||
|
||||
parent::__construct(sprintf(<<<'EOF'
|
||||
This should not happen - please create an new issue here: https://github.com/pestphp/pest.
|
||||
This should not happen - please create an new issue here: https://github.com/pestphp/pest/issues
|
||||
|
||||
Issue: %s
|
||||
PHP version: %s
|
||||
|
||||
@ -535,7 +535,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && $object->reflectionClass->isFinal(),
|
||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && isset($object->reflectionClass) && $object->reflectionClass->isFinal(),
|
||||
'to be final',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -548,7 +548,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && $object->reflectionClass->isReadOnly() && assert(true), // @phpstan-ignore-line
|
||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && isset($object->reflectionClass) && $object->reflectionClass->isReadOnly() && assert(true), // @phpstan-ignore-line
|
||||
'to be readonly',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -561,7 +561,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->isTrait(),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && $object->reflectionClass->isTrait(),
|
||||
'to be trait',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -582,7 +582,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->isAbstract(),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && $object->reflectionClass->isAbstract(),
|
||||
'to be abstract',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -599,7 +599,7 @@ final class Expectation
|
||||
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => count(array_filter($methods, fn (string $method): bool => $object->reflectionClass->hasMethod($method))) === count($methods),
|
||||
fn (ObjectDescription $object): bool => count(array_filter($methods, fn (string $method): bool => isset($object->reflectionClass) && $object->reflectionClass->hasMethod($method))) === count($methods),
|
||||
sprintf("to have method '%s'", implode("', '", $methods)),
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -670,7 +670,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->isEnum(),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && $object->reflectionClass->isEnum(),
|
||||
'to be enum',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -712,7 +712,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->isInterface(),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && $object->reflectionClass->isInterface(),
|
||||
'to be interface',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -733,7 +733,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => $class === $object->reflectionClass->getName() || $object->reflectionClass->isSubclassOf($class),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && ($class === $object->reflectionClass->getName() || $object->reflectionClass->isSubclassOf($class)),
|
||||
sprintf("to extend '%s'", $class),
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -773,6 +773,10 @@ final class Expectation
|
||||
$this,
|
||||
function (ObjectDescription $object) use ($traits): bool {
|
||||
foreach ($traits as $trait) {
|
||||
if (isset($object->reflectionClass) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! in_array($trait, $object->reflectionClass->getTraitNames(), true)) {
|
||||
return false;
|
||||
}
|
||||
@ -792,7 +796,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->getInterfaceNames() === [],
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && $object->reflectionClass->getInterfaceNames() === [],
|
||||
'to implement nothing',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -809,7 +813,8 @@ final class Expectation
|
||||
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => count($interfaces) === count($object->reflectionClass->getInterfaceNames())
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass)
|
||||
&& (count($interfaces) === count($object->reflectionClass->getInterfaceNames()))
|
||||
&& array_diff($interfaces, $object->reflectionClass->getInterfaceNames()) === [],
|
||||
"to only implement '".implode("', '", $interfaces)."'",
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
@ -823,7 +828,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => str_starts_with($object->reflectionClass->getShortName(), $prefix),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && str_starts_with($object->reflectionClass->getShortName(), $prefix),
|
||||
"to have prefix '{$prefix}'",
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -836,7 +841,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => str_ends_with($object->reflectionClass->getName(), $suffix),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && str_ends_with($object->reflectionClass->getName(), $suffix),
|
||||
"to have suffix '{$suffix}'",
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -855,7 +860,7 @@ final class Expectation
|
||||
$this,
|
||||
function (ObjectDescription $object) use ($interfaces): bool {
|
||||
foreach ($interfaces as $interface) {
|
||||
if (! $object->reflectionClass->implementsInterface($interface)) {
|
||||
if (! isset($object->reflectionClass) || ! $object->reflectionClass->implementsInterface($interface)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -928,7 +933,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->hasMethod('__invoke'),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && $object->reflectionClass->hasMethod('__invoke'),
|
||||
'to be invokable',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class'))
|
||||
);
|
||||
@ -1037,7 +1042,7 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->getAttributes($attribute) !== [],
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) && $object->reflectionClass->getAttributes($attribute) !== [],
|
||||
"to have attribute '{$attribute}'",
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -1066,7 +1071,8 @@ final class Expectation
|
||||
{
|
||||
return Targeted::make(
|
||||
$this,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->isEnum()
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass)
|
||||
&& $object->reflectionClass->isEnum()
|
||||
&& (new ReflectionEnum($object->name))->isBacked() // @phpstan-ignore-line
|
||||
&& (string) (new ReflectionEnum($object->name))->getBackingType() === $backingType, // @phpstan-ignore-line
|
||||
'to be '.$backingType.' backed enum',
|
||||
|
||||
@ -193,7 +193,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && ! $object->reflectionClass->isFinal(),
|
||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && (isset($object->reflectionClass) === false || ! $object->reflectionClass->isFinal()),
|
||||
'not to be final',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -209,7 +209,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && ! $object->reflectionClass->isReadOnly() && assert(true), // @phpstan-ignore-line
|
||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && (isset($object->reflectionClass) === false || ! $object->reflectionClass->isReadOnly()) && assert(true), // @phpstan-ignore-line
|
||||
'not to be readonly',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -225,7 +225,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! $object->reflectionClass->isTrait(),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || ! $object->reflectionClass->isTrait(),
|
||||
'not to be trait',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -249,7 +249,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! $object->reflectionClass->isAbstract(),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || ! $object->reflectionClass->isAbstract(),
|
||||
'not to be abstract',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -271,7 +271,7 @@ final readonly class OppositeExpectation
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => array_filter(
|
||||
$methods,
|
||||
fn (string $method): bool => $object->reflectionClass->hasMethod($method),
|
||||
fn (string $method): bool => isset($object->reflectionClass) === false || $object->reflectionClass->hasMethod($method),
|
||||
) === [],
|
||||
'to not have methods: '.implode(', ', $methods),
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
@ -436,7 +436,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! $object->reflectionClass->isEnum(),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || ! $object->reflectionClass->isEnum(),
|
||||
'not to be enum',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -484,7 +484,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! $object->reflectionClass->isInterface(),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || ! $object->reflectionClass->isInterface(),
|
||||
'not to be interface',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -508,7 +508,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! $object->reflectionClass->isSubclassOf($class),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || ! $object->reflectionClass->isSubclassOf($class),
|
||||
sprintf("not to extend '%s'", $class),
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -524,7 +524,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->getParentClass() !== false,
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || $object->reflectionClass->getParentClass() !== false,
|
||||
'to extend a class',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -554,7 +554,7 @@ final readonly class OppositeExpectation
|
||||
$original,
|
||||
function (ObjectDescription $object) use ($traits): bool {
|
||||
foreach ($traits as $trait) {
|
||||
if (in_array($trait, $object->reflectionClass->getTraitNames(), true)) {
|
||||
if (isset($object->reflectionClass) && in_array($trait, $object->reflectionClass->getTraitNames(), true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -582,7 +582,7 @@ final readonly class OppositeExpectation
|
||||
$original,
|
||||
function (ObjectDescription $object) use ($interfaces): bool {
|
||||
foreach ($interfaces as $interface) {
|
||||
if ($object->reflectionClass->implementsInterface($interface)) {
|
||||
if (isset($object->reflectionClass) && $object->reflectionClass->implementsInterface($interface)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -604,7 +604,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->getInterfaceNames() !== [],
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || $object->reflectionClass->getInterfaceNames() !== [],
|
||||
'to implement an interface',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -628,7 +628,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! str_starts_with($object->reflectionClass->getShortName(), $prefix),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || ! str_starts_with($object->reflectionClass->getShortName(), $prefix),
|
||||
"not to have prefix '{$prefix}'",
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -644,7 +644,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! str_ends_with($object->reflectionClass->getName(), $suffix),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || ! str_ends_with($object->reflectionClass->getName(), $suffix),
|
||||
"not to have suffix '{$suffix}'",
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||
);
|
||||
@ -715,7 +715,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! $object->reflectionClass->hasMethod('__invoke'),
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || ! $object->reflectionClass->hasMethod('__invoke'),
|
||||
'to not be invokable',
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class'))
|
||||
);
|
||||
@ -731,7 +731,7 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => $object->reflectionClass->getAttributes($attribute) === [],
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false || $object->reflectionClass->getAttributes($attribute) === [],
|
||||
"to not have attribute '{$attribute}'",
|
||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class'))
|
||||
);
|
||||
@ -826,7 +826,8 @@ final readonly class OppositeExpectation
|
||||
|
||||
return Targeted::make(
|
||||
$original,
|
||||
fn (ObjectDescription $object): bool => ! $object->reflectionClass->isEnum()
|
||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false
|
||||
|| ! $object->reflectionClass->isEnum()
|
||||
|| ! (new \ReflectionEnum($object->name))->isBacked() // @phpstan-ignore-line
|
||||
|| (string) (new \ReflectionEnum($object->name))->getBackingType() !== $backingType, // @phpstan-ignore-line
|
||||
'not to be '.$backingType.' backed enum',
|
||||
|
||||
@ -232,7 +232,6 @@ final class TeamCityLogger
|
||||
$reflector = new ReflectionClass($telemetry);
|
||||
|
||||
$property = $reflector->getProperty('current');
|
||||
$property->setAccessible(true);
|
||||
$snapshot = $property->getValue($telemetry);
|
||||
assert($snapshot instanceof Snapshot);
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ namespace Pest;
|
||||
|
||||
function version(): string
|
||||
{
|
||||
return '3.8.1';
|
||||
return '3.8.4';
|
||||
}
|
||||
|
||||
function testDirectory(string $file = ''): string
|
||||
|
||||
@ -19,8 +19,8 @@ final class SnapshotRepository
|
||||
* Creates a snapshot repository instance.
|
||||
*/
|
||||
public function __construct(
|
||||
readonly private string $testsPath,
|
||||
readonly private string $snapshotsPath,
|
||||
private readonly string $testsPath,
|
||||
private readonly string $snapshotsPath,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
||||
@ -40,7 +40,7 @@ final class Result
|
||||
*/
|
||||
public static function exitCode(Configuration $configuration, TestResult $result): int
|
||||
{
|
||||
if ($result->wasSuccessfulIgnoringPhpunitWarnings()) {
|
||||
if ($result->wasSuccessful()) {
|
||||
if ($configuration->failOnWarning()) {
|
||||
$warnings = $result->numberOfTestsWithTestTriggeredPhpunitWarningEvents()
|
||||
+ count($result->warnings())
|
||||
@ -60,7 +60,7 @@ final class Result
|
||||
return self::FAILURE_EXIT;
|
||||
}
|
||||
|
||||
if ($result->wasSuccessfulIgnoringPhpunitWarnings()) {
|
||||
if ($result->wasSuccessful()) {
|
||||
if ($configuration->failOnRisky() && $result->hasTestConsideredRiskyEvents()) {
|
||||
$returnCode = self::FAILURE_EXIT;
|
||||
}
|
||||
|
||||
@ -23,14 +23,12 @@ final class EnsureIgnorableTestCasesAreIgnored implements StartedSubscriber
|
||||
{
|
||||
$reflection = new ReflectionClass(Facade::class);
|
||||
$property = $reflection->getProperty('collector');
|
||||
$property->setAccessible(true);
|
||||
$collector = $property->getValue();
|
||||
|
||||
assert($collector instanceof Collector);
|
||||
|
||||
$reflection = new ReflectionClass($collector);
|
||||
$property = $reflection->getProperty('testRunnerTriggeredWarningEvents');
|
||||
$property->setAccessible(true);
|
||||
|
||||
/** @var array<int, WarningTriggered> $testRunnerTriggeredWarningEvents */
|
||||
$testRunnerTriggeredWarningEvents = $property->getValue($collector);
|
||||
|
||||
@ -34,8 +34,6 @@ final class Reflection
|
||||
try {
|
||||
$reflectionMethod = $reflectionClass->getMethod($method);
|
||||
|
||||
$reflectionMethod->setAccessible(true);
|
||||
|
||||
return $reflectionMethod->invoke($object, ...$args);
|
||||
} catch (ReflectionException $exception) {
|
||||
if (method_exists($object, '__call')) {
|
||||
@ -113,8 +111,6 @@ final class Reflection
|
||||
}
|
||||
}
|
||||
|
||||
$reflectionProperty->setAccessible(true);
|
||||
|
||||
return $reflectionProperty->getValue($object);
|
||||
}
|
||||
|
||||
@ -144,8 +140,6 @@ final class Reflection
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$reflectionProperty->setAccessible(true);
|
||||
$reflectionProperty->setValue($object, $value);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
Pest Testing Framework 3.8.1.
|
||||
Pest Testing Framework 3.8.4.
|
||||
|
||||
USAGE: pest <file> [options]
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
--disallow-test-output ................. Be strict about output during tests
|
||||
--enforce-time-limit ................. Enforce time limit based on test size
|
||||
--default-time-limit [sec] Timeout in seconds for tests that have no declared size
|
||||
--dont-report-useless-tests .. Do not report tests that do not test anything
|
||||
--do-not-report-useless-tests Do not report tests that do not test anything
|
||||
--stop-on-defect ... Stop after first error, failure, warning, or risky test
|
||||
--stop-on-error ..................................... Stop after first error
|
||||
--stop-on-failure ................................. Stop after first failure
|
||||
@ -68,9 +68,20 @@
|
||||
--fail-on-risky Signal failure using shell exit code when a test was considered risky
|
||||
--fail-on-deprecation Signal failure using shell exit code when a deprecation was triggered
|
||||
--fail-on-phpunit-deprecation Signal failure using shell exit code when a PHPUnit deprecation was triggered
|
||||
--fail-on-phpunit-warning Signal failure using shell exit code when a PHPUnit warning was triggered
|
||||
--fail-on-notice Signal failure using shell exit code when a notice was triggered
|
||||
--fail-on-skipped Signal failure using shell exit code when a test was skipped
|
||||
--fail-on-incomplete Signal failure using shell exit code when a test was marked incomplete
|
||||
--fail-on-all-issues Signal failure using shell exit code when an issue is triggered
|
||||
--do-not-fail-on-empty-test-suite Do not signal failure using shell exit code when no tests were run
|
||||
--do-not-fail-on-warning Do not signal failure using shell exit code when a warning was triggered
|
||||
--do-not-fail-on-risky Do not signal failure using shell exit code when a test was considered risky
|
||||
--do-not-fail-on-deprecation Do not signal failure using shell exit code when a deprecation was triggered
|
||||
--do-not-fail-on-phpunit-deprecation Do not signal failure using shell exit code when a PHPUnit deprecation was triggered
|
||||
--do-not-fail-on-phpunit-warning Do not signal failure using shell exit code when a PHPUnit warning was triggered
|
||||
--do-not-fail-on-notice Do not signal failure using shell exit code when a notice was triggered
|
||||
--do-not-fail-on-skipped Do not signal failure using shell exit code when a test was skipped
|
||||
--do-not-fail-on-incomplete Do not signal failure using shell exit code when a test was marked incomplete
|
||||
--cache-result ............................ Write test results to cache file
|
||||
--do-not-cache-result .............. Do not write test results to cache file
|
||||
--order-by [order] Run tests in order: default|defects|depends|duration|no-depends|random|reverse|size
|
||||
@ -91,6 +102,7 @@
|
||||
--display-errors ............. Display details for errors triggered by tests
|
||||
--display-notices ........... Display details for notices triggered by tests
|
||||
--display-warnings ......... Display details for warnings triggered by tests
|
||||
--display-all-issues ..... Display details for all issues that are triggered
|
||||
--reverse-list .............................. Print defects in reverse order
|
||||
--teamcity . Replace default progress and result output with TeamCity format
|
||||
--testdox ................ Replace default result output with TestDox format
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
|
||||
Pest Testing Framework 3.8.1.
|
||||
Pest Testing Framework 3.8.4.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user