mirror of
https://github.com/pestphp/pest.git
synced 2026-09-05 14:23:34 +02:00
chore: coding style changes
This commit is contained in:
@@ -13,15 +13,11 @@ use Pest\Expectation;
|
||||
abstract class AbstractPreset // @pest-arch-ignore-line
|
||||
{
|
||||
/**
|
||||
* The expectations.
|
||||
*
|
||||
* @var array<int, Expectation<mixed>|ArchExpectation>
|
||||
*/
|
||||
protected array $expectations = [];
|
||||
|
||||
/**
|
||||
* Creates a new preset instance.
|
||||
*
|
||||
* @param array<int, string> $userNamespaces
|
||||
*/
|
||||
public function __construct(
|
||||
@@ -31,15 +27,11 @@ abstract class AbstractPreset // @pest-arch-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the arch preset.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract public function execute(): void;
|
||||
|
||||
/**
|
||||
* Ignores the given "targets" or "dependencies".
|
||||
*
|
||||
* @param array<int, string>|string $targetsOrDependencies
|
||||
*/
|
||||
final public function ignoring(array|string $targetsOrDependencies): void
|
||||
@@ -51,8 +43,6 @@ abstract class AbstractPreset // @pest-arch-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given callback for each namespace.
|
||||
*
|
||||
* @param callable(Expectation<string>): ArchExpectation ...$callbacks
|
||||
*/
|
||||
final public function eachUserNamespace(callable ...$callbacks): void
|
||||
@@ -64,9 +54,6 @@ abstract class AbstractPreset // @pest-arch-ignore-line
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the expectations.
|
||||
*/
|
||||
final public function flush(): void
|
||||
{
|
||||
$this->expectations = [];
|
||||
|
||||
@@ -14,8 +14,6 @@ use Pest\Expectation;
|
||||
final class Custom extends AbstractPreset
|
||||
{
|
||||
/**
|
||||
* Creates a new preset instance.
|
||||
*
|
||||
* @param array<int, string> $userNamespaces
|
||||
* @param Closure(array<int, string>): array<Expectation<mixed>|ArchExpectation> $execute
|
||||
*/
|
||||
@@ -27,17 +25,11 @@ final class Custom extends AbstractPreset
|
||||
parent::__construct($userNamespaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the preset.
|
||||
*/
|
||||
public function name(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the arch preset.
|
||||
*/
|
||||
public function execute(): void
|
||||
{
|
||||
$this->expectations = ($this->execute)($this->userNamespaces);
|
||||
|
||||
@@ -11,9 +11,6 @@ use Throwable;
|
||||
*/
|
||||
final class Laravel extends AbstractPreset
|
||||
{
|
||||
/**
|
||||
* Executes the arch preset.
|
||||
*/
|
||||
public function execute(): void
|
||||
{
|
||||
$this->expectations[] = expect('App\Traits')
|
||||
|
||||
@@ -9,9 +9,6 @@ namespace Pest\ArchPresets;
|
||||
*/
|
||||
final class Php extends AbstractPreset
|
||||
{
|
||||
/**
|
||||
* Executes the arch preset.
|
||||
*/
|
||||
public function execute(): void
|
||||
{
|
||||
$this->expectations[] = expect([
|
||||
|
||||
@@ -12,9 +12,6 @@ use Pest\Expectation;
|
||||
*/
|
||||
final class Relaxed extends AbstractPreset
|
||||
{
|
||||
/**
|
||||
* Executes the arch preset.
|
||||
*/
|
||||
public function execute(): void
|
||||
{
|
||||
$this->eachUserNamespace(
|
||||
|
||||
@@ -9,9 +9,6 @@ namespace Pest\ArchPresets;
|
||||
*/
|
||||
final class Security extends AbstractPreset
|
||||
{
|
||||
/**
|
||||
* Executes the arch preset.
|
||||
*/
|
||||
public function execute(): void
|
||||
{
|
||||
$this->expectations[] = expect([
|
||||
|
||||
@@ -12,9 +12,6 @@ use Pest\Expectation;
|
||||
*/
|
||||
final class Strict extends AbstractPreset
|
||||
{
|
||||
/**
|
||||
* Executes the arch preset.
|
||||
*/
|
||||
public function execute(): void
|
||||
{
|
||||
$this->eachUserNamespace(
|
||||
|
||||
@@ -13,8 +13,6 @@ use PHPUnit\Util\ExcludeList;
|
||||
final class BootExcludeList implements Bootstrapper
|
||||
{
|
||||
/**
|
||||
* The directories to exclude.
|
||||
*
|
||||
* @var array<int, non-empty-string>
|
||||
*/
|
||||
private const array EXCLUDE_LIST = [
|
||||
@@ -25,9 +23,6 @@ final class BootExcludeList implements Bootstrapper
|
||||
'stubs',
|
||||
];
|
||||
|
||||
/**
|
||||
* Boots the "exclude list" for PHPUnit to ignore Pest files.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$baseDirectory = dirname(__DIR__, 2);
|
||||
|
||||
@@ -21,8 +21,6 @@ use function Pest\testDirectory;
|
||||
final class BootFiles implements Bootstrapper
|
||||
{
|
||||
/**
|
||||
* The structure of the tests directory.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private const array STRUCTURE = [
|
||||
@@ -33,9 +31,6 @@ final class BootFiles implements Bootstrapper
|
||||
'Pest.php',
|
||||
];
|
||||
|
||||
/**
|
||||
* Boots the structure of the tests directory.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$rootPath = TestSuite::getInstance()->rootPath;
|
||||
@@ -67,9 +62,6 @@ final class BootFiles implements Bootstrapper
|
||||
$this->bootDatasets($testsPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads, if possible, the given file.
|
||||
*/
|
||||
private function load(string $filename): void
|
||||
{
|
||||
if (! Str::endsWith($filename, '.php')) {
|
||||
|
||||
@@ -14,18 +14,12 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
*/
|
||||
final readonly class BootKernelDump implements Bootstrapper
|
||||
{
|
||||
/**
|
||||
* Creates a new Boot Kernel Dump instance.
|
||||
*/
|
||||
public function __construct(
|
||||
private OutputInterface $output,
|
||||
) {
|
||||
// ...
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Boots the kernel dump.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
Container::getInstance()->add(KernelDump::class, $kernelDump = new KernelDump(
|
||||
|
||||
@@ -13,8 +13,6 @@ use Pest\Exceptions\ShouldNotHappen;
|
||||
final class BootOverrides implements Bootstrapper
|
||||
{
|
||||
/**
|
||||
* The list of files to be overridden.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public const array FILES = [
|
||||
@@ -30,9 +28,6 @@ final class BootOverrides implements Bootstrapper
|
||||
'Logging/JUnit/JunitXmlLogger.php',
|
||||
];
|
||||
|
||||
/**
|
||||
* Boots the list of files to be overridden.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
foreach (self::FILES as $file) {
|
||||
|
||||
@@ -16,8 +16,6 @@ use PHPUnit\Event\Subscriber;
|
||||
final readonly class BootSubscribers implements Bootstrapper
|
||||
{
|
||||
/**
|
||||
* The list of Subscribers.
|
||||
*
|
||||
* @var array<int, class-string<Subscriber>>
|
||||
*/
|
||||
private const array SUBSCRIBERS = [
|
||||
@@ -44,16 +42,10 @@ final readonly class BootSubscribers implements Bootstrapper
|
||||
Subscribers\EnsureTiaAssertionsAreRecordedOnFinished::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Creates a new instance of the Boot Subscribers.
|
||||
*/
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Boots the list of Subscribers.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
foreach (self::SUBSCRIBERS as $subscriber) {
|
||||
|
||||
@@ -13,18 +13,12 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
*/
|
||||
final readonly class BootView implements Bootstrapper
|
||||
{
|
||||
/**
|
||||
* Creates a new instance of the Boot View.
|
||||
*/
|
||||
public function __construct(
|
||||
private OutputInterface $output
|
||||
) {
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Boots the view renderer.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
View::renderUsing($this->output);
|
||||
|
||||
@@ -16,22 +16,13 @@ use function Termwind\renderUsing;
|
||||
*/
|
||||
final class Events
|
||||
{
|
||||
/**
|
||||
* Sets the output.
|
||||
*/
|
||||
private static ?OutputInterface $output = null;
|
||||
|
||||
/**
|
||||
* Sets the output.
|
||||
*/
|
||||
public static function setOutput(OutputInterface $output): void
|
||||
{
|
||||
self::$output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires before the test method description is printed.
|
||||
*/
|
||||
public static function beforeTestMethodDescription(TestResult $result, string $description): string
|
||||
{
|
||||
if (($context = $result->context) === []) {
|
||||
@@ -73,9 +64,6 @@ final class Events
|
||||
return $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after the test method description is printed.
|
||||
*/
|
||||
public static function afterTestMethodDescription(TestResult $result): void
|
||||
{
|
||||
if (($context = $result->context) === []) {
|
||||
|
||||
@@ -14,8 +14,6 @@ trait Expectable
|
||||
/**
|
||||
* @template TValue
|
||||
*
|
||||
* Creates a new Expectation.
|
||||
*
|
||||
* @param TValue $value
|
||||
* @return Expectation<TValue>
|
||||
*/
|
||||
|
||||
@@ -14,15 +14,11 @@ use Closure;
|
||||
trait Extendable
|
||||
{
|
||||
/**
|
||||
* The list of extends.
|
||||
*
|
||||
* @var array<string, Closure>
|
||||
*/
|
||||
private static array $extends = [];
|
||||
|
||||
/**
|
||||
* Register a new extend.
|
||||
*
|
||||
* @param-closure-this T $extend
|
||||
*/
|
||||
public function extend(string $name, Closure $extend): void
|
||||
@@ -30,9 +26,6 @@ trait Extendable
|
||||
static::$extends[$name] = $extend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given extend name is registered.
|
||||
*/
|
||||
public static function hasExtend(string $name): bool
|
||||
{
|
||||
return array_key_exists($name, static::$extends);
|
||||
|
||||
@@ -9,33 +9,21 @@ namespace Pest\Concerns\Logging;
|
||||
*/
|
||||
trait WritesToConsole
|
||||
{
|
||||
/**
|
||||
* Writes the given success message to the console.
|
||||
*/
|
||||
private function writeSuccess(string $message): void
|
||||
{
|
||||
$this->writePestTestOutput($message, 'fg-green, bold', '✓');
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given error message to the console.
|
||||
*/
|
||||
private function writeError(string $message): void
|
||||
{
|
||||
$this->writePestTestOutput($message, 'fg-red, bold', '⨯');
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given warning message to the console.
|
||||
*/
|
||||
private function writeWarning(string $message): void
|
||||
{
|
||||
$this->writePestTestOutput($message, 'fg-yellow, bold', '-');
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the give message to the console.
|
||||
*/
|
||||
private function writePestTestOutput(string $message, string $color, string $symbol): void
|
||||
{
|
||||
$this->writeWithColor($color, "$symbol ", false);
|
||||
|
||||
@@ -12,30 +12,21 @@ use Closure;
|
||||
trait Pipeable
|
||||
{
|
||||
/**
|
||||
* The list of pipes.
|
||||
*
|
||||
* @var array<string, array<Closure(Closure, mixed ...$arguments): void>>
|
||||
*/
|
||||
private static array $pipes = [];
|
||||
|
||||
/**
|
||||
* The list of interceptors.
|
||||
*
|
||||
* @var array<string, array<Closure(Closure, mixed ...$arguments): void>>
|
||||
*/
|
||||
private static array $interceptors = [];
|
||||
|
||||
/**
|
||||
* Register a pipe to be applied before an expectation is checked.
|
||||
*/
|
||||
public function pipe(string $name, Closure $pipe): void
|
||||
{
|
||||
self::$pipes[$name][] = $pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an interceptor that should replace an existing expectation.
|
||||
*
|
||||
* @param string|Closure(mixed $value, mixed ...$arguments):bool $filter
|
||||
*/
|
||||
public function intercept(string $name, string|Closure $filter, Closure $handler): void
|
||||
@@ -60,8 +51,6 @@ trait Pipeable
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of pipes by the given name.
|
||||
*
|
||||
* @return array<int, Closure>
|
||||
*/
|
||||
private function pipes(string $name, object $context, string $scope): array
|
||||
|
||||
@@ -11,8 +11,6 @@ trait Retrievable
|
||||
{
|
||||
/**
|
||||
* @template TRetrievableValue
|
||||
*
|
||||
* Safely retrieve the value at the given key from an object or array.
|
||||
* @template TRetrievableValue
|
||||
*
|
||||
* @param array<string, TRetrievableValue>|object $value
|
||||
|
||||
@@ -37,105 +37,53 @@ use Throwable;
|
||||
*/
|
||||
trait Testable
|
||||
{
|
||||
/**
|
||||
* The test's description.
|
||||
*/
|
||||
private string $__description;
|
||||
|
||||
/**
|
||||
* The test's latest description.
|
||||
*/
|
||||
private static string $__latestDescription;
|
||||
|
||||
/**
|
||||
* The test's assignees.
|
||||
*/
|
||||
private static array $__latestAssignees = [];
|
||||
|
||||
/**
|
||||
* The test's notes.
|
||||
*/
|
||||
private static array $__latestNotes = [];
|
||||
|
||||
/**
|
||||
* The test's issues.
|
||||
*
|
||||
* @var array<int, int>
|
||||
*/
|
||||
private static array $__latestIssues = [];
|
||||
|
||||
/**
|
||||
* The test's PRs.
|
||||
*
|
||||
* @var array<int, int>
|
||||
*/
|
||||
private static array $__latestPrs = [];
|
||||
|
||||
/**
|
||||
* The test's describing, if any.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public array $__describing = [];
|
||||
|
||||
/**
|
||||
* Whether the test has ran or not.
|
||||
*/
|
||||
public bool $__ran = false;
|
||||
|
||||
/**
|
||||
* The active replay mode for this test, set in `setUp()` and checked
|
||||
* in `__runTest()` / `tearDown()` to skip the body and after-each.
|
||||
*/
|
||||
private ReplayType $__replay = ReplayType::None;
|
||||
|
||||
/**
|
||||
* The cached assertion count to replay, captured when entering replay mode.
|
||||
*/
|
||||
private int $__replayAssertions = 0;
|
||||
|
||||
/**
|
||||
* The test's test closure.
|
||||
*/
|
||||
private Closure $__test;
|
||||
|
||||
/**
|
||||
* The test's before each closure.
|
||||
*/
|
||||
private ?Closure $__beforeEach = null;
|
||||
|
||||
/**
|
||||
* The test's after each closure.
|
||||
*/
|
||||
private ?Closure $__afterEach = null;
|
||||
|
||||
/**
|
||||
* The test's before all closure.
|
||||
*/
|
||||
private static ?Closure $__beforeAll = null;
|
||||
|
||||
/**
|
||||
* The test's after all closure.
|
||||
*/
|
||||
private static ?Closure $__afterAll = null;
|
||||
|
||||
/**
|
||||
* The list of snapshot changes, if any.
|
||||
*/
|
||||
private array $__snapshotChanges = [];
|
||||
|
||||
/**
|
||||
* Resets the test case static properties.
|
||||
*/
|
||||
public static function flush(): void
|
||||
{
|
||||
self::$__beforeAll = null;
|
||||
self::$__afterAll = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new "note" to the Test Case.
|
||||
*/
|
||||
public function note(array|string $note): self
|
||||
{
|
||||
$note = is_array($note) ? $note : [$note];
|
||||
@@ -145,9 +93,6 @@ trait Testable
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new "setUpBeforeClass" to the Test Case.
|
||||
*/
|
||||
public function __addBeforeAll(?Closure $hook): void
|
||||
{
|
||||
if (! $hook instanceof Closure) {
|
||||
@@ -159,9 +104,6 @@ trait Testable
|
||||
: $hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new "tearDownAfterClass" to the Test Case.
|
||||
*/
|
||||
public function __addAfterAll(?Closure $hook): void
|
||||
{
|
||||
if (! $hook instanceof Closure) {
|
||||
@@ -173,25 +115,16 @@ trait Testable
|
||||
: $hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new "setUp" to the Test Case.
|
||||
*/
|
||||
public function __addBeforeEach(?Closure $hook): void
|
||||
{
|
||||
$this->__addHook('__beforeEach', $hook);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new "tearDown" to the Test Case.
|
||||
*/
|
||||
public function __addAfterEach(?Closure $hook): void
|
||||
{
|
||||
$this->__addHook('__afterEach', $hook);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new "hook" to the Test Case.
|
||||
*/
|
||||
private function __addHook(string $property, ?Closure $hook): void
|
||||
{
|
||||
if (! $hook instanceof Closure) {
|
||||
@@ -203,9 +136,6 @@ trait Testable
|
||||
: $hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called before the first test of this Test Case is run.
|
||||
*/
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
@@ -223,9 +153,6 @@ trait Testable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called after the last test of this Test Case is run.
|
||||
*/
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
$afterAll = TestSuite::getInstance()->afterAll->get(self::$__filename);
|
||||
@@ -239,9 +166,6 @@ trait Testable
|
||||
parent::tearDownAfterClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets executed before the Test Case.
|
||||
*/
|
||||
protected function setUp(...$arguments): void
|
||||
{
|
||||
TestSuite::getInstance()->test = $this;
|
||||
@@ -325,12 +249,8 @@ trait Testable
|
||||
$this->__ran = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize test case properties from TestSuite.
|
||||
*/
|
||||
public function __initializeTestCase(): void
|
||||
{
|
||||
// Return if the test case has already been initialized
|
||||
if (isset($this->__test)) {
|
||||
return;
|
||||
}
|
||||
@@ -352,9 +272,6 @@ trait Testable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets executed after the Test Case.
|
||||
*/
|
||||
protected function tearDown(...$arguments): void
|
||||
{
|
||||
if ($this->__replay !== ReplayType::None) {
|
||||
@@ -382,8 +299,6 @@ trait Testable
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the Test Case current test.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
private function __runTest(Closure $closure, ...$args): mixed
|
||||
@@ -454,9 +369,6 @@ trait Testable
|
||||
throw $lastException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the given exception matches PHPUnit's expected exception.
|
||||
*/
|
||||
private function __isExpectedException(Throwable $e): bool
|
||||
{
|
||||
$expectation = Closure::bind(fn () => $this->exceptionExpectation, $this, TestCase::class)();
|
||||
@@ -491,8 +403,6 @@ trait Testable
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the passed arguments. Any Closures will be bound to the testcase and resolved.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
private function __resolveTestArguments(array $arguments): array
|
||||
@@ -500,10 +410,6 @@ trait Testable
|
||||
$method = TestSuite::getInstance()->tests->get(self::$__filename)->getMethod($this->name());
|
||||
|
||||
if ($method->repetitions > 1) {
|
||||
// If the test is repeated, the first argument is the iteration number
|
||||
// we need to move it to the end of the arguments list
|
||||
// so that the datasets are the first n arguments
|
||||
// and the iteration number is the last argument
|
||||
$firstArgument = array_shift($arguments);
|
||||
$arguments[] = $firstArgument;
|
||||
}
|
||||
@@ -552,8 +458,6 @@ trait Testable
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures dataset items count matches underlying test case required parameters
|
||||
*
|
||||
* @throws ReflectionException
|
||||
* @throws DatasetArgumentsMismatch
|
||||
*/
|
||||
@@ -593,9 +497,6 @@ trait Testable
|
||||
return ExceptionTrace::ensure(fn (): mixed => call_user_func_array(Closure::bind($closure, $this, $this::class), $arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the given preset on the test.
|
||||
*/
|
||||
public function preset(): Preset
|
||||
{
|
||||
return new Preset;
|
||||
@@ -611,33 +512,21 @@ trait Testable
|
||||
$this->markTestIncomplete(implode('. ', $this->__snapshotChanges));
|
||||
}
|
||||
|
||||
/**
|
||||
* The printable test case name.
|
||||
*/
|
||||
public static function getPrintableTestCaseName(): string
|
||||
{
|
||||
return preg_replace('/P\\\/', '', self::class, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* The printable test case method name.
|
||||
*/
|
||||
public function getPrintableTestCaseMethodName(): string
|
||||
{
|
||||
return $this->__description;
|
||||
}
|
||||
|
||||
/**
|
||||
* The latest printable test case method name.
|
||||
*/
|
||||
public static function getLatestPrintableTestCaseMethodName(): string
|
||||
{
|
||||
return self::$__latestDescription ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* The printable test case method context.
|
||||
*/
|
||||
public static function getPrintableContext(): array
|
||||
{
|
||||
return [
|
||||
@@ -648,9 +537,6 @@ trait Testable
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a shell for the test case.
|
||||
*/
|
||||
public function shell(): void
|
||||
{
|
||||
Shell::open();
|
||||
|
||||
@@ -14,31 +14,19 @@ use Pest\PendingCalls\UsesCall;
|
||||
*/
|
||||
final readonly class Configuration
|
||||
{
|
||||
/**
|
||||
* The filename of the configuration.
|
||||
*/
|
||||
private string $filename;
|
||||
|
||||
/**
|
||||
* Creates a new configuration instance.
|
||||
*/
|
||||
public function __construct(
|
||||
string $filename,
|
||||
) {
|
||||
$this->filename = str_ends_with($filename, DIRECTORY_SEPARATOR.'Pest.php') ? dirname($filename) : $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the given classes and traits in the given targets.
|
||||
*/
|
||||
public function in(string ...$targets): UsesCall
|
||||
{
|
||||
return new UsesCall($this->filename, [])->in(...$targets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on where is called, it will extend the given classes and traits globally or locally.
|
||||
*/
|
||||
public function extend(string ...$classAndTraits): UsesCall
|
||||
{
|
||||
return new UsesCall(
|
||||
@@ -47,97 +35,62 @@ final readonly class Configuration
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on where is called, it will extend the given classes and traits globally or locally.
|
||||
*/
|
||||
public function extends(string ...$classAndTraits): UsesCall
|
||||
{
|
||||
return $this->extend(...$classAndTraits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on where is called, it will add the given groups globally or locally.
|
||||
*/
|
||||
public function group(string ...$groups): UsesCall
|
||||
{
|
||||
return new UsesCall($this->filename, [])->group(...$groups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks all tests in the current file to be run exclusively.
|
||||
*/
|
||||
public function only(): void
|
||||
{
|
||||
new BeforeEachCall(TestSuite::getInstance(), $this->filename)->only();
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on where is called, it will extend the given classes and traits globally or locally.
|
||||
*/
|
||||
public function use(string ...$classAndTraits): UsesCall
|
||||
{
|
||||
return $this->extend(...$classAndTraits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on where is called, it will extend the given classes and traits globally or locally.
|
||||
*/
|
||||
public function uses(string ...$classAndTraits): UsesCall
|
||||
{
|
||||
return $this->extends(...$classAndTraits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the printer configuration.
|
||||
*/
|
||||
public function printer(): Configuration\Printer
|
||||
{
|
||||
return new Configuration\Printer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the presets configuration.
|
||||
*/
|
||||
public function presets(): Configuration\Presets
|
||||
{
|
||||
return new Configuration\Presets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the project configuration.
|
||||
*/
|
||||
public function project(): Configuration\Project
|
||||
{
|
||||
return Configuration\Project::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the browser configuration.
|
||||
*/
|
||||
public function browser(): Browser\Configuration
|
||||
{
|
||||
return new Browser\Configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the evals configuration.
|
||||
*/
|
||||
public function evals(): Evals\Configuration // @phpstan-ignore-line
|
||||
{
|
||||
return new Evals\Configuration; // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the TIA (Test Impact Analysis) configuration.
|
||||
*/
|
||||
public function tia(): Plugins\Tia\Configuration
|
||||
{
|
||||
return new Plugins\Tia\Configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxies calls to the uses method.
|
||||
*
|
||||
* @param array<array-key, mixed> $arguments
|
||||
*/
|
||||
public function __call(string $name, array $arguments): mixed
|
||||
|
||||
@@ -9,9 +9,6 @@ use Pest\Preset;
|
||||
|
||||
final class Presets
|
||||
{
|
||||
/**
|
||||
* Creates a custom preset instance, and adds it to the list of presets.
|
||||
*/
|
||||
public function custom(string $name, Closure $execute): void
|
||||
{
|
||||
Preset::custom($name, $execute);
|
||||
|
||||
@@ -11,9 +11,6 @@ use NunoMaduro\Collision\Adapters\Phpunit\Printers\DefaultPrinter;
|
||||
*/
|
||||
final readonly class Printer
|
||||
{
|
||||
/**
|
||||
* Sets the theme to compact.
|
||||
*/
|
||||
public function compact(): self
|
||||
{
|
||||
DefaultPrinter::compact(true);
|
||||
|
||||
@@ -10,42 +10,27 @@ namespace Pest\Configuration;
|
||||
final class Project
|
||||
{
|
||||
/**
|
||||
* The assignees link.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public string $assignees = '';
|
||||
|
||||
/**
|
||||
* The issues link.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public string $issues = '';
|
||||
|
||||
/**
|
||||
* The PRs link.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public string $prs = '';
|
||||
|
||||
/**
|
||||
* The singleton instance.
|
||||
*/
|
||||
private static ?self $instance = null;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the project.
|
||||
*/
|
||||
public static function getInstance(): self
|
||||
{
|
||||
return self::$instance ??= new self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test project to GitHub.
|
||||
*/
|
||||
public function github(string $project): self
|
||||
{
|
||||
$this->issues = "https://github.com/{$project}/issues/%s";
|
||||
@@ -56,12 +41,8 @@ final class Project
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test project to GitLab.
|
||||
*/
|
||||
public function gitlab(string $project, string $hostname = 'gitlab.com'): self
|
||||
{
|
||||
// Simple way to ensure only the host is used
|
||||
$hostname = parse_url($hostname, PHP_URL_HOST) ?? $hostname;
|
||||
|
||||
$this->issues = "https://{$hostname}/{$project}/-/work_items/%s";
|
||||
@@ -72,9 +53,6 @@ final class Project
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test project to Bitbucket.
|
||||
*/
|
||||
public function bitbucket(string $project): self
|
||||
{
|
||||
$this->issues = "https://bitbucket.org/{$project}/issues/%s";
|
||||
@@ -85,9 +63,6 @@ final class Project
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test project to Jira.
|
||||
*/
|
||||
public function jira(string $namespace, string $project): self
|
||||
{
|
||||
$this->issues = "https://{$namespace}.atlassian.net/browse/{$project}-%s";
|
||||
@@ -97,9 +72,6 @@ final class Project
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test project to custom.
|
||||
*/
|
||||
public function custom(string $issues, string $prs, string $assignees): self
|
||||
{
|
||||
$this->issues = $issues;
|
||||
|
||||
@@ -12,8 +12,6 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
final readonly class Help
|
||||
{
|
||||
/**
|
||||
* The Command messages.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private const array HELP_MESSAGES = [
|
||||
@@ -24,17 +22,11 @@ final readonly class Help
|
||||
' <info>--group=<fg=cyan><name></></info> Only runs tests from the specified group(s)',
|
||||
];
|
||||
|
||||
/**
|
||||
* Creates a new Console Command instance.
|
||||
*/
|
||||
public function __construct(private OutputInterface $output)
|
||||
{
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the Console Command.
|
||||
*/
|
||||
public function __invoke(): void
|
||||
{
|
||||
foreach (self::HELP_MESSAGES as $message) {
|
||||
|
||||
@@ -18,8 +18,6 @@ use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
final readonly class Thanks
|
||||
{
|
||||
/**
|
||||
* The support options.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private const array FUNDING_MESSAGES = [
|
||||
@@ -33,19 +31,13 @@ final readonly class Thanks
|
||||
'Sponsor' => 'https://github.com/sponsors/nunomaduro',
|
||||
];
|
||||
|
||||
/**
|
||||
* Creates a new Console Command instance.
|
||||
*/
|
||||
public function __construct(
|
||||
private InputInterface $input,
|
||||
private OutputInterface $output
|
||||
) {
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the Console Command.
|
||||
*/
|
||||
public function __invoke(): void
|
||||
{
|
||||
$bootstrapper = new BootView($this->output);
|
||||
|
||||
@@ -9,8 +9,5 @@ namespace Pest\Contracts;
|
||||
*/
|
||||
interface Bootstrapper
|
||||
{
|
||||
/**
|
||||
* Boots the bootstrapper.
|
||||
*/
|
||||
public function boot(): void;
|
||||
}
|
||||
|
||||
@@ -11,5 +11,5 @@ use NunoMaduro\Collision\Contracts\Adapters\Phpunit\HasPrintableTestCaseName as
|
||||
*/
|
||||
interface HasPrintableTestCaseName extends BaseHasPrintableTestCaseName
|
||||
{
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
@@ -11,13 +11,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
*/
|
||||
interface Panicable
|
||||
{
|
||||
/**
|
||||
* Renders the panic on the given output.
|
||||
*/
|
||||
public function render(OutputInterface $output): void;
|
||||
|
||||
/**
|
||||
* The exit code to be used.
|
||||
*/
|
||||
public function exitCode(): int;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,5 @@ namespace Pest\Contracts\Plugins;
|
||||
*/
|
||||
interface AddsOutput
|
||||
{
|
||||
/**
|
||||
* Adds output after the Test Suite execution.
|
||||
*/
|
||||
public function addOutput(int $exitCode): int;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,5 @@ namespace Pest\Contracts\Plugins;
|
||||
*/
|
||||
interface Bootable
|
||||
{
|
||||
/**
|
||||
* Boots the plugin.
|
||||
*/
|
||||
public function boot(): void;
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace Pest\Contracts\Plugins;
|
||||
interface HandlesArguments
|
||||
{
|
||||
/**
|
||||
* Adds arguments before the Test Suite execution.
|
||||
*
|
||||
* @param array<int, string> $arguments
|
||||
* @return array<int, string>
|
||||
*/
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace Pest\Contracts\Plugins;
|
||||
interface HandlesOriginalArguments
|
||||
{
|
||||
/**
|
||||
* Adds original arguments before the Test Suite execution.
|
||||
*
|
||||
* @param array<int, string> $arguments
|
||||
*/
|
||||
public function handleOriginalArguments(array $arguments): void;
|
||||
|
||||
@@ -9,8 +9,5 @@ namespace Pest\Contracts\Plugins;
|
||||
*/
|
||||
interface Terminable
|
||||
{
|
||||
/**
|
||||
* Terminates the plugin.
|
||||
*/
|
||||
public function terminate(): void;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,5 @@ namespace Pest\Contracts;
|
||||
|
||||
interface TestCaseFilter
|
||||
{
|
||||
/**
|
||||
* Whether the test case is accepted.
|
||||
*/
|
||||
public function accept(string $testCaseFilename): bool;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,5 @@ use Pest\Factories\TestCaseMethodFactory;
|
||||
|
||||
interface TestCaseMethodFilter
|
||||
{
|
||||
/**
|
||||
* Whether the test case method is accepted.
|
||||
*/
|
||||
public function accept(TestCaseMethodFactory $factory): bool;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ use Pest\Factories\Attribute;
|
||||
final class Attributes
|
||||
{
|
||||
/**
|
||||
* Evaluates the given attributes and returns the code.
|
||||
*
|
||||
* @param iterable<int, Attribute> $attributes
|
||||
*/
|
||||
public static function code(iterable $attributes): string
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class AfterAllAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $filename)
|
||||
{
|
||||
parent::__construct(sprintf('The afterAll already exists in the filename [%s].', $filename));
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class AfterAllWithinDescribe extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $filename)
|
||||
{
|
||||
parent::__construct(sprintf('The afterAll method can not be used within describe functions. Filename [%s].', $filename));
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class AfterBeforeTestFunction extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $filename)
|
||||
{
|
||||
parent::__construct('After method cannot be used with before the [test|it] functions in the filename ['.$filename.'].');
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class BeforeAllAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $filename)
|
||||
{
|
||||
parent::__construct(sprintf('The beforeAll already exists in the filename [%s].', $filename));
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class BeforeAllWithinDescribe extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $filename)
|
||||
{
|
||||
parent::__construct(sprintf('The beforeAll method can not be used within describe functions. Filename [%s].', $filename));
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class DatasetAlreadyExists extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $name, string $scope)
|
||||
{
|
||||
parent::__construct(sprintf('A dataset with the name [%s] already exists in scope [%s].', $name, $scope));
|
||||
|
||||
@@ -16,6 +16,4 @@ final class DatasetArgumentsMismatch extends Exception
|
||||
parent::__construct(sprintf('Test expects %d arguments but dataset only provides %d', $requiredCount, $suppliedCount));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class DatasetDoesNotExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $name)
|
||||
{
|
||||
parent::__construct(sprintf("A dataset with the name [%s] does not exist. You can create it using `dataset('%s', ['a', 'b']);`.", $name, $name));
|
||||
|
||||
@@ -15,8 +15,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
final class DatasetMissing extends BadFunctionCallException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*
|
||||
* @param array<string, string> $arguments
|
||||
*/
|
||||
public function __construct(string $file, string $name, array $arguments)
|
||||
|
||||
@@ -11,9 +11,6 @@ use Exception;
|
||||
*/
|
||||
final class ExpectationNotFound extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates a new ExpectationNotFound instance from the given name.
|
||||
*/
|
||||
public static function fromName(string $name): ExpectationNotFound
|
||||
{
|
||||
return new self("Expectation [$name] does not exist.");
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class FileOrFolderNotFound extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $filename)
|
||||
{
|
||||
parent::__construct(sprintf('The file or folder with the name [%s] could not be found.', $filename));
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $message)
|
||||
{
|
||||
parent::__construct($message, 1);
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class InvalidOption extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $message)
|
||||
{
|
||||
parent::__construct($message, 1);
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class InvalidPestCommand extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('Please run [./vendor/bin/pest] instead.');
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class InvalidTestClassName extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance for the given class name.
|
||||
*/
|
||||
public static function fromClassName(string $filename, string $className): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
@@ -26,9 +23,6 @@ final class InvalidTestClassName extends InvalidArgumentException implements Exc
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Exception instance for the given namespace.
|
||||
*/
|
||||
public static function fromNamespace(string $filename, string $namespace, string $part): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class MissingDependency extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $feature, string $dependency)
|
||||
{
|
||||
parent::__construct(sprintf('The feature [%s] requires [%s].', $feature, $dependency));
|
||||
|
||||
@@ -16,9 +16,6 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
*/
|
||||
final class NoDirtyTestsFound extends InvalidArgumentException implements ExceptionInterface, Panicable, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Renders the panic on the given output.
|
||||
*/
|
||||
public function render(OutputInterface $output): void
|
||||
{
|
||||
$output->writeln([
|
||||
@@ -28,9 +25,6 @@ final class NoDirtyTestsFound extends InvalidArgumentException implements Except
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The exit code to be used.
|
||||
*/
|
||||
public function exitCode(): int
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -12,9 +12,6 @@ use RuntimeException;
|
||||
*/
|
||||
final class ShouldNotHappen extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(Exception $exception)
|
||||
{
|
||||
$message = $exception->getMessage();
|
||||
@@ -29,9 +26,6 @@ EOF
|
||||
, $message, phpversion(), PHP_OS), 1, $exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of should not happen without a specific exception.
|
||||
*/
|
||||
public static function fromMessage(string $message): ShouldNotHappen
|
||||
{
|
||||
return new ShouldNotHappen(new Exception($message));
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class TestAlreadyExist extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $fileName, string $description)
|
||||
{
|
||||
parent::__construct(sprintf('A test with the description [%s] already exists in the filename [%s].', $description, $fileName));
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class TestCaseAlreadyInUse extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $inUse, string $newOne, string $folder)
|
||||
{
|
||||
parent::__construct(sprintf(
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class TestCaseClassOrTraitNotFound extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $testCaseClass)
|
||||
{
|
||||
parent::__construct(sprintf('The class [%s] was not found.', $testCaseClass));
|
||||
|
||||
@@ -15,9 +15,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class TestClosureMustNotBeStatic extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(TestCaseMethodFactory $method)
|
||||
{
|
||||
parent::__construct(
|
||||
|
||||
@@ -14,9 +14,6 @@ use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
*/
|
||||
final class TestDescriptionMissing extends InvalidArgumentException implements ExceptionInterface, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
/**
|
||||
* Creates a new Exception instance.
|
||||
*/
|
||||
public function __construct(string $fileName)
|
||||
{
|
||||
parent::__construct(sprintf('Test description is missing in the filename [%s].', $fileName));
|
||||
|
||||
+1
-198
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace Pest;
|
||||
|
||||
use Attribute;
|
||||
use BadMethodCallException;
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
@@ -60,19 +59,15 @@ final class Expectation
|
||||
use Retrievable;
|
||||
|
||||
/**
|
||||
* Creates a new expectation.
|
||||
*
|
||||
* @param TValue $value
|
||||
*/
|
||||
public function __construct(
|
||||
public mixed $value
|
||||
) {
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new expectation.
|
||||
*
|
||||
* @template TAndValue
|
||||
*
|
||||
* @param TAndValue $value
|
||||
@@ -84,8 +79,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new expectation with the decoded JSON value.
|
||||
*
|
||||
* @return self<array<int|string, mixed>|bool>
|
||||
*/
|
||||
public function json(): Expectation
|
||||
@@ -103,8 +96,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the expectation value.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function dump(mixed ...$arguments): self
|
||||
@@ -118,9 +109,6 @@ final class Expectation
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the expectation value and end the script.
|
||||
*/
|
||||
public function dd(mixed ...$arguments): never
|
||||
{
|
||||
if (function_exists('dd')) {
|
||||
@@ -141,8 +129,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the expectation value when the result of the condition is truthy.
|
||||
*
|
||||
* @param (Closure(TValue): bool)|bool $condition
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -158,8 +144,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the expectation value when the result of the condition is falsy.
|
||||
*
|
||||
* @param (Closure(TValue): bool)|bool $condition
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -175,8 +159,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the expectation value to Ray along with all given arguments.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function ray(mixed ...$arguments): self
|
||||
@@ -189,8 +171,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the opposite expectation for the value.
|
||||
*
|
||||
* @return OppositeExpectation<TValue>
|
||||
*/
|
||||
public function not(): OppositeExpectation
|
||||
@@ -199,8 +179,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an expectation on each item of the iterable "value".
|
||||
*
|
||||
* @return EachExpectation<TValue>
|
||||
*/
|
||||
public function each(?callable $callback = null): EachExpectation
|
||||
@@ -219,8 +197,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to specify a sequential set of expectations for each item in a iterable "value".
|
||||
*
|
||||
* @template TSequenceValue
|
||||
*
|
||||
* @param (callable(self<TValue>, self<string|int>): void)|TSequenceValue ...$callbacks
|
||||
@@ -258,8 +234,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* If the subject matches one of the given "expressions", the expression callback will run.
|
||||
*
|
||||
* @template TMatchSubject of array-key
|
||||
*
|
||||
* @param (callable(): TMatchSubject)|TMatchSubject $subject
|
||||
@@ -298,8 +272,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the callback if the given "condition" is falsy.
|
||||
*
|
||||
* @param (callable(): bool)|bool $condition
|
||||
* @param callable(Expectation<TValue>): mixed $callback
|
||||
* @return self<TValue>
|
||||
@@ -314,8 +286,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the callback if the given "condition" is truthy.
|
||||
*
|
||||
* @param (callable(): bool)|bool $condition
|
||||
* @param callable(self<TValue>): mixed $callback
|
||||
* @return self<TValue>
|
||||
@@ -334,8 +304,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically calls methods on the class or creates a new higher order expectation.
|
||||
*
|
||||
* @param array<int, mixed> $parameters
|
||||
* @return Expectation<TValue>|HigherOrderExpectation<Expectation<TValue>, TValue>
|
||||
*/
|
||||
@@ -379,8 +347,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new expectation closure from the given name.
|
||||
*
|
||||
* @throws ExpectationNotFound
|
||||
*/
|
||||
private function getExpectationClosure(string $name): Closure
|
||||
@@ -402,8 +368,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically calls methods on the class without any arguments or creates a new higher order expectation.
|
||||
*
|
||||
* @return Expectation<TValue>|OppositeExpectation<TValue>|EachExpectation<TValue>|HigherOrderExpectation<Expectation<TValue>, TValue|null>|TValue
|
||||
*/
|
||||
public function __get(string $name): mixed
|
||||
@@ -422,9 +386,6 @@ final class Expectation
|
||||
return $this->{$name}();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given expectation method exists.
|
||||
*/
|
||||
public static function hasMethod(string $name): bool
|
||||
{
|
||||
return method_exists(self::class, $name)
|
||||
@@ -432,17 +393,12 @@ final class Expectation
|
||||
|| self::hasExtend($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches any value.
|
||||
*/
|
||||
public function any(): Any
|
||||
{
|
||||
return new Any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target use the given dependencies.
|
||||
*
|
||||
* @param array<int, string>|string $targets
|
||||
*/
|
||||
public function toUse(array|string $targets): ArchExpectation
|
||||
@@ -450,9 +406,6 @@ final class Expectation
|
||||
return ToUse::make($this, $targets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does have the given permissions
|
||||
*/
|
||||
public function toHaveFileSystemPermissions(string $permissions): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -463,9 +416,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to have line count less than the given number.
|
||||
*/
|
||||
public function toHaveLineCountLessThan(int $lines): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -476,9 +426,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target have all methods documented.
|
||||
*/
|
||||
public function toHaveMethodsDocumented(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -495,9 +442,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target have all properties documented.
|
||||
*/
|
||||
public function toHavePropertiesDocumented(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -515,9 +459,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target use the "declare(strict_types=1)" declaration.
|
||||
*/
|
||||
public function toUseStrictTypes(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -528,9 +469,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target uses strict equality.
|
||||
*/
|
||||
public function toUseStrictEquality(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -541,9 +479,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is final.
|
||||
*/
|
||||
public function toBeFinal(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -554,9 +489,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is readonly.
|
||||
*/
|
||||
public function toBeReadonly(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -567,9 +499,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is trait.
|
||||
*/
|
||||
public function toBeTrait(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -580,17 +509,11 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are traits.
|
||||
*/
|
||||
public function toBeTraits(): ArchExpectation
|
||||
{
|
||||
return $this->toBeTrait();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is abstract.
|
||||
*/
|
||||
public function toBeAbstract(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -602,8 +525,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target has a specific method.
|
||||
*
|
||||
* @param array<int, string>|string $method
|
||||
*/
|
||||
public function toHaveMethod(array|string $method): ArchExpectation
|
||||
@@ -619,8 +540,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target has a specific methods.
|
||||
*
|
||||
* @param array<int, string> $methods
|
||||
*/
|
||||
public function toHaveMethods(array $methods): ArchExpectation
|
||||
@@ -628,57 +547,36 @@ final class Expectation
|
||||
return $this->toHaveMethod($methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toHavePublicMethodsBesides(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['toHavePublicMethodsBesides']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toHavePublicMethods(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['toHavePublicMethods']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toHaveProtectedMethodsBesides(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['toHaveProtectedMethodsBesides']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toHaveProtectedMethods(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['toHaveProtectedMethods']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toHavePrivateMethodsBesides(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['toHavePrivateMethodsBesides']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toHavePrivateMethods(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['toHavePrivateMethods']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is cased correctly.
|
||||
*/
|
||||
public function toBeCasedCorrectly(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -711,9 +609,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is enum.
|
||||
*/
|
||||
public function toBeEnum(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -724,17 +619,11 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are enums.
|
||||
*/
|
||||
public function toBeEnums(): ArchExpectation
|
||||
{
|
||||
return $this->toBeEnum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is a class.
|
||||
*/
|
||||
public function toBeClass(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -745,17 +634,11 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are classes.
|
||||
*/
|
||||
public function toBeClasses(): ArchExpectation
|
||||
{
|
||||
return $this->toBeClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is interface.
|
||||
*/
|
||||
public function toBeInterface(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -766,17 +649,11 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are interfaces.
|
||||
*/
|
||||
public function toBeInterfaces(): ArchExpectation
|
||||
{
|
||||
return $this->toBeInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to be subclass of the given class.
|
||||
*/
|
||||
public function toExtend(string $class): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -787,9 +664,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to be have a parent class.
|
||||
*/
|
||||
public function toExtendNothing(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -800,17 +674,12 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to use the given trait.
|
||||
*/
|
||||
public function toUseTrait(string $trait): ArchExpectation
|
||||
{
|
||||
return $this->toUseTraits($trait);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to use the given traits.
|
||||
*
|
||||
* @param array<int, string>|string $traits
|
||||
*/
|
||||
public function toUseTraits(array|string $traits): ArchExpectation
|
||||
@@ -852,9 +721,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to not implement any interfaces.
|
||||
*/
|
||||
public function toImplementNothing(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -866,8 +732,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to only implement the given interfaces.
|
||||
*
|
||||
* @param array<int, string>|string $interfaces
|
||||
*/
|
||||
public function toOnlyImplement(array|string $interfaces): ArchExpectation
|
||||
@@ -884,9 +748,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to have the given prefix.
|
||||
*/
|
||||
public function toHavePrefix(string $prefix): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -897,9 +758,6 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to have the given suffix.
|
||||
*/
|
||||
public function toHaveSuffix(string $suffix): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -911,8 +769,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to implement the given interfaces.
|
||||
*
|
||||
* @param array<int, string>|string $interfaces
|
||||
*/
|
||||
public function toImplement(array|string $interfaces): ArchExpectation
|
||||
@@ -928,8 +784,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target "only" use on the given dependencies.
|
||||
*
|
||||
* @param array<int, string>|string $targets
|
||||
*/
|
||||
public function toOnlyUse(array|string $targets): ArchExpectation
|
||||
@@ -937,33 +791,22 @@ final class Expectation
|
||||
return ToOnlyUse::make($this, $targets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not use any dependencies.
|
||||
*/
|
||||
public function toUseNothing(): ArchExpectation
|
||||
{
|
||||
return ToUseNothing::make($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the source code of the given expectation target does not include suspicious characters.
|
||||
*/
|
||||
public function toHaveSuspiciousCharacters(): ArchExpectation
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['toHaveSuspiciousCharacters']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toBeUsed(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['toBeUsed']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation dependency is used by the given targets.
|
||||
*
|
||||
* @param array<int, string>|string $targets
|
||||
*/
|
||||
public function toBeUsedIn(array|string $targets): ArchExpectation
|
||||
@@ -972,8 +815,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation dependency is "only" used by the given targets.
|
||||
*
|
||||
* @param array<int, string>|string $targets
|
||||
*/
|
||||
public function toOnlyBeUsedIn(array|string $targets): ArchExpectation
|
||||
@@ -981,17 +822,11 @@ final class Expectation
|
||||
return ToOnlyBeUsedIn::make($this, $targets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation dependency is not used.
|
||||
*/
|
||||
public function toBeUsedInNothing(): ArchExpectation
|
||||
{
|
||||
return ToBeUsedInNothing::make($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation dependency is an invokable class.
|
||||
*/
|
||||
public function toBeInvokable(): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -1003,8 +838,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation is iterable and contains snake_case keys.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toHaveSnakeCaseKeys(string $message = ''): self
|
||||
@@ -1027,8 +860,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation is iterable and contains kebab-case keys.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toHaveKebabCaseKeys(string $message = ''): self
|
||||
@@ -1051,8 +882,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation is iterable and contains camelCase keys.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toHaveCamelCaseKeys(string $message = ''): self
|
||||
@@ -1075,8 +904,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation is iterable and contains StudlyCase keys.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toHaveStudlyCaseKeys(string $message = ''): self
|
||||
@@ -1098,9 +925,6 @@ final class Expectation
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to have the given attribute.
|
||||
*/
|
||||
public function toHaveAttribute(string $attribute): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -1111,25 +935,16 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target has a constructor method.
|
||||
*/
|
||||
public function toHaveConstructor(): ArchExpectation
|
||||
{
|
||||
return $this->toHaveMethod('__construct');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target has a destructor method.
|
||||
*/
|
||||
public function toHaveDestructor(): ArchExpectation
|
||||
{
|
||||
return $this->toHaveMethod('__destruct');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is a backed enum of given type.
|
||||
*/
|
||||
private function toBeBackedEnum(string $backingType): ArchExpectation
|
||||
{
|
||||
return Targeted::make(
|
||||
@@ -1143,33 +958,21 @@ final class Expectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are string backed enums.
|
||||
*/
|
||||
public function toBeStringBackedEnums(): ArchExpectation
|
||||
{
|
||||
return $this->toBeStringBackedEnum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are int backed enums.
|
||||
*/
|
||||
public function toBeIntBackedEnums(): ArchExpectation
|
||||
{
|
||||
return $this->toBeIntBackedEnum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is a string backed enum.
|
||||
*/
|
||||
public function toBeStringBackedEnum(): ArchExpectation
|
||||
{
|
||||
return $this->toBeBackedEnum('string');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is an int backed enum.
|
||||
*/
|
||||
public function toBeIntBackedEnum(): ArchExpectation
|
||||
{
|
||||
return $this->toBeBackedEnum('int');
|
||||
|
||||
@@ -17,21 +17,14 @@ use function expect;
|
||||
*/
|
||||
final class EachExpectation
|
||||
{
|
||||
/**
|
||||
* Indicates if the expectation is the opposite.
|
||||
*/
|
||||
private bool $opposite = false;
|
||||
|
||||
/**
|
||||
* Creates an expectation on each item of the iterable "value".
|
||||
*
|
||||
* @param Expectation<TValue> $original
|
||||
*/
|
||||
public function __construct(private readonly Expectation $original) {}
|
||||
|
||||
/**
|
||||
* Creates a new expectation.
|
||||
*
|
||||
* @template TAndValue
|
||||
*
|
||||
* @param TAndValue $value
|
||||
@@ -43,8 +36,6 @@ final class EachExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the opposite expectation for the value.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function not(): self
|
||||
@@ -55,8 +46,6 @@ final class EachExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically calls methods on the class with the given arguments on each item.
|
||||
*
|
||||
* @param array<int|string, mixed> $arguments
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -73,8 +62,6 @@ final class EachExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically calls methods on the class without any arguments on each item.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function __get(string $name): self
|
||||
|
||||
@@ -25,19 +25,11 @@ final class HigherOrderExpectation
|
||||
*/
|
||||
private Expectation|EachExpectation $expectation;
|
||||
|
||||
/**
|
||||
* Indicates if the expectation is the opposite.
|
||||
*/
|
||||
private bool $opposite = false;
|
||||
|
||||
/**
|
||||
* Indicates if the expectation should reset the value.
|
||||
*/
|
||||
private bool $shouldReset = false;
|
||||
|
||||
/**
|
||||
* Creates a new higher order expectation.
|
||||
*
|
||||
* @param Expectation<TOriginalValue> $original
|
||||
* @param TValue $value
|
||||
*/
|
||||
@@ -47,8 +39,6 @@ final class HigherOrderExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the opposite expectation for the value.
|
||||
*
|
||||
* @return self<TOriginalValue, TValue>
|
||||
*/
|
||||
public function not(): self
|
||||
@@ -59,8 +49,6 @@ final class HigherOrderExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Expectation.
|
||||
*
|
||||
* @template TExpectValue
|
||||
*
|
||||
* @param TExpectValue $value
|
||||
@@ -72,8 +60,6 @@ final class HigherOrderExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new expectation.
|
||||
*
|
||||
* @template TExpectValue
|
||||
*
|
||||
* @param TExpectValue $value
|
||||
@@ -85,9 +71,6 @@ final class HigherOrderExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope an expectation callback to the current value in
|
||||
* the HigherOrderExpectation chain.
|
||||
*
|
||||
* @param Closure(Expectation<TValue>): void $expectation
|
||||
* @return HigherOrderExpectation<TOriginalValue, TOriginalValue>
|
||||
*/
|
||||
@@ -99,8 +82,6 @@ final class HigherOrderExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new expectation with the decoded JSON value.
|
||||
*
|
||||
* @return self<TOriginalValue, array<string|int, mixed>|bool>
|
||||
*/
|
||||
public function json(): self
|
||||
@@ -109,8 +90,6 @@ final class HigherOrderExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically calls methods on the class with the given arguments.
|
||||
*
|
||||
* @param array<int, mixed> $arguments
|
||||
* @return self<TOriginalValue, mixed>
|
||||
*/
|
||||
@@ -125,8 +104,6 @@ final class HigherOrderExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Accesses properties in the value or in the expectation.
|
||||
*
|
||||
* @return self<TOriginalValue, mixed>
|
||||
*/
|
||||
public function __get(string $name): self
|
||||
@@ -145,9 +122,6 @@ final class HigherOrderExpectation
|
||||
return $this->performAssertion($name, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the original expectation has the given method name.
|
||||
*/
|
||||
private function expectationHasMethod(string $name): bool
|
||||
{
|
||||
if (method_exists($this->original, $name)) {
|
||||
@@ -161,8 +135,6 @@ final class HigherOrderExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the applicable value based on the current reset condition.
|
||||
*
|
||||
* @return TOriginalValue|TValue
|
||||
*/
|
||||
private function getValue(): mixed
|
||||
@@ -171,8 +143,6 @@ final class HigherOrderExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given assertion with the current expectation.
|
||||
*
|
||||
* @param array<int, mixed> $arguments
|
||||
* @return self<TOriginalValue, TValue>
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace Pest\Expectations;
|
||||
|
||||
use Attribute;
|
||||
use Pest\Arch\Contracts\ArchExpectation;
|
||||
use Pest\Arch\Expectations\Targeted;
|
||||
use Pest\Arch\Expectations\ToBeUsedIn;
|
||||
@@ -38,15 +37,11 @@ use stdClass;
|
||||
final readonly class OppositeExpectation
|
||||
{
|
||||
/**
|
||||
* Creates a new opposite expectation.
|
||||
*
|
||||
* @param Expectation<TValue> $original
|
||||
*/
|
||||
public function __construct(private Expectation $original) {}
|
||||
|
||||
/**
|
||||
* Asserts that the value array not has the provided $keys.
|
||||
*
|
||||
* @param array<int, int|string|array<int-string, mixed>> $keys
|
||||
* @return Expectation<TValue>
|
||||
*/
|
||||
@@ -70,8 +65,6 @@ final readonly class OppositeExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not use any of the given dependencies.
|
||||
*
|
||||
* @param array<int, string>|string $targets
|
||||
*/
|
||||
public function toUse(array|string $targets): ArchExpectation
|
||||
@@ -84,9 +77,6 @@ final readonly class OppositeExpectation
|
||||
), is_string($targets) ? [$targets] : $targets));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not have the given permissions
|
||||
*/
|
||||
public function toHaveFileSystemPermissions(string $permissions): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -100,17 +90,11 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toHaveLineCountLessThan(): ArchExpectation
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['not', 'toHaveLineCountLessThan']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toHaveMethodsDocumented(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -130,9 +114,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toHavePropertiesDocumented(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -153,9 +134,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not use the "declare(strict_types=1)" declaration.
|
||||
*/
|
||||
public function toUseStrictTypes(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -169,9 +147,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not use the strict equality operator.
|
||||
*/
|
||||
public function toUseStrictEquality(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -185,9 +160,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not final.
|
||||
*/
|
||||
public function toBeFinal(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -201,9 +173,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not readonly.
|
||||
*/
|
||||
public function toBeReadonly(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -217,9 +186,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not trait.
|
||||
*/
|
||||
public function toBeTrait(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -233,17 +199,11 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are not traits.
|
||||
*/
|
||||
public function toBeTraits(): ArchExpectation
|
||||
{
|
||||
return $this->toBeTrait();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not abstract.
|
||||
*/
|
||||
public function toBeAbstract(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -258,8 +218,6 @@ final readonly class OppositeExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not have a specific method.
|
||||
*
|
||||
* @param array<int, string>|string $method
|
||||
*/
|
||||
public function toHaveMethod(array|string $method): ArchExpectation
|
||||
@@ -280,9 +238,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not have suspicious characters.
|
||||
*/
|
||||
public function toHaveSuspiciousCharacters(): ArchExpectation
|
||||
{
|
||||
if (! class_exists(Spoofchecker::class)) {
|
||||
@@ -303,8 +258,6 @@ final readonly class OppositeExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not have the given methods.
|
||||
*
|
||||
* @param array<int, string> $methods
|
||||
*/
|
||||
public function toHaveMethods(array $methods): ArchExpectation
|
||||
@@ -313,8 +266,6 @@ final readonly class OppositeExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to have the public methods besides the given methods.
|
||||
*
|
||||
* @param array<int, string>|string $methods
|
||||
*/
|
||||
public function toHavePublicMethodsBesides(array|string $methods): ArchExpectation
|
||||
@@ -350,17 +301,12 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to have the public methods.
|
||||
*/
|
||||
public function toHavePublicMethods(): ArchExpectation
|
||||
{
|
||||
return $this->toHavePublicMethodsBesides([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to have the protected methods besides the given methods.
|
||||
*
|
||||
* @param array<int, string>|string $methods
|
||||
*/
|
||||
public function toHaveProtectedMethodsBesides(array|string $methods): ArchExpectation
|
||||
@@ -396,17 +342,12 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to have the protected methods.
|
||||
*/
|
||||
public function toHaveProtectedMethods(): ArchExpectation
|
||||
{
|
||||
return $this->toHaveProtectedMethodsBesides([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to have the private methods besides the given methods.
|
||||
*
|
||||
* @param array<int, string>|string $methods
|
||||
*/
|
||||
public function toHavePrivateMethodsBesides(array|string $methods): ArchExpectation
|
||||
@@ -442,17 +383,11 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to have the private methods.
|
||||
*/
|
||||
public function toHavePrivateMethods(): ArchExpectation
|
||||
{
|
||||
return $this->toHavePrivateMethodsBesides([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not enum.
|
||||
*/
|
||||
public function toBeEnum(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -466,17 +401,11 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are not enums.
|
||||
*/
|
||||
public function toBeEnums(): ArchExpectation
|
||||
{
|
||||
return $this->toBeEnum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets is not class.
|
||||
*/
|
||||
public function toBeClass(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -490,17 +419,11 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are not classes.
|
||||
*/
|
||||
public function toBeClasses(): ArchExpectation
|
||||
{
|
||||
return $this->toBeClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not interface.
|
||||
*/
|
||||
public function toBeInterface(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -514,17 +437,11 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are not interfaces.
|
||||
*/
|
||||
public function toBeInterfaces(): ArchExpectation
|
||||
{
|
||||
return $this->toBeInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to be not subclass of the given class.
|
||||
*/
|
||||
public function toExtend(string $class): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -538,9 +455,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to be not have any parent class.
|
||||
*/
|
||||
public function toExtendNothing(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -554,17 +468,12 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to use the given trait.
|
||||
*/
|
||||
public function toUseTrait(string $trait): ArchExpectation
|
||||
{
|
||||
return $this->toUseTraits($trait);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to use the given traits.
|
||||
*
|
||||
* @param array<int, string>|string $traits
|
||||
*/
|
||||
public function toUseTraits(array|string $traits): ArchExpectation
|
||||
@@ -583,8 +492,6 @@ final readonly class OppositeExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to implement the given interfaces.
|
||||
*
|
||||
* @param array<int, string>|string $interfaces
|
||||
*/
|
||||
public function toImplement(array|string $interfaces): ArchExpectation
|
||||
@@ -602,9 +509,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to not implement any interfaces.
|
||||
*/
|
||||
public function toImplementNothing(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -618,17 +522,11 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toOnlyImplement(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['not', 'toOnlyImplement']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to not have the given prefix.
|
||||
*/
|
||||
public function toHavePrefix(string $prefix): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -642,9 +540,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target to not have the given suffix.
|
||||
*/
|
||||
public function toHaveSuffix(string $suffix): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -658,25 +553,16 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toOnlyUse(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['not', 'toOnlyUse']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported.
|
||||
*/
|
||||
public function toUseNothing(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['not', 'toUseNothing']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation dependency is not used.
|
||||
*/
|
||||
public function toBeUsed(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -686,8 +572,6 @@ final readonly class OppositeExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation dependency is not used by any of the given targets.
|
||||
*
|
||||
* @param array<int, string>|string $targets
|
||||
*/
|
||||
public function toBeUsedIn(array|string $targets): ArchExpectation
|
||||
@@ -705,17 +589,11 @@ final readonly class OppositeExpectation
|
||||
throw InvalidExpectation::fromMethods(['not', 'toOnlyBeUsedIn']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation dependency is not used.
|
||||
*/
|
||||
public function toBeUsedInNothing(): void
|
||||
{
|
||||
throw InvalidExpectation::fromMethods(['not', 'toBeUsedInNothing']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation dependency is not an invokable class.
|
||||
*/
|
||||
public function toBeInvokable(): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -729,9 +607,6 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target not to have the given attribute.
|
||||
*/
|
||||
public function toHaveAttribute(string $attribute): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -746,8 +621,6 @@ final readonly class OppositeExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle dynamic method calls into the original expectation.
|
||||
*
|
||||
* @param array<int, mixed> $arguments
|
||||
* @return Expectation<TValue>|Expectation<mixed>|never
|
||||
*/
|
||||
@@ -768,8 +641,6 @@ final readonly class OppositeExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle dynamic properties gets into the original expectation.
|
||||
*
|
||||
* @return Expectation<TValue>|Expectation<mixed>|never
|
||||
*/
|
||||
public function __get(string $name): Expectation
|
||||
@@ -788,8 +659,6 @@ final readonly class OppositeExpectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new expectation failed exception with a nice readable message.
|
||||
*
|
||||
* @param array<int, mixed>|string $arguments
|
||||
*/
|
||||
public function throwExpectationFailedException(string $name, array|string $arguments = []): never
|
||||
@@ -806,25 +675,16 @@ final readonly class OppositeExpectation
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not have a constructor method.
|
||||
*/
|
||||
public function toHaveConstructor(): ArchExpectation
|
||||
{
|
||||
return $this->toHaveMethod('__construct');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target does not have a destructor method.
|
||||
*/
|
||||
public function toHaveDestructor(): ArchExpectation
|
||||
{
|
||||
return $this->toHaveMethod('__destruct');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not a backed enum of given type.
|
||||
*/
|
||||
private function toBeBackedEnum(string $backingType): ArchExpectation
|
||||
{
|
||||
/** @var Expectation<array<int, string>|string> $original */
|
||||
@@ -841,33 +701,21 @@ final readonly class OppositeExpectation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are not string backed enums.
|
||||
*/
|
||||
public function toBeStringBackedEnums(): ArchExpectation
|
||||
{
|
||||
return $this->toBeStringBackedEnum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation targets are not int backed enums.
|
||||
*/
|
||||
public function toBeIntBackedEnums(): ArchExpectation
|
||||
{
|
||||
return $this->toBeIntBackedEnum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not a string backed enum.
|
||||
*/
|
||||
public function toBeStringBackedEnum(): ArchExpectation
|
||||
{
|
||||
return $this->toBeBackedEnum('string');
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given expectation target is not an int backed enum.
|
||||
*/
|
||||
public function toBeIntBackedEnum(): ArchExpectation
|
||||
{
|
||||
return $this->toBeBackedEnum('int');
|
||||
|
||||
@@ -8,24 +8,12 @@ use Pest\Support\HigherOrderMessageCollection;
|
||||
|
||||
trait HigherOrderable
|
||||
{
|
||||
/**
|
||||
* The higher order messages that are chainable.
|
||||
*/
|
||||
public HigherOrderMessageCollection $chains;
|
||||
|
||||
/**
|
||||
* The higher order messages that are "factory" proxyable.
|
||||
*/
|
||||
public HigherOrderMessageCollection $factoryProxies;
|
||||
|
||||
/**
|
||||
* The higher order messages that are proxyable.
|
||||
*/
|
||||
public HigherOrderMessageCollection $proxies;
|
||||
|
||||
/**
|
||||
* Boot the higher order properties.
|
||||
*/
|
||||
private function bootHigherOrderable(): void
|
||||
{
|
||||
$this->chains = new HigherOrderMessageCollection;
|
||||
|
||||
@@ -30,29 +30,21 @@ final class TestCaseFactory
|
||||
use HigherOrderable;
|
||||
|
||||
/**
|
||||
* The list of attributes.
|
||||
*
|
||||
* @var array<int, Attribute>
|
||||
*/
|
||||
public array $attributes = [];
|
||||
|
||||
/**
|
||||
* The FQN of the Test Case class.
|
||||
*
|
||||
* @var class-string
|
||||
*/
|
||||
public string $class = TestCase::class;
|
||||
|
||||
/**
|
||||
* The list of class methods.
|
||||
*
|
||||
* @var array<string, TestCaseMethodFactory>
|
||||
*/
|
||||
public array $methods = [];
|
||||
|
||||
/**
|
||||
* The list of class traits.
|
||||
*
|
||||
* @var array <int, class-string>
|
||||
*/
|
||||
public array $traits = [
|
||||
@@ -60,14 +52,8 @@ final class TestCaseFactory
|
||||
Concerns\Expectable::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The namespace for the test case, overrides the path-based namespace when set.
|
||||
*/
|
||||
public ?string $namespace = null;
|
||||
|
||||
/**
|
||||
* Creates a new Factory instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $filename
|
||||
) {
|
||||
@@ -84,14 +70,11 @@ final class TestCaseFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Test Case class using a runtime evaluate.
|
||||
*
|
||||
* @param array<string, TestCaseMethodFactory> $methods
|
||||
*/
|
||||
public function evaluate(string $filename, array $methods): void
|
||||
{
|
||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
||||
// In case Windows, strtolower drive name, like in UsesCall.
|
||||
$filename = (string) preg_replace_callback('~^(?P<drive>[a-z]+:\\\)~i', static fn (array $match): string => strtolower($match['drive']), $filename);
|
||||
}
|
||||
|
||||
@@ -114,11 +97,8 @@ final class TestCaseFactory
|
||||
|
||||
$relativePath = str_replace(DIRECTORY_SEPARATOR, '\\', $relativePath);
|
||||
|
||||
// Strip out any %-encoded octets.
|
||||
$relativePath = (string) preg_replace('|%[a-fA-F0-9][a-fA-F0-9]|', '', $relativePath);
|
||||
// Remove escaped quote sequences (maintain namespace)
|
||||
$relativePath = str_replace(array_map(fn (string $quote): string => sprintf('\\%s', $quote), ['\'', '"']), '', $relativePath);
|
||||
// Limit to Unicode letters and numbers.
|
||||
$relativePath = (string) preg_replace('/[^\p{L}\p{N}\\\\]/u', '', $relativePath);
|
||||
|
||||
$classFQN = 'P\\'.$relativePath;
|
||||
@@ -197,9 +177,6 @@ final class TestCaseFactory
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given Method to the Test Case.
|
||||
*/
|
||||
public function addMethod(TestCaseMethodFactory $method): void
|
||||
{
|
||||
if ($method->description === null) {
|
||||
@@ -233,9 +210,6 @@ final class TestCaseFactory
|
||||
$this->methods[$method->description] = $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a test case has a method.
|
||||
*/
|
||||
public function hasMethod(string $methodName): bool
|
||||
{
|
||||
foreach ($this->methods as $method) {
|
||||
@@ -251,9 +225,6 @@ final class TestCaseFactory
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Method by the given name.
|
||||
*/
|
||||
public function getMethod(string $methodName): TestCaseMethodFactory
|
||||
{
|
||||
foreach ($this->methods as $method) {
|
||||
|
||||
@@ -27,84 +27,54 @@ final class TestCaseMethodFactory
|
||||
use HigherOrderable;
|
||||
|
||||
/**
|
||||
* The list of attributes.
|
||||
*
|
||||
* @var array<int, Attribute>
|
||||
*/
|
||||
public array $attributes = [];
|
||||
|
||||
/**
|
||||
* The test's describing, if any.
|
||||
*
|
||||
* @var array<int, Description>
|
||||
*/
|
||||
public array $describing = [];
|
||||
|
||||
/**
|
||||
* The test's description, if any.
|
||||
*/
|
||||
public ?string $description = null;
|
||||
|
||||
/**
|
||||
* The test's number of repetitions.
|
||||
*/
|
||||
public int $repetitions = 1;
|
||||
|
||||
/**
|
||||
* The test's number of flaky retry tries.
|
||||
*/
|
||||
public ?int $flakyTries = null;
|
||||
|
||||
/**
|
||||
* Determines if the test is a "todo".
|
||||
*/
|
||||
public bool $todo = false;
|
||||
|
||||
/**
|
||||
* The associated issue numbers.
|
||||
*
|
||||
* @var array<int, int>
|
||||
*/
|
||||
public array $issues = [];
|
||||
|
||||
/**
|
||||
* The test assignees.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public array $assignees = [];
|
||||
|
||||
/**
|
||||
* The associated PRs numbers.
|
||||
*
|
||||
* @var array<int, int>
|
||||
*/
|
||||
public array $prs = [];
|
||||
|
||||
/**
|
||||
* The test's notes.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public array $notes = [];
|
||||
|
||||
/**
|
||||
* The test's datasets.
|
||||
*
|
||||
* @var array<Closure|iterable<int|string, mixed>|string>
|
||||
*/
|
||||
public array $datasets = [];
|
||||
|
||||
/**
|
||||
* The test's dependencies.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public array $depends = [];
|
||||
|
||||
/**
|
||||
* The test's groups.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public array $groups = [];
|
||||
@@ -114,9 +84,6 @@ final class TestCaseMethodFactory
|
||||
*/
|
||||
public bool $__ran = false;
|
||||
|
||||
/**
|
||||
* Creates a new test case method factory instance.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $filename,
|
||||
public ?Closure $closure,
|
||||
@@ -128,9 +95,6 @@ final class TestCaseMethodFactory
|
||||
$this->bootHigherOrderable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test's hooks, and runs any proxy to the test case.
|
||||
*/
|
||||
public function setUp(TestCase $concrete): void
|
||||
{
|
||||
$concrete::flush(); // @phpstan-ignore-line
|
||||
@@ -146,17 +110,11 @@ final class TestCaseMethodFactory
|
||||
$this->factoryProxies->proxy($concrete);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the test case.
|
||||
*/
|
||||
public function tearDown(TestCase $concrete): void
|
||||
{
|
||||
$concrete::flush(); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the test's closure.
|
||||
*/
|
||||
public function getClosure(): Closure
|
||||
{
|
||||
$closure = $this->closure;
|
||||
@@ -178,17 +136,11 @@ final class TestCaseMethodFactory
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the test case will receive argument input from Pest, or not.
|
||||
*/
|
||||
public function receivesArguments(): bool
|
||||
{
|
||||
return $this->datasets !== [] || $this->depends !== [] || $this->repetitions > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PHPUnit method as a string ready for evaluation.
|
||||
*/
|
||||
public function buildForEvaluation(): string
|
||||
{
|
||||
if ($this->description === null) {
|
||||
@@ -248,9 +200,6 @@ final class TestCaseMethodFactory
|
||||
PHP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PHPUnit Data Provider as a string ready for evaluation.
|
||||
*/
|
||||
private function buildDatasetForEvaluation(string $methodName, string $dataProviderName): string
|
||||
{
|
||||
$datasets = $this->datasets;
|
||||
|
||||
@@ -27,8 +27,6 @@ use PHPUnit\Framework\TestCase;
|
||||
|
||||
if (! function_exists('expect')) {
|
||||
/**
|
||||
* Creates a new expectation.
|
||||
*
|
||||
* @template TValue
|
||||
*
|
||||
* @param TValue|null $value
|
||||
@@ -41,9 +39,6 @@ if (! function_exists('expect')) {
|
||||
}
|
||||
|
||||
if (! function_exists('beforeAll')) {
|
||||
/**
|
||||
* Runs the given closure before all tests in the current file.
|
||||
*/
|
||||
function beforeAll(Closure $closure): void
|
||||
{
|
||||
if (DescribeCall::describing() !== []) {
|
||||
@@ -58,8 +53,6 @@ if (! function_exists('beforeAll')) {
|
||||
|
||||
if (! function_exists('beforeEach')) {
|
||||
/**
|
||||
* Runs the given closure before each test in the current file.
|
||||
*
|
||||
* @param-closure-this TestCall $closure
|
||||
*/
|
||||
function beforeEach(?Closure $closure = null): BeforeEachCall
|
||||
@@ -72,8 +65,6 @@ if (! function_exists('beforeEach')) {
|
||||
|
||||
if (! function_exists('dataset')) {
|
||||
/**
|
||||
* Registers the given dataset.
|
||||
*
|
||||
* @param Closure|iterable<int|string, mixed> $dataset
|
||||
*/
|
||||
function dataset(string $name, Closure|iterable $dataset): void
|
||||
@@ -85,11 +76,6 @@ if (! function_exists('dataset')) {
|
||||
}
|
||||
|
||||
if (! function_exists('describe')) {
|
||||
/**
|
||||
* Adds the given closure as a group of tests. The first argument
|
||||
* is the group description; the second argument is a closure
|
||||
* that contains the group tests.
|
||||
*/
|
||||
function describe(string $description, Closure $tests): DescribeCall
|
||||
{
|
||||
$filename = Backtrace::testFile();
|
||||
@@ -100,9 +86,6 @@ if (! function_exists('describe')) {
|
||||
|
||||
if (! function_exists('uses')) {
|
||||
/**
|
||||
* The uses function binds the given
|
||||
* arguments to test closures.
|
||||
*
|
||||
* @param class-string ...$classAndTraits
|
||||
*/
|
||||
function uses(string ...$classAndTraits): UsesCall
|
||||
@@ -114,9 +97,6 @@ if (! function_exists('uses')) {
|
||||
}
|
||||
|
||||
if (! function_exists('pest')) {
|
||||
/**
|
||||
* Creates a new Pest configuration instance.
|
||||
*/
|
||||
function pest(): Configuration
|
||||
{
|
||||
return new Configuration(Backtrace::testFile());
|
||||
@@ -125,10 +105,6 @@ if (! function_exists('pest')) {
|
||||
|
||||
if (! function_exists('test')) {
|
||||
/**
|
||||
* Adds the given closure as a test. The first argument
|
||||
* is the test description; the second argument is
|
||||
* a closure that contains the test expectations.
|
||||
*
|
||||
* @param-closure-this TestCall $closure
|
||||
*
|
||||
* @return ($description is string ? TestCall : HigherOrderTapProxy|TestCall)
|
||||
@@ -147,10 +123,6 @@ if (! function_exists('test')) {
|
||||
|
||||
if (! function_exists('it')) {
|
||||
/**
|
||||
* Adds the given closure as a test. The first argument
|
||||
* is the test description; the second argument is
|
||||
* a closure that contains the test expectations.
|
||||
*
|
||||
* @param-closure-this TestCall $closure
|
||||
*/
|
||||
function it(string $description, ?Closure $closure = null): TestCall
|
||||
@@ -162,9 +134,6 @@ if (! function_exists('it')) {
|
||||
}
|
||||
|
||||
if (! function_exists('todo')) {
|
||||
/**
|
||||
* Creates a new test that is marked as "todo".
|
||||
*/
|
||||
function todo(string $description): TestCall
|
||||
{
|
||||
return test($description)->todo();
|
||||
@@ -173,8 +142,6 @@ if (! function_exists('todo')) {
|
||||
|
||||
if (! function_exists('afterEach')) {
|
||||
/**
|
||||
* Runs the given closure after each test in the current file.
|
||||
*
|
||||
* @param-closure-this TestCall $closure
|
||||
*/
|
||||
function afterEach(?Closure $closure = null): AfterEachCall
|
||||
@@ -186,9 +153,6 @@ if (! function_exists('afterEach')) {
|
||||
}
|
||||
|
||||
if (! function_exists('afterAll')) {
|
||||
/**
|
||||
* Runs the given closure after all tests in the current file.
|
||||
*/
|
||||
function afterAll(Closure $closure): void
|
||||
{
|
||||
if (DescribeCall::describing() !== []) {
|
||||
@@ -203,8 +167,6 @@ if (! function_exists('afterAll')) {
|
||||
|
||||
if (! function_exists('covers')) {
|
||||
/**
|
||||
* Specifies which classes, or functions, a test case covers.
|
||||
*
|
||||
* @param array<int, string>|string $classesOrFunctions
|
||||
*/
|
||||
function covers(array|string ...$classesOrFunctions): void
|
||||
@@ -232,8 +194,6 @@ 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
|
||||
@@ -266,9 +226,6 @@ if (! function_exists('mutates')) {
|
||||
}
|
||||
|
||||
if (! function_exists('fixture')) {
|
||||
/**
|
||||
* Returns the absolute path to a fixture file.
|
||||
*/
|
||||
function fixture(string $file): string
|
||||
{
|
||||
$file = implode(DIRECTORY_SEPARATOR, [
|
||||
@@ -292,8 +249,6 @@ if (! function_exists('fixture')) {
|
||||
|
||||
if (! function_exists('visit')) {
|
||||
/**
|
||||
* Browse to the given URL.
|
||||
*
|
||||
* @template TUrl of array<int, string>|string
|
||||
*
|
||||
* @param TUrl $url
|
||||
|
||||
@@ -29,14 +29,9 @@ use Whoops\Exception\Inspector;
|
||||
*/
|
||||
final class Kernel
|
||||
{
|
||||
/**
|
||||
* Either the kernel is terminated or not.
|
||||
*/
|
||||
private bool $terminated = false;
|
||||
|
||||
/**
|
||||
* The Kernel bootstrappers.
|
||||
*
|
||||
* @var array<int, class-string>
|
||||
*/
|
||||
private const array BOOTSTRAPPERS = [
|
||||
@@ -51,10 +46,6 @@ final class Kernel
|
||||
];
|
||||
|
||||
/**
|
||||
* The Kernel restarters — resolved and invoked from `bin/pest`
|
||||
* before any other Pest class is touched, so the list is exposed
|
||||
* on the Kernel rather than driven from `bin/pest` directly.
|
||||
*
|
||||
* @var array<int, class-string<Contracts\Restarter>>
|
||||
*/
|
||||
public const array RESTARTERS = [
|
||||
@@ -62,14 +53,8 @@ final class Kernel
|
||||
Restarters\PcovRestarter::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Creates a new Kernel instance.
|
||||
*/
|
||||
public function __construct(private readonly Application $application, private readonly OutputInterface $output) {}
|
||||
|
||||
/**
|
||||
* Boots the Kernel.
|
||||
*/
|
||||
public static function boot(TestSuite $testSuite, InputInterface $input, OutputInterface $output): self
|
||||
{
|
||||
$container = Container::getInstance();
|
||||
@@ -102,8 +87,6 @@ final class Kernel
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the application, and returns the exit code.
|
||||
*
|
||||
* @param array<int, string> $originalArguments
|
||||
* @param array<int, string> $arguments
|
||||
*/
|
||||
@@ -135,9 +118,6 @@ final class Kernel
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate the Kernel.
|
||||
*/
|
||||
public function terminate(): void
|
||||
{
|
||||
if ($this->terminated) {
|
||||
@@ -155,9 +135,6 @@ final class Kernel
|
||||
CallsTerminable::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdowns unexpectedly the Kernel.
|
||||
*/
|
||||
public function shutdown(): void
|
||||
{
|
||||
$this->terminate();
|
||||
|
||||
+1
-25
@@ -10,23 +10,14 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
final class KernelDump
|
||||
{
|
||||
/**
|
||||
* The output buffer, if any.
|
||||
*/
|
||||
private string $buffer = '';
|
||||
|
||||
/**
|
||||
* Creates a new Kernel Dump instance.
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly OutputInterface $output,
|
||||
) {
|
||||
// ...
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the output buffering.
|
||||
*/
|
||||
public function enable(): void
|
||||
{
|
||||
if (class_exists(Execution::class) && Execution::running()) {
|
||||
@@ -40,9 +31,6 @@ final class KernelDump
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the output buffering.
|
||||
*/
|
||||
public function disable(): void
|
||||
{
|
||||
@ob_clean();
|
||||
@@ -52,17 +40,11 @@ final class KernelDump
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate the output buffering.
|
||||
*/
|
||||
public function terminate(): void
|
||||
{
|
||||
$this->disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the buffer.
|
||||
*/
|
||||
private function flush(): void
|
||||
{
|
||||
View::renderUsing($this->output);
|
||||
@@ -103,17 +85,11 @@ final class KernelDump
|
||||
$this->buffer = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given output contains an opening headline.
|
||||
*/
|
||||
private function isOpeningHeadline(string $output): bool
|
||||
{
|
||||
return str_contains($output, 'by Sebastian Bergmann and contributors.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given output contains an opening headline.
|
||||
*/
|
||||
private function isInternalError(string $output): bool
|
||||
{
|
||||
return str_contains($output, 'An error occurred inside PHPUnit.');
|
||||
|
||||
@@ -25,28 +25,16 @@ use PHPUnit\TestRunner\TestResult\TestResult as PhpUnitTestResult;
|
||||
*/
|
||||
final readonly class Converter
|
||||
{
|
||||
/**
|
||||
* The prefix for the test suite name.
|
||||
*/
|
||||
private const string PREFIX = 'P\\';
|
||||
|
||||
/**
|
||||
* The state generator.
|
||||
*/
|
||||
private StateGenerator $stateGenerator;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the Converter.
|
||||
*/
|
||||
public function __construct(
|
||||
private string $rootPath,
|
||||
) {
|
||||
$this->stateGenerator = new StateGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the test case method name.
|
||||
*/
|
||||
public function getTestCaseMethodName(Test $test): string
|
||||
{
|
||||
if (! $test instanceof TestMethod) {
|
||||
@@ -56,9 +44,6 @@ final readonly class Converter
|
||||
return $test->testDox()->prettifiedMethodName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the test case location.
|
||||
*/
|
||||
public function getTestCaseLocation(Test $test): string
|
||||
{
|
||||
if (! $test instanceof TestMethod) {
|
||||
@@ -68,15 +53,11 @@ final readonly class Converter
|
||||
$path = $test->testDox()->prettifiedClassName();
|
||||
$relativePath = $this->toRelativePath($path);
|
||||
|
||||
// TODO: Get the description without the dataset.
|
||||
$description = $test->testDox()->prettifiedMethodName();
|
||||
|
||||
return "$relativePath::$description";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exception message.
|
||||
*/
|
||||
public function getExceptionMessage(Throwable $throwable): string
|
||||
{
|
||||
if (is_a($throwable->className(), FrameworkException::class, true)) {
|
||||
@@ -93,9 +74,6 @@ final readonly class Converter
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exception details.
|
||||
*/
|
||||
public function getExceptionDetails(Throwable $throwable): string
|
||||
{
|
||||
$buffer = $this->getStackTrace($throwable);
|
||||
@@ -113,26 +91,19 @@ final readonly class Converter
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stack trace.
|
||||
*/
|
||||
public function getStackTrace(Throwable $throwable): string
|
||||
{
|
||||
$stackTrace = $throwable->stackTrace();
|
||||
|
||||
// Split stacktrace per frame.
|
||||
$frames = explode("\n", $stackTrace);
|
||||
|
||||
// Remove empty lines
|
||||
$frames = array_filter($frames);
|
||||
|
||||
// clean the paths of each frame.
|
||||
$frames = array_map(
|
||||
$this->toRelativePath(...),
|
||||
$frames
|
||||
);
|
||||
|
||||
// Format stacktrace as `at <path>`
|
||||
$frames = array_map(
|
||||
fn (string $frame): string => "at $frame",
|
||||
$frames
|
||||
@@ -141,9 +112,6 @@ final readonly class Converter
|
||||
return implode("\n", $frames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the test suite name.
|
||||
*/
|
||||
public function getTestSuiteName(TestSuite $testSuite): string
|
||||
{
|
||||
if ($testSuite instanceof TestSuiteForTestMethodWithDataProvider) {
|
||||
@@ -162,17 +130,11 @@ final readonly class Converter
|
||||
return Str::after($name, self::PREFIX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the trimmed test class name.
|
||||
*/
|
||||
public function getTrimmedTestClassName(TestMethod $test): string
|
||||
{
|
||||
return Str::after($test->className(), self::PREFIX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the test suite location.
|
||||
*/
|
||||
public function getTestSuiteLocation(TestSuite $testSuite): ?string
|
||||
{
|
||||
$firstTest = $this->getFirstTest($testSuite);
|
||||
@@ -191,22 +153,15 @@ final readonly class Converter
|
||||
return $classRelativePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the prettified test method name without dataset-related suffix.
|
||||
*/
|
||||
private function getTestMethodNameWithoutDatasetSuffix(TestMethod $testMethod): string
|
||||
{
|
||||
return Str::beforeLast($testMethod->testDox()->prettifiedMethodName(), ' with data set ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first test from the test suite.
|
||||
*/
|
||||
private function getFirstTest(TestSuite $testSuite): ?TestMethod
|
||||
{
|
||||
$tests = $testSuite->tests()->asArray();
|
||||
|
||||
// TODO: figure out how to get the file path without a test being there.
|
||||
if ($tests === []) {
|
||||
return null;
|
||||
}
|
||||
@@ -219,26 +174,16 @@ final readonly class Converter
|
||||
return $firstTest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the test suite size.
|
||||
*/
|
||||
public function getTestSuiteSize(TestSuite $testSuite): int
|
||||
{
|
||||
return $testSuite->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the given path in relative path.
|
||||
*/
|
||||
private function toRelativePath(string $path): string
|
||||
{
|
||||
// Remove cwd from the path.
|
||||
return str_replace("$this->rootPath".DIRECTORY_SEPARATOR, '', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the test result.
|
||||
*/
|
||||
public function getStateFromResult(PhpUnitTestResult $result): State
|
||||
{
|
||||
$events = [
|
||||
@@ -253,11 +198,9 @@ final readonly class Converter
|
||||
|
||||
foreach ($events as $event) {
|
||||
if ($event instanceof AfterLastTestMethodErrored) {
|
||||
// PHPUnit's collector does not count these towards `numberOfTestsRun`...
|
||||
continue;
|
||||
}
|
||||
if ($event instanceof AfterLastTestMethodFailed) {
|
||||
// PHPUnit's collector does not count these towards `numberOfTestsRun`...
|
||||
continue;
|
||||
}
|
||||
if ($event instanceof BeforeFirstTestMethodErrored || $event instanceof BeforeFirstTestMethodFailed) {
|
||||
|
||||
@@ -9,9 +9,6 @@ namespace Pest\Logging\TeamCity;
|
||||
*/
|
||||
final class ServiceMessage
|
||||
{
|
||||
/**
|
||||
* The flow ID.
|
||||
*/
|
||||
private static ?int $flowId = null;
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,14 +11,8 @@ use Pest\Logging\TeamCity\TeamCityLogger;
|
||||
*/
|
||||
abstract class Subscriber // @pest-arch-ignore-line
|
||||
{
|
||||
/**
|
||||
* Creates a new Subscriber instance.
|
||||
*/
|
||||
public function __construct(private readonly TeamCityLogger $logger) {}
|
||||
|
||||
/**
|
||||
* Creates a new TeamCityLogger instance.
|
||||
*/
|
||||
final protected function logger(): TeamCityLogger // @pest-arch-ignore-line
|
||||
{
|
||||
return $this->logger;
|
||||
|
||||
@@ -15,7 +15,7 @@ final class TestSkippedSubscriber extends Subscriber implements SkippedSubscribe
|
||||
public function notify(Skipped $event): void
|
||||
{
|
||||
if ($event->message() === '__TODO__') {
|
||||
return; // "todo" tests are reported in the summary, not as ignored tests...
|
||||
return;
|
||||
}
|
||||
|
||||
$this->logger()->testSkipped($event);
|
||||
|
||||
@@ -43,14 +43,8 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
*/
|
||||
final class TeamCityLogger
|
||||
{
|
||||
/**
|
||||
* The current time.
|
||||
*/
|
||||
private ?HRTime $time = null;
|
||||
|
||||
/**
|
||||
* Indicates if the summary test count has been printed.
|
||||
*/
|
||||
private bool $isSummaryTestCountPrinted = false;
|
||||
|
||||
/**
|
||||
@@ -129,10 +123,6 @@ final class TeamCityLogger
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This will trigger in the following scenarios
|
||||
* - When an exception is thrown
|
||||
*/
|
||||
public function testErrored(Errored $event): void
|
||||
{
|
||||
$this->whenFirstEventForTest($event->test(), function () use ($event): void {
|
||||
@@ -150,10 +140,6 @@ final class TeamCityLogger
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This will trigger in the following scenarios
|
||||
* - When an assertion fails
|
||||
*/
|
||||
public function testFailed(Failed $event): void
|
||||
{
|
||||
$this->whenFirstEventForTest($event->test(), function () use ($event): void {
|
||||
@@ -182,10 +168,6 @@ final class TeamCityLogger
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This will trigger in the following scenarios
|
||||
* - When no assertions in a test
|
||||
*/
|
||||
public function testConsideredRisky(ConsideredRisky $event): void
|
||||
{
|
||||
$this->whenFirstEventForTest($event->test(), function () use ($event): void {
|
||||
|
||||
+1
-169
@@ -38,27 +38,18 @@ use Traversable;
|
||||
*/
|
||||
final class Expectation
|
||||
{
|
||||
/**
|
||||
* The exporter instance, if any.
|
||||
*/
|
||||
private ?Exporter $exporter = null;
|
||||
|
||||
/**
|
||||
* Creates a new expectation.
|
||||
*
|
||||
* @param TValue $value
|
||||
*/
|
||||
public function __construct(
|
||||
public mixed $value
|
||||
) {
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that two variables have the same type and
|
||||
* value. Used on objects, it asserts that two
|
||||
* variables reference the same object.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBe(mixed $expected, string $message = ''): self
|
||||
@@ -69,8 +60,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is empty.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeEmpty(string $message = ''): self
|
||||
@@ -81,8 +70,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is true.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeTrue(string $message = ''): self
|
||||
@@ -93,8 +80,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is truthy.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeTruthy(string $message = ''): self
|
||||
@@ -105,8 +90,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is false.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeFalse(string $message = ''): self
|
||||
@@ -117,8 +100,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is falsy.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeFalsy(string $message = ''): self
|
||||
@@ -129,8 +110,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is greater than $expected.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeGreaterThan(int|float|string|DateTimeInterface $expected, string $message = ''): self
|
||||
@@ -141,8 +120,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is greater than or equal to $expected.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeGreaterThanOrEqual(int|float|string|DateTimeInterface $expected, string $message = ''): self
|
||||
@@ -153,8 +130,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is less than or equal to $expected.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeLessThan(int|float|string|DateTimeInterface $expected, string $message = ''): self
|
||||
@@ -165,8 +140,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is less than $expected.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeLessThanOrEqual(int|float|string|DateTimeInterface $expected, string $message = ''): self
|
||||
@@ -177,8 +150,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that $needle is an element of the value.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toContain(mixed ...$needles): self
|
||||
@@ -198,8 +169,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that $needle equal an element of the value.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toContainEqual(mixed ...$needles): self
|
||||
@@ -216,8 +185,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value starts with $expected.
|
||||
*
|
||||
* @param non-empty-string $expected
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -233,8 +200,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value ends with $expected.
|
||||
*
|
||||
* @param non-empty-string $expected
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -250,8 +215,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that $number matches value's Length.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toHaveLength(int $number, string $message = ''): self
|
||||
@@ -278,8 +241,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that $count matches the number of elements of the value.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toHaveCount(int $count, string $message = ''): self
|
||||
@@ -294,8 +255,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the size of the value and $expected are the same.
|
||||
*
|
||||
* @param Countable|iterable<mixed> $expected
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -311,8 +270,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value contains the property $name.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toHaveProperty(string $name, mixed $value = new Any, string $message = ''): self
|
||||
@@ -331,8 +288,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value contains the provided properties $names.
|
||||
*
|
||||
* @param iterable<string, mixed>|iterable<int, string> $names
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -346,8 +301,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that two variables have the same value.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toEqual(mixed $expected, string $message = ''): self
|
||||
@@ -358,14 +311,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that two variables have the same value.
|
||||
* The contents of $expected and the $this->value are
|
||||
* canonicalized before they are compared. For instance, when the two
|
||||
* variables $expected and $this->value are arrays, then these arrays
|
||||
* are sorted before they are compared. When $expected and $this->value
|
||||
* are objects, each object is converted to an array containing all
|
||||
* private, protected and public attributes.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toEqualCanonicalizing(mixed $expected, string $message = ''): self
|
||||
@@ -376,9 +321,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the absolute difference between the value and $expected
|
||||
* is lower than $delta.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toEqualWithDelta(mixed $expected, float $delta, string $message = ''): self
|
||||
@@ -389,8 +331,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is one of the given values.
|
||||
*
|
||||
* @param iterable<int|string, mixed> $values
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -402,8 +342,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is infinite.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeInfinite(string $message = ''): self
|
||||
@@ -414,8 +352,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is an instance of $class.
|
||||
*
|
||||
* @param class-string $class
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -427,8 +363,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is an array.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeArray(string $message = ''): self
|
||||
@@ -439,8 +373,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a list.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeList(string $message = ''): self
|
||||
@@ -451,8 +383,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type bool.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeBool(string $message = ''): self
|
||||
@@ -463,8 +393,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type callable.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeCallable(string $message = ''): self
|
||||
@@ -475,8 +403,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type float.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeFloat(string $message = ''): self
|
||||
@@ -487,8 +413,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type int.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeInt(string $message = ''): self
|
||||
@@ -499,8 +423,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type iterable.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeIterable(string $message = ''): self
|
||||
@@ -511,8 +433,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type numeric.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeNumeric(string $message = ''): self
|
||||
@@ -523,8 +443,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value contains only digits.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeDigits(string $message = ''): self
|
||||
@@ -535,8 +453,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type object.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeObject(string $message = ''): self
|
||||
@@ -547,8 +463,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type resource.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeResource(string $message = ''): self
|
||||
@@ -559,8 +473,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type scalar.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeScalar(string $message = ''): self
|
||||
@@ -571,8 +483,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is of type string.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeString(string $message = ''): self
|
||||
@@ -583,8 +493,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a JSON string.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeJson(string $message = ''): self
|
||||
@@ -597,8 +505,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is NAN.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeNan(string $message = ''): self
|
||||
@@ -609,8 +515,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is null.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeNull(string $message = ''): self
|
||||
@@ -621,8 +525,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value array has the provided $key.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toHaveKey(string|int $key, mixed $value = new Any, string $message = ''): self
|
||||
@@ -653,8 +555,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value array has the provided $keys.
|
||||
*
|
||||
* @param array<int, int|string|array<array-key, mixed>> $keys
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -672,8 +572,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a directory.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeDirectory(string $message = ''): self
|
||||
@@ -688,8 +586,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a directory and is readable.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeReadableDirectory(string $message = ''): self
|
||||
@@ -704,8 +600,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a directory and is writable.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeWritableDirectory(string $message = ''): self
|
||||
@@ -720,8 +614,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a file.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeFile(string $message = ''): self
|
||||
@@ -736,8 +628,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a file and is readable.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeReadableFile(string $message = ''): self
|
||||
@@ -752,8 +642,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a file and is writable.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeWritableFile(string $message = ''): self
|
||||
@@ -767,8 +655,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value array matches the given array subset.
|
||||
*
|
||||
* @param iterable<int|string, mixed> $array
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -796,9 +682,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value object matches a subset
|
||||
* of the properties of an given object.
|
||||
*
|
||||
* @param iterable<string, mixed> $object
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -827,8 +710,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value "stringable" matches the given snapshot..
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toMatchSnapshot(string $message = ''): self
|
||||
@@ -883,8 +764,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value matches a regular expression.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toMatch(string $expression, string $message = ''): self
|
||||
@@ -898,8 +777,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value matches a constraint.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toMatchConstraint(Constraint $constraint, string $message = ''): self
|
||||
@@ -925,8 +802,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that executing value throws an exception.
|
||||
*
|
||||
* @param (Closure(Throwable): mixed)|string $exception
|
||||
* @return self<TValue>
|
||||
*/
|
||||
@@ -994,9 +869,6 @@ final class Expectation
|
||||
throw new ExpectationFailedException("Exception \"$exception\" not thrown.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the given value.
|
||||
*/
|
||||
private function export(mixed $value): string
|
||||
{
|
||||
if (! $this->exporter instanceof Exporter) {
|
||||
@@ -1007,8 +879,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is uppercase.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeUppercase(string $message = ''): self
|
||||
@@ -1019,8 +889,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is lowercase.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeLowercase(string $message = ''): self
|
||||
@@ -1031,8 +899,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is alphanumeric.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeAlphaNumeric(string $message = ''): self
|
||||
@@ -1043,8 +909,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is alpha.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeAlpha(string $message = ''): self
|
||||
@@ -1055,8 +919,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is snake_case.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeSnakeCase(string $message = ''): self
|
||||
@@ -1073,8 +935,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is kebab-case.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeKebabCase(string $message = ''): self
|
||||
@@ -1091,8 +951,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is camelCase.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeCamelCase(string $message = ''): self
|
||||
@@ -1109,8 +967,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is StudlyCase.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeStudlyCase(string $message = ''): self
|
||||
@@ -1127,8 +983,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is UUID.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeUuid(string $message = ''): self
|
||||
@@ -1143,8 +997,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a ULID.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeUlid(string $message = ''): self
|
||||
@@ -1159,8 +1011,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is between 2 specified values
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeBetween(int|float|DateTimeInterface $lowestValue, int|float|DateTimeInterface $highestValue, string $message = ''): self
|
||||
@@ -1172,8 +1022,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is an email address.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeEmail(string $message = ''): self
|
||||
@@ -1188,8 +1036,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a url
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeUrl(string $message = ''): self
|
||||
@@ -1204,8 +1050,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value can be converted to a slug
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeSlug(string $message = ''): self
|
||||
@@ -1221,8 +1065,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is an IP address.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeIpAddress(string $message = ''): self
|
||||
@@ -1237,8 +1079,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a MAC address.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeMacAddress(string $message = ''): self
|
||||
@@ -1253,8 +1093,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a hostname.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeHostname(string $message = ''): self
|
||||
@@ -1269,8 +1107,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a domain name.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeDomain(string $message = ''): self
|
||||
@@ -1288,8 +1124,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a base64-encoded string.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeBase64(string $message = ''): self
|
||||
@@ -1305,8 +1139,6 @@ final class Expectation
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the value is a hexadecimal string.
|
||||
*
|
||||
* @return self<TValue>
|
||||
*/
|
||||
public function toBeHexadecimal(string $message = ''): self
|
||||
|
||||
@@ -15,12 +15,6 @@ use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
|
||||
/**
|
||||
* Prevents native declared properties of HigherOrderExpectation (like $original,
|
||||
* $expectation, $opposite, $shouldReset) from being incorrectly resolved as
|
||||
* higher-order value property accesses by downstream ExpressionTypeResolverExtensions.
|
||||
*
|
||||
* This extension must be registered BEFORE the pest-plugin-phpstan HigherOrderExpectationTypeExtension.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final readonly class HigherOrderExpectationTypeExtension implements ExpressionTypeResolverExtension
|
||||
|
||||
+1
-10
@@ -14,18 +14,12 @@ use Whoops\Exception\Inspector;
|
||||
|
||||
final readonly class Panic
|
||||
{
|
||||
/**
|
||||
* Creates a new Panic instance.
|
||||
*/
|
||||
private function __construct(
|
||||
private Throwable $throwable
|
||||
) {
|
||||
// ...
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Panic instance, and exits the application.
|
||||
*/
|
||||
public static function with(Throwable $throwable): never
|
||||
{
|
||||
if ($throwable instanceof TestDescriptionMissing && ! is_null($previous = $throwable->getPrevious())) {
|
||||
@@ -39,9 +33,6 @@ final readonly class Panic
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the panic.
|
||||
*/
|
||||
private function handle(): void
|
||||
{
|
||||
try {
|
||||
|
||||
@@ -20,19 +20,10 @@ final class AfterEachCall
|
||||
{
|
||||
use Describable;
|
||||
|
||||
/**
|
||||
* The "afterEach" closure.
|
||||
*/
|
||||
private readonly Closure $closure;
|
||||
|
||||
/**
|
||||
* The calls that should be proxied.
|
||||
*/
|
||||
private readonly HigherOrderMessageCollection $proxies;
|
||||
|
||||
/**
|
||||
* Creates a new Pending Call.
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly TestSuite $testSuite,
|
||||
private readonly string $filename,
|
||||
@@ -45,9 +36,6 @@ final class AfterEachCall
|
||||
$this->describing = DescribeCall::describing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Call.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$describing = $this->describing;
|
||||
@@ -69,8 +57,6 @@ final class AfterEachCall
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the calls to be used on the target.
|
||||
*
|
||||
* @param array<int, mixed> $arguments
|
||||
*/
|
||||
public function __call(string $name, array $arguments): self
|
||||
|
||||
@@ -23,24 +23,12 @@ final class BeforeEachCall
|
||||
{
|
||||
use Describable;
|
||||
|
||||
/**
|
||||
* Holds the before each closure.
|
||||
*/
|
||||
private readonly Closure $closure;
|
||||
|
||||
/**
|
||||
* The test call proxies.
|
||||
*/
|
||||
private readonly HigherOrderMessageCollection $testCallProxies;
|
||||
|
||||
/**
|
||||
* The test case proxies.
|
||||
*/
|
||||
private readonly HigherOrderMessageCollection $testCaseProxies;
|
||||
|
||||
/**
|
||||
* Creates a new Pending Call.
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly TestSuite $testSuite,
|
||||
private readonly string $filename,
|
||||
@@ -54,9 +42,6 @@ final class BeforeEachCall
|
||||
$this->describing = DescribeCall::describing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Call.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$describing = $this->describing;
|
||||
@@ -92,9 +77,6 @@ final class BeforeEachCall
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given closure after the test.
|
||||
*/
|
||||
public function after(Closure $closure): self
|
||||
{
|
||||
if ($this->describing === []) {
|
||||
@@ -105,8 +87,6 @@ final class BeforeEachCall
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the calls to be used on the target.
|
||||
*
|
||||
* @param array<int, mixed> $arguments
|
||||
*/
|
||||
public function __call(string $name, array $arguments): self
|
||||
|
||||
@@ -12,15 +12,11 @@ use Pest\Support\Description;
|
||||
trait Describable
|
||||
{
|
||||
/**
|
||||
* Note: this is property is not used; however, it gets added automatically by rector php.
|
||||
*
|
||||
* @var array<int, Description>
|
||||
*/
|
||||
public array $__describing;
|
||||
|
||||
/**
|
||||
* The describing of the test case.
|
||||
*
|
||||
* @var array<int, Description>
|
||||
*/
|
||||
public array $describing = [];
|
||||
|
||||
@@ -14,20 +14,12 @@ use Pest\TestSuite;
|
||||
final class DescribeCall
|
||||
{
|
||||
/**
|
||||
* The current describe call.
|
||||
*
|
||||
* @var array<int, Description>
|
||||
*/
|
||||
private static array $describing = [];
|
||||
|
||||
/**
|
||||
* The describe "before each" call.
|
||||
*/
|
||||
private ?BeforeEachCall $currentBeforeEachCall = null;
|
||||
|
||||
/**
|
||||
* Creates a new Pending Call.
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly TestSuite $testSuite,
|
||||
public readonly string $filename,
|
||||
@@ -38,8 +30,6 @@ final class DescribeCall
|
||||
}
|
||||
|
||||
/**
|
||||
* What is the current describing.
|
||||
*
|
||||
* @return array<int, Description>
|
||||
*/
|
||||
public static function describing(): array
|
||||
@@ -47,17 +37,11 @@ final class DescribeCall
|
||||
return self::$describing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Call.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// Ensure BeforeEachCall destructs before creating tests
|
||||
// by moving to local scope and clearing the reference
|
||||
$beforeEach = $this->currentBeforeEachCall;
|
||||
$this->currentBeforeEachCall = null;
|
||||
unset($beforeEach); // Trigger destructor immediately
|
||||
|
||||
unset($beforeEach);
|
||||
self::$describing[] = $this->description;
|
||||
|
||||
try {
|
||||
@@ -68,8 +52,6 @@ final class DescribeCall
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically calls methods on each test call.
|
||||
*
|
||||
* @param array<int, mixed> $arguments
|
||||
*/
|
||||
public function __call(string $name, array $arguments): self
|
||||
|
||||
@@ -38,25 +38,14 @@ final class TestCall // @phpstan-ignore-line
|
||||
use Describable;
|
||||
|
||||
/**
|
||||
* The list of test case factory attributes.
|
||||
*
|
||||
* @var array<int, Attribute>
|
||||
*/
|
||||
private array $testCaseFactoryAttributes = [];
|
||||
|
||||
/**
|
||||
* The Test Case Factory.
|
||||
*/
|
||||
public readonly TestCaseMethodFactory $testCaseMethod;
|
||||
|
||||
/**
|
||||
* If test call is descriptionLess.
|
||||
*/
|
||||
private readonly bool $descriptionLess;
|
||||
|
||||
/**
|
||||
* Creates a new Pending Call.
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly TestSuite $testSuite,
|
||||
private readonly string $filename,
|
||||
@@ -72,9 +61,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
$this->testSuite->beforeEach->get($this->filename)[0]($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given closure after the test.
|
||||
*/
|
||||
public function after(Closure $closure): self
|
||||
{
|
||||
if ($this->description === null) {
|
||||
@@ -108,17 +94,11 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the test fails with the given message.
|
||||
*/
|
||||
public function fails(?string $message = null): self
|
||||
{
|
||||
return $this->throws(AssertionFailedError::class, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the test throws the given `$exceptionClass` when called.
|
||||
*/
|
||||
public function throws(string|int $exception, ?string $exceptionMessage = null, ?int $exceptionCode = null): self
|
||||
{
|
||||
if (is_int($exception)) {
|
||||
@@ -147,8 +127,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the test throws the given `$exceptionClass` when called if the given condition is true.
|
||||
*
|
||||
* @param (callable(): bool)|bool $condition
|
||||
*/
|
||||
public function throwsIf(callable|bool $condition, string|int $exception, ?string $exceptionMessage = null, ?int $exceptionCode = null): self
|
||||
@@ -165,8 +143,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the test throws the given `$exceptionClass` when called if the given condition is false.
|
||||
*
|
||||
* @param (callable(): bool)|bool $condition
|
||||
*/
|
||||
public function throwsUnless(callable|bool $condition, string|int $exception, ?string $exceptionMessage = null, ?int $exceptionCode = null): self
|
||||
@@ -183,8 +159,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the current test multiple times with each item of the given `iterable`.
|
||||
*
|
||||
* @param Closure|iterable<array-key, mixed>|string $data
|
||||
*/
|
||||
public function with(Closure|iterable|string ...$data): self
|
||||
@@ -196,9 +170,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test depends.
|
||||
*/
|
||||
public function depends(string ...$depends): self
|
||||
{
|
||||
foreach ($depends as $depend) {
|
||||
@@ -208,9 +179,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test group(s).
|
||||
*/
|
||||
public function group(string ...$groups): self
|
||||
{
|
||||
foreach ($groups as $group) {
|
||||
@@ -223,9 +191,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the test suite by "only" tests.
|
||||
*/
|
||||
public function only(): self
|
||||
{
|
||||
Only::enable($this, ...func_get_args());
|
||||
@@ -233,9 +198,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test.
|
||||
*/
|
||||
public function skip(Closure|bool|string $conditionOrMessage = true, string $message = ''): self
|
||||
{
|
||||
$condition = is_string($conditionOrMessage)
|
||||
@@ -260,9 +222,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test on the given PHP version.
|
||||
*/
|
||||
public function skipOnPhp(string $version): self
|
||||
{
|
||||
if (mb_strlen($version) < 2) {
|
||||
@@ -275,7 +234,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
} elseif (str_starts_with($version, '>') || str_starts_with($version, '<')) {
|
||||
$operator = $version[0];
|
||||
$version = substr($version, 1);
|
||||
// ensure starts with number:
|
||||
} elseif (is_numeric($version[0])) {
|
||||
$operator = '==';
|
||||
} else {
|
||||
@@ -285,33 +243,21 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this->skip(version_compare(PHP_VERSION, $version, $operator), sprintf('This test is skipped on PHP [%s%s].', $operator, $version));
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test if the given test is running on Windows.
|
||||
*/
|
||||
public function skipOnWindows(): self
|
||||
{
|
||||
return $this->skipOnOs('Windows', 'This test is skipped on [Windows].');
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test if the given test is running on Mac OS.
|
||||
*/
|
||||
public function skipOnMac(): self
|
||||
{
|
||||
return $this->skipOnOs('Darwin', 'This test is skipped on [Mac].');
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test if the given test is running on Linux.
|
||||
*/
|
||||
public function skipOnLinux(): self
|
||||
{
|
||||
return $this->skipOnOs('Linux', 'This test is skipped on [Linux].');
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test if the given test is running on the given operating systems.
|
||||
*/
|
||||
private function skipOnOs(string $osFamily, string $message): self
|
||||
{
|
||||
return $osFamily === PHP_OS_FAMILY
|
||||
@@ -319,9 +265,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
: $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Weather the current test is running on a CI environment.
|
||||
*/
|
||||
private function runningOnCI(): bool
|
||||
{
|
||||
foreach ([
|
||||
@@ -353,9 +296,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return Environment::name() === Environment::CI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test when running on a CI environments.
|
||||
*/
|
||||
public function skipOnCI(): self
|
||||
{
|
||||
if ($this->runningOnCI()) {
|
||||
@@ -374,33 +314,21 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test unless the given test is running on Windows.
|
||||
*/
|
||||
public function onlyOnWindows(): self
|
||||
{
|
||||
return $this->skipOnMac()->skipOnLinux();
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test unless the given test is running on Mac.
|
||||
*/
|
||||
public function onlyOnMac(): self
|
||||
{
|
||||
return $this->skipOnWindows()->skipOnLinux();
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the current test unless the given test is running on Linux.
|
||||
*/
|
||||
public function onlyOnLinux(): self
|
||||
{
|
||||
return $this->skipOnWindows()->skipOnMac();
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeats the current test the given number of times.
|
||||
*/
|
||||
public function repeat(int $times): self
|
||||
{
|
||||
if ($times < 1) {
|
||||
@@ -412,9 +340,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the test as flaky, retrying it up to the given number of times.
|
||||
*/
|
||||
public function flaky(int $tries = 3): self
|
||||
{
|
||||
if ($tries < 1) {
|
||||
@@ -426,9 +351,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the test as "todo".
|
||||
*/
|
||||
public function todo(// @phpstan-ignore-line
|
||||
array|string|null $note = null,
|
||||
array|string|null $assignee = null,
|
||||
@@ -458,9 +380,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test as "work in progress".
|
||||
*/
|
||||
public function wip(// @phpstan-ignore-line
|
||||
array|string|null $note = null,
|
||||
array|string|null $assignee = null,
|
||||
@@ -486,9 +405,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test as "done".
|
||||
*/
|
||||
public function done(// @phpstan-ignore-line
|
||||
array|string|null $note = null,
|
||||
array|string|null $assignee = null,
|
||||
@@ -515,8 +431,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the test with the given issue(s).
|
||||
*
|
||||
* @param array<int, string|int>|string|int $number
|
||||
*/
|
||||
public function issue(array|string|int $number): self
|
||||
@@ -531,8 +445,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the test with the given ticket(s). (Alias for `issue`)
|
||||
*
|
||||
* @param array<int, string|int>|string|int $number
|
||||
*/
|
||||
public function ticket(array|string|int $number): self
|
||||
@@ -541,8 +453,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test assignee(s).
|
||||
*
|
||||
* @param array<int, string>|string $assignee
|
||||
*/
|
||||
public function assignee(array|string $assignee): self
|
||||
@@ -555,8 +465,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the test with the given pull request(s).
|
||||
*
|
||||
* @param array<int, string|int>|string|int $number
|
||||
*/
|
||||
public function pr(array|string|int $number): self
|
||||
@@ -571,8 +479,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a note to the test.
|
||||
*
|
||||
* @param array<int, string>|string $note
|
||||
*/
|
||||
public function note(array|string $note): self
|
||||
@@ -585,8 +491,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the covered classes or methods.
|
||||
*
|
||||
* @param array<int, string>|string $classesOrFunctions
|
||||
*/
|
||||
public function covers(array|string ...$classesOrFunctions): self
|
||||
@@ -615,9 +519,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the covered classes.
|
||||
*/
|
||||
public function coversClass(string ...$classes): self
|
||||
{
|
||||
foreach ($classes as $class) {
|
||||
@@ -638,9 +539,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the covered classes.
|
||||
*/
|
||||
public function coversTrait(string ...$traits): self
|
||||
{
|
||||
foreach ($traits as $trait) {
|
||||
@@ -661,9 +559,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the covered functions.
|
||||
*/
|
||||
public function coversFunction(string ...$functions): self
|
||||
{
|
||||
foreach ($functions as $function) {
|
||||
@@ -677,9 +572,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one or more references to the tested method or class. This helps
|
||||
* to link test cases to the source code for easier navigation.
|
||||
*
|
||||
* @param array<class-string|string>|class-string ...$classes
|
||||
*/
|
||||
public function references(string|array ...$classes): self
|
||||
@@ -690,9 +582,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one or more references to the tested method or class. This helps
|
||||
* to link test cases to the source code for easier navigation.
|
||||
*
|
||||
* @param array<class-string|string>|class-string ...$classes
|
||||
*/
|
||||
public function see(string|array ...$classes): self
|
||||
@@ -700,11 +589,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this->references(...$classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the test runner that no expectations happen in this test,
|
||||
* and its purpose is simply to check whether the given code can
|
||||
* be executed without throwing exceptions.
|
||||
*/
|
||||
public function throwsNoExceptions(): self
|
||||
{
|
||||
$this->testCaseMethod->proxies->add(Backtrace::file(), Backtrace::line(), 'expectNotToPerformAssertions', []);
|
||||
@@ -712,17 +596,12 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the property accessors to be used on the target.
|
||||
*/
|
||||
public function __get(string $name): self
|
||||
{
|
||||
return $this->addChain(Backtrace::file(), Backtrace::line(), $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the calls to be used on the target.
|
||||
*
|
||||
* @param array<int, mixed> $arguments
|
||||
*/
|
||||
public function __call(string $name, array $arguments): self
|
||||
@@ -731,8 +610,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a chain to the test case factory. Omitting the arguments will treat it as a property accessor.
|
||||
*
|
||||
* @param array<int, mixed>|null $arguments
|
||||
*/
|
||||
private function addChain(string $file, int $line, string $name, ?array $arguments = null): self
|
||||
@@ -758,9 +635,6 @@ final class TestCall // @phpstan-ignore-line
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Call.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->description === null) {
|
||||
|
||||
@@ -14,36 +14,21 @@ use Pest\TestSuite;
|
||||
final class UsesCall
|
||||
{
|
||||
/**
|
||||
* Contains a global before each hook closure to be executed.
|
||||
*
|
||||
* Array indices here matter. They are mapped as follows:
|
||||
*
|
||||
* - `0` => `beforeAll`
|
||||
* - `1` => `beforeEach`
|
||||
* - `2` => `afterEach`
|
||||
* - `3` => `afterAll`
|
||||
*
|
||||
* @var array<int, Closure>
|
||||
*/
|
||||
private array $hooks = [];
|
||||
|
||||
/**
|
||||
* Holds the targets of the uses.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private array $targets;
|
||||
|
||||
/**
|
||||
* Holds the groups of the uses.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private array $groups = [];
|
||||
|
||||
/**
|
||||
* Creates a new Pending Call.
|
||||
*
|
||||
* @param array<int, string> $classAndTraits
|
||||
*/
|
||||
public function __construct(
|
||||
@@ -62,8 +47,6 @@ final class UsesCall
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the class or traits to use.
|
||||
*
|
||||
* @alias extend
|
||||
*/
|
||||
public function use(string ...$classAndTraits): self
|
||||
@@ -71,9 +54,6 @@ final class UsesCall
|
||||
return $this->extend(...$classAndTraits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the class or traits to use.
|
||||
*/
|
||||
public function extend(string ...$classAndTraits): self
|
||||
{
|
||||
$this->classAndTraits = array_merge($this->classAndTraits, array_values($classAndTraits));
|
||||
@@ -81,9 +61,6 @@ final class UsesCall
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The directories or file where the class or traits should be used.
|
||||
*/
|
||||
public function in(string ...$targets): self
|
||||
{
|
||||
$targets = array_map(function (string $path): string {
|
||||
@@ -116,9 +93,6 @@ final class UsesCall
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test group(s).
|
||||
*/
|
||||
public function group(string ...$groups): self
|
||||
{
|
||||
$this->groups = array_values($groups);
|
||||
@@ -126,9 +100,6 @@ final class UsesCall
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the global beforeAll test hook.
|
||||
*/
|
||||
public function beforeAll(Closure $hook): self
|
||||
{
|
||||
$this->hooks[0] = $hook;
|
||||
@@ -136,9 +107,6 @@ final class UsesCall
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the global beforeEach test hook.
|
||||
*/
|
||||
public function beforeEach(Closure $hook): self
|
||||
{
|
||||
$this->hooks[1] = $hook;
|
||||
@@ -146,9 +114,6 @@ final class UsesCall
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the global afterEach test hook.
|
||||
*/
|
||||
public function afterEach(Closure $hook): self
|
||||
{
|
||||
$this->hooks[2] = $hook;
|
||||
@@ -156,9 +121,6 @@ final class UsesCall
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the global afterAll test hook.
|
||||
*/
|
||||
public function afterAll(Closure $hook): self
|
||||
{
|
||||
$this->hooks[3] = $hook;
|
||||
@@ -166,9 +128,6 @@ final class UsesCall
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the Call.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
TestSuite::getInstance()->tests->use(
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ namespace Pest;
|
||||
|
||||
function version(): string
|
||||
{
|
||||
return '5.0.4';
|
||||
return '5.0.5';
|
||||
}
|
||||
|
||||
function testDirectory(string $file = ''): string
|
||||
|
||||
@@ -7,8 +7,6 @@ namespace Pest;
|
||||
final class Plugin
|
||||
{
|
||||
/**
|
||||
* The lazy callables to be executed once the test suite boots.
|
||||
*
|
||||
* @var array<int, callable>
|
||||
*
|
||||
* @internal
|
||||
@@ -16,8 +14,6 @@ final class Plugin
|
||||
public static array $callables = [];
|
||||
|
||||
/**
|
||||
* Lazy loads an `uses` call on the context of plugins.
|
||||
*
|
||||
* @param class-string ...$traits
|
||||
*/
|
||||
public static function uses(string ...$traits): void
|
||||
|
||||
@@ -12,11 +12,6 @@ use Pest\Plugin\Loader;
|
||||
*/
|
||||
final class CallsAddsOutput
|
||||
{
|
||||
/**
|
||||
* Executes the Plugin action.
|
||||
*
|
||||
* Provides an opportunity for any plugins that want to provide additional output after test execution.
|
||||
*/
|
||||
public static function execute(int $exitCode): int
|
||||
{
|
||||
$plugins = Loader::getPlugins(Plugins\AddsOutput::class);
|
||||
|
||||
@@ -12,11 +12,6 @@ use Pest\Plugin\Loader;
|
||||
*/
|
||||
final class CallsBoot
|
||||
{
|
||||
/**
|
||||
* Executes the Plugin action.
|
||||
*
|
||||
* Provides an opportunity for any plugins to boot.
|
||||
*/
|
||||
public static function execute(): void
|
||||
{
|
||||
$plugins = Loader::getPlugins(Plugins\Bootable::class);
|
||||
|
||||
@@ -13,10 +13,6 @@ use Pest\Plugin\Loader;
|
||||
final class CallsHandleArguments
|
||||
{
|
||||
/**
|
||||
* Executes the Plugin action.
|
||||
*
|
||||
* Transform the input arguments by passing it to the relevant plugins.
|
||||
*
|
||||
* @param array<int, string> $argv
|
||||
* @return array<int, string>
|
||||
*/
|
||||
|
||||
@@ -13,10 +13,6 @@ use Pest\Plugin\Loader;
|
||||
final class CallsHandleOriginalArguments
|
||||
{
|
||||
/**
|
||||
* Executes the Plugin action.
|
||||
*
|
||||
* Transform the input arguments by passing it to the relevant plugins.
|
||||
*
|
||||
* @param array<int, string> $argv
|
||||
*/
|
||||
public static function execute(array $argv): void
|
||||
|
||||
@@ -12,11 +12,6 @@ use Pest\Plugin\Loader;
|
||||
*/
|
||||
final class CallsTerminable
|
||||
{
|
||||
/**
|
||||
* Executes the Plugin action.
|
||||
*
|
||||
* Provides an opportunity for any plugins to terminate.
|
||||
*/
|
||||
public static function execute(): void
|
||||
{
|
||||
$plugins = Loader::getPlugins(Plugins\Terminable::class);
|
||||
|
||||
@@ -14,9 +14,6 @@ final class Bail implements HandlesArguments
|
||||
{
|
||||
use HandleArguments;
|
||||
|
||||
/**
|
||||
* Handles the arguments, adding the `--stop-on-defect` when the `--bail` argument is present.
|
||||
*/
|
||||
public function handleArguments(array $arguments): array
|
||||
{
|
||||
if ($this->hasArgument('--bail', $arguments)) {
|
||||
|
||||
@@ -18,9 +18,6 @@ final class Cache implements HandlesArguments
|
||||
{
|
||||
use HandleArguments;
|
||||
|
||||
/**
|
||||
* The temporary folder.
|
||||
*/
|
||||
private const string TEMPORARY_FOLDER = __DIR__
|
||||
.DIRECTORY_SEPARATOR
|
||||
.'..'
|
||||
@@ -29,9 +26,6 @@ final class Cache implements HandlesArguments
|
||||
.DIRECTORY_SEPARATOR
|
||||
.'.temp';
|
||||
|
||||
/**
|
||||
* Handles the arguments, adding the cache directory and the cache result arguments.
|
||||
*/
|
||||
public function handleArguments(array $arguments): array
|
||||
{
|
||||
if (! $this->hasArgument('--cache-directory', $arguments)) {
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace Pest\Plugins\Concerns;
|
||||
trait HandleArguments
|
||||
{
|
||||
/**
|
||||
* Checks if the given argument exists on the arguments.
|
||||
*
|
||||
* @param array<int, string> $arguments
|
||||
*/
|
||||
public function hasArgument(string $argument, array $arguments): bool
|
||||
@@ -30,8 +28,6 @@ trait HandleArguments
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given argument and value to the list of arguments.
|
||||
*
|
||||
* @param array<int, string> $arguments
|
||||
* @return array<int, string>
|
||||
*/
|
||||
@@ -43,8 +39,6 @@ trait HandleArguments
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops the given argument from the arguments.
|
||||
*
|
||||
* @param array<int, string> $arguments
|
||||
* @return array<int, string>
|
||||
*/
|
||||
@@ -61,8 +55,6 @@ trait HandleArguments
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops the given argument and its value from the arguments, returning the value.
|
||||
*
|
||||
* @param array<int, string> $arguments
|
||||
*/
|
||||
public function popArgumentValue(string $argument, array &$arguments): ?string
|
||||
|
||||
@@ -18,9 +18,6 @@ final class Configuration implements HandlesArguments, Terminable
|
||||
{
|
||||
use HandleArguments;
|
||||
|
||||
/**
|
||||
* The base PHPUnit file.
|
||||
*/
|
||||
public const string BASE_PHPUNIT_FILE = __DIR__
|
||||
.DIRECTORY_SEPARATOR
|
||||
.'..'
|
||||
@@ -29,9 +26,6 @@ final class Configuration implements HandlesArguments, Terminable
|
||||
.DIRECTORY_SEPARATOR
|
||||
.'resources/base-phpunit.xml';
|
||||
|
||||
/**
|
||||
* Handles the arguments, adding the cache directory and the cache result arguments.
|
||||
*/
|
||||
public function handleArguments(array $arguments): array
|
||||
{
|
||||
if ($this->hasArgument('--configuration', $arguments) || $this->hasArgument('-c', $arguments) || $this->hasCustomConfigurationFile()) {
|
||||
@@ -43,9 +37,6 @@ final class Configuration implements HandlesArguments, Terminable
|
||||
return $this->pushArgument((string) realpath($this->fromGeneratedConfigurationFile()), $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configuration file from the generated configuration file.
|
||||
*/
|
||||
private function fromGeneratedConfigurationFile(): string
|
||||
{
|
||||
$path = $this->getTempPhpunitXmlPath();
|
||||
@@ -63,9 +54,6 @@ final class Configuration implements HandlesArguments, Terminable
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the configuration file is custom.
|
||||
*/
|
||||
private function hasCustomConfigurationFile(): bool
|
||||
{
|
||||
$cliConfiguration = (new CliConfigurationBuilder)->fromParameters([]);
|
||||
@@ -74,17 +62,11 @@ final class Configuration implements HandlesArguments, Terminable
|
||||
return is_string($configurationFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the temporary phpunit.xml path.
|
||||
*/
|
||||
private function getTempPhpunitXmlPath(): string
|
||||
{
|
||||
return getcwd().'/.pest.xml';
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates the plugin.
|
||||
*/
|
||||
public function terminate(): void
|
||||
{
|
||||
$path = $this->getTempPhpunitXmlPath();
|
||||
|
||||
@@ -27,37 +27,19 @@ final class Coverage implements AddsOutput, HandlesArguments
|
||||
|
||||
private const string ONLY_COVERED_OPTION = 'only-covered';
|
||||
|
||||
/**
|
||||
* Whether it should show the coverage or not.
|
||||
*/
|
||||
public bool $coverage = false;
|
||||
|
||||
/**
|
||||
* Whether it should show the coverage or not.
|
||||
*/
|
||||
public bool $compact = false;
|
||||
|
||||
/**
|
||||
* The minimum coverage.
|
||||
*/
|
||||
public float $coverageMin = 0.0;
|
||||
|
||||
/**
|
||||
* The exactly coverage.
|
||||
*/
|
||||
public ?float $coverageExactly = null;
|
||||
|
||||
/**
|
||||
* Whether it should show only covered files.
|
||||
*/
|
||||
public bool $showOnlyCovered = false;
|
||||
|
||||
/**
|
||||
* Creates a new Plugin instance.
|
||||
*/
|
||||
public function __construct(private readonly OutputInterface $output)
|
||||
{
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,9 +168,6 @@ final class Coverage implements AddsOutput, HandlesArguments
|
||||
return $exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the comparable coverage to a percentage with one decimal.
|
||||
*/
|
||||
private function computeComparableCoverage(float $coverage): float
|
||||
{
|
||||
return floor($coverage * 10) / 10;
|
||||
|
||||
@@ -11,19 +11,10 @@ use Pest\Contracts\Plugins\HandlesArguments;
|
||||
*/
|
||||
final class Environment implements HandlesArguments
|
||||
{
|
||||
/**
|
||||
* The continuous integration environment.
|
||||
*/
|
||||
public const string CI = 'ci';
|
||||
|
||||
/**
|
||||
* The local environment.
|
||||
*/
|
||||
public const string LOCAL = 'local';
|
||||
|
||||
/**
|
||||
* The current environment.
|
||||
*/
|
||||
private static ?string $name = null;
|
||||
|
||||
/**
|
||||
@@ -42,9 +33,6 @@ final class Environment implements HandlesArguments
|
||||
return array_values($arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the environment name.
|
||||
*/
|
||||
public static function name(?string $name = null): string
|
||||
{
|
||||
if (is_string($name)) {
|
||||
|
||||
@@ -18,13 +18,10 @@ final readonly class Help implements HandlesArguments
|
||||
{
|
||||
use Concerns\HandleArguments;
|
||||
|
||||
/**
|
||||
* Creates a new Plugin instance.
|
||||
*/
|
||||
public function __construct(
|
||||
private OutputInterface $output
|
||||
) {
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,9 +77,6 @@ final readonly class Help implements HandlesArguments
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Colorizes the given string options.
|
||||
*/
|
||||
private function colorizeOptions(string $argument): string
|
||||
{
|
||||
return (string) preg_replace(
|
||||
|
||||
+1
-16
@@ -17,14 +17,8 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
*/
|
||||
final readonly class Init implements HandlesArguments
|
||||
{
|
||||
/**
|
||||
* The option the triggers the init job.
|
||||
*/
|
||||
private const string INIT_OPTION = '--init';
|
||||
|
||||
/**
|
||||
* The files that will be created.
|
||||
*/
|
||||
private const array STUBS = [
|
||||
'phpunit.xml.stub' => 'phpunit.xml',
|
||||
'Pest.php.stub' => 'tests/Pest.php',
|
||||
@@ -33,15 +27,12 @@ final readonly class Init implements HandlesArguments
|
||||
'Feature/ExampleTest.php.stub' => 'tests/Feature/ExampleTest.php',
|
||||
];
|
||||
|
||||
/**
|
||||
* Creates a new Plugin instance.
|
||||
*/
|
||||
public function __construct(
|
||||
private TestSuite $testSuite,
|
||||
private InputInterface $input,
|
||||
private OutputInterface $output
|
||||
) {
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,9 +54,6 @@ final readonly class Init implements HandlesArguments
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the tests directory.
|
||||
*/
|
||||
public function init(): void
|
||||
{
|
||||
$testsBaseDir = "{$this->testSuite->rootPath}/tests";
|
||||
@@ -114,9 +102,6 @@ final readonly class Init implements HandlesArguments
|
||||
(new Thanks($this->input, $this->output))();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if laravel is installed through Composer
|
||||
*/
|
||||
private function isLaravelInstalled(): bool
|
||||
{
|
||||
return InstalledVersions::isInstalled('laravel/framework');
|
||||
|
||||
@@ -15,18 +15,12 @@ final class Memory implements AddsOutput, HandlesArguments
|
||||
{
|
||||
use Concerns\HandleArguments;
|
||||
|
||||
/**
|
||||
* If memory should be displayed.
|
||||
*/
|
||||
private bool $enabled = false;
|
||||
|
||||
/**
|
||||
* Creates a new Plugin instance.
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly OutputInterface $output
|
||||
) {
|
||||
// ..
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user