mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 15:57:21 +01:00
Merge branch 'master' into performs_no_expectations
# Conflicts: # src/PendingCalls/TestCall.php
This commit is contained in:
8
.github/workflows/static.yml
vendored
8
.github/workflows/static.yml
vendored
@ -20,10 +20,10 @@ jobs:
|
|||||||
coverage: none
|
coverage: none
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: composer update --no-interaction --no-progress
|
run: composer update --no-interaction --no-progress --ansi
|
||||||
|
|
||||||
- name: Run PHP-CS-Fixer
|
- name: Run PHP-CS-Fixer
|
||||||
run: PHP_CS_FIXER_IGNORE_ENV=true vendor/bin/php-cs-fixer fix -v --allow-risky=yes --dry-run
|
run: PHP_CS_FIXER_IGNORE_ENV=true vendor/bin/php-cs-fixer fix -v --allow-risky=yes --dry-run --ansi
|
||||||
|
|
||||||
phpstan:
|
phpstan:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -45,7 +45,7 @@ jobs:
|
|||||||
coverage: none
|
coverage: none
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: composer update --prefer-stable --no-interaction --no-progress
|
run: composer update --prefer-stable --no-interaction --no-progress --ansi
|
||||||
|
|
||||||
- name: Run PHPStan
|
- name: Run PHPStan
|
||||||
run: vendor/bin/phpstan analyse --no-progress --debug
|
run: vendor/bin/phpstan analyse --no-progress --debug --ansi
|
||||||
|
|||||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
|||||||
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||||
|
|
||||||
- name: Install PHP dependencies
|
- name: Install PHP dependencies
|
||||||
run: composer update --${{ matrix.dependency-version }} --no-interaction --no-progress
|
run: composer update --${{ matrix.dependency-version }} --no-interaction --no-progress --ansi
|
||||||
|
|
||||||
- name: Unit Tests
|
- name: Unit Tests
|
||||||
run: php bin/pest --colors=always --exclude-group=integration
|
run: php bin/pest --colors=always --exclude-group=integration
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
|
<a href="https://supportukrainenow.org/"><img src="https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner-direct.svg" width="100%"></a>
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://raw.githubusercontent.com/pestphp/art/master/readme.png" width="600" alt="PEST">
|
<img src="https://raw.githubusercontent.com/pestphp/art/master/readme.png" width="600" alt="PEST">
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@ -21,6 +25,7 @@ We would like to extend our thanks to the following sponsors for funding Pest de
|
|||||||
|
|
||||||
### Platinum Sponsors
|
### Platinum Sponsors
|
||||||
|
|
||||||
|
- **[Advent](https://advent.dev)**
|
||||||
- **[Spatie](https://spatie.be)**
|
- **[Spatie](https://spatie.be)**
|
||||||
- **[Worksome](https://www.worksome.com/)**
|
- **[Worksome](https://www.worksome.com/)**
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,7 @@ final class BootFiles
|
|||||||
if (is_dir($filename)) {
|
if (is_dir($filename)) {
|
||||||
$directory = new RecursiveDirectoryIterator($filename);
|
$directory = new RecursiveDirectoryIterator($filename);
|
||||||
$iterator = new RecursiveIteratorIterator($directory);
|
$iterator = new RecursiveIteratorIterator($directory);
|
||||||
|
/** @var \DirectoryIterator $file */
|
||||||
foreach ($iterator as $file) {
|
foreach ($iterator as $file) {
|
||||||
$this->load($file->__toString());
|
$this->load($file->__toString());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ trait Pipeable
|
|||||||
$this->pipe($name, function ($next, ...$arguments) use ($handler, $filter) {
|
$this->pipe($name, function ($next, ...$arguments) use ($handler, $filter) {
|
||||||
/* @phpstan-ignore-next-line */
|
/* @phpstan-ignore-next-line */
|
||||||
if ($filter($this->value, ...$arguments)) {
|
if ($filter($this->value, ...$arguments)) {
|
||||||
//@phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
$handler->bindTo($this, get_class($this))(...$arguments);
|
$handler->bindTo($this, get_class($this))(...$arguments);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -76,6 +76,22 @@ final class Expectation
|
|||||||
return $this->toBeJson()->and($value);
|
return $this->toBeJson()->and($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump the expectation value.
|
||||||
|
*
|
||||||
|
* @return self<TValue>
|
||||||
|
*/
|
||||||
|
public function dump(mixed ...$arguments): self
|
||||||
|
{
|
||||||
|
if (function_exists('dump')) {
|
||||||
|
dump($this->value, ...$arguments);
|
||||||
|
} else {
|
||||||
|
var_dump($this->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump the expectation value and end the script.
|
* Dump the expectation value and end the script.
|
||||||
*
|
*
|
||||||
@ -151,7 +167,6 @@ final class Expectation
|
|||||||
throw new BadMethodCallException('Expectation value is not iterable.');
|
throw new BadMethodCallException('Expectation value is not iterable.');
|
||||||
}
|
}
|
||||||
|
|
||||||
//@phpstan-ignore-next-line
|
|
||||||
$value = is_array($this->value) ? $this->value : iterator_to_array($this->value);
|
$value = is_array($this->value) ? $this->value : iterator_to_array($this->value);
|
||||||
$keys = array_keys($value);
|
$keys = array_keys($value);
|
||||||
$values = array_values($value);
|
$values = array_values($value);
|
||||||
@ -292,7 +307,7 @@ final class Expectation
|
|||||||
private function getExpectationClosure(string $name): Closure
|
private function getExpectationClosure(string $name): Closure
|
||||||
{
|
{
|
||||||
if (method_exists(Mixins\Expectation::class, $name)) {
|
if (method_exists(Mixins\Expectation::class, $name)) {
|
||||||
//@phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
return Closure::fromCallable([new Mixins\Expectation($this->value), $name]);
|
return Closure::fromCallable([new Mixins\Expectation($this->value), $name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
src/Factories/Annotations/CoversNothing.php
Normal file
30
src/Factories/Annotations/CoversNothing.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Factories\Annotations;
|
||||||
|
|
||||||
|
use Pest\Factories\Covers\CoversNothing as CoversNothingFactory;
|
||||||
|
use Pest\Factories\TestCaseMethodFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class CoversNothing
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Adds annotations regarding the "depends" feature.
|
||||||
|
*
|
||||||
|
* @param array<int, string> $annotations
|
||||||
|
*
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
public function __invoke(TestCaseMethodFactory $method, array $annotations): array
|
||||||
|
{
|
||||||
|
if (($method->covers[0] ?? null) instanceof CoversNothingFactory) {
|
||||||
|
$annotations[] = '@coversNothing';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $annotations;
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/Factories/Attributes/Attribute.php
Normal file
30
src/Factories/Attributes/Attribute.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Factories\Attributes;
|
||||||
|
|
||||||
|
use Pest\Factories\TestCaseMethodFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
abstract class Attribute
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the attribute should be placed above the class instead of above the method.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public const ABOVE_CLASS = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int, string> $attributes
|
||||||
|
*
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
public function __invoke(TestCaseMethodFactory $method, array $attributes): array // @phpstan-ignore-line
|
||||||
|
{
|
||||||
|
return $attributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/Factories/Attributes/Covers.php
Normal file
47
src/Factories/Attributes/Covers.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Factories\Attributes;
|
||||||
|
|
||||||
|
use Pest\Factories\Covers\CoversClass;
|
||||||
|
use Pest\Factories\Covers\CoversFunction;
|
||||||
|
use Pest\Factories\TestCaseMethodFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class Covers extends Attribute
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the attribute should be placed above the classe instead of above the method.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public const ABOVE_CLASS = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds attributes regarding the "covers" feature.
|
||||||
|
*
|
||||||
|
* @param array<int, string> $attributes
|
||||||
|
*
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
public function __invoke(TestCaseMethodFactory $method, array $attributes): array
|
||||||
|
{
|
||||||
|
foreach ($method->covers as $covering) {
|
||||||
|
if ($covering instanceof CoversClass) {
|
||||||
|
// Prepend a backslash for FQN classes
|
||||||
|
if (str_contains($covering->class, '\\')) {
|
||||||
|
$covering->class = '\\' . $covering->class;
|
||||||
|
}
|
||||||
|
|
||||||
|
$attributes[] = "#[\PHPUnit\Framework\Attributes\CoversClass({$covering->class}::class)]";
|
||||||
|
} elseif ($covering instanceof CoversFunction) {
|
||||||
|
$attributes[] = "#[\PHPUnit\Framework\Attributes\CoversFunction('{$covering->function}')]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $attributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/Factories/Covers/CoversClass.php
Normal file
15
src/Factories/Covers/CoversClass.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Factories\Covers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class CoversClass
|
||||||
|
{
|
||||||
|
public function __construct(public string $class)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/Factories/Covers/CoversFunction.php
Normal file
15
src/Factories/Covers/CoversFunction.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Factories\Covers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class CoversFunction
|
||||||
|
{
|
||||||
|
public function __construct(public string $function)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/Factories/Covers/CoversNothing.php
Normal file
12
src/Factories/Covers/CoversNothing.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Factories\Covers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class CoversNothing
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -33,6 +33,16 @@ final class TestCaseFactory
|
|||||||
private static array $annotations = [
|
private static array $annotations = [
|
||||||
Annotations\Depends::class,
|
Annotations\Depends::class,
|
||||||
Annotations\Groups::class,
|
Annotations\Groups::class,
|
||||||
|
Annotations\CoversNothing::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of attributes.
|
||||||
|
*
|
||||||
|
* @var array<int, class-string<\Pest\Factories\Attributes\Attribute>>
|
||||||
|
*/
|
||||||
|
private static array $attributes = [
|
||||||
|
Attributes\Covers::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,11 +151,33 @@ final class TestCaseFactory
|
|||||||
$classFQN .= $className;
|
$classFQN .= $className;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$classAvailableAttributes = array_filter(self::$attributes, fn (string $attribute) => $attribute::ABOVE_CLASS);
|
||||||
|
$methodAvailableAttributes = array_filter(self::$attributes, fn (string $attribute) => !$attribute::ABOVE_CLASS);
|
||||||
|
|
||||||
|
$classAttributes = [];
|
||||||
|
|
||||||
|
foreach ($classAvailableAttributes as $attribute) {
|
||||||
|
$classAttributes = array_reduce(
|
||||||
|
$methods,
|
||||||
|
fn (array $carry, TestCaseMethodFactory $methodFactory) => (new $attribute())->__invoke($methodFactory, $carry),
|
||||||
|
$classAttributes
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$methodsCode = implode('', array_map(
|
$methodsCode = implode('', array_map(
|
||||||
fn (TestCaseMethodFactory $methodFactory) => $methodFactory->buildForEvaluation($classFQN, self::$annotations),
|
fn (TestCaseMethodFactory $methodFactory) => $methodFactory->buildForEvaluation(
|
||||||
|
$classFQN,
|
||||||
|
self::$annotations,
|
||||||
|
$methodAvailableAttributes
|
||||||
|
),
|
||||||
$methods
|
$methods
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$classAttributesCode = implode('', array_map(
|
||||||
|
static fn (string $attribute) => sprintf("\n %s", $attribute),
|
||||||
|
array_unique($classAttributes),
|
||||||
|
));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
eval("
|
eval("
|
||||||
namespace $namespace;
|
namespace $namespace;
|
||||||
@ -153,6 +185,7 @@ final class TestCaseFactory
|
|||||||
use Pest\Repositories\DatasetsRepository as __PestDatasets;
|
use Pest\Repositories\DatasetsRepository as __PestDatasets;
|
||||||
use Pest\TestSuite as __PestTestSuite;
|
use Pest\TestSuite as __PestTestSuite;
|
||||||
|
|
||||||
|
$classAttributesCode
|
||||||
final class $className extends $baseClass implements $hasPrintableTestCaseClassFQN {
|
final class $className extends $baseClass implements $hasPrintableTestCaseClassFQN {
|
||||||
$traitsCode
|
$traitsCode
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,13 @@ final class TestCaseMethodFactory
|
|||||||
*/
|
*/
|
||||||
public array $groups = [];
|
public array $groups = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The covered classes and functions, if any.
|
||||||
|
*
|
||||||
|
* @var array<int, \Pest\Factories\Covers\CoversClass|\Pest\Factories\Covers\CoversFunction|\Pest\Factories\Covers\CoversNothing>
|
||||||
|
*/
|
||||||
|
public array $covers = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Factory instance.
|
* Creates a new Factory instance.
|
||||||
*/
|
*/
|
||||||
@ -106,9 +113,10 @@ final class TestCaseMethodFactory
|
|||||||
/**
|
/**
|
||||||
* Creates a PHPUnit method as a string ready for evaluation.
|
* Creates a PHPUnit method as a string ready for evaluation.
|
||||||
*
|
*
|
||||||
* @param array<int, class-string> $annotationsToUse
|
* @param array<int, class-string> $annotationsToUse
|
||||||
|
* @param array<int, class-string<\Pest\Factories\Attributes\Attribute>> $attributesToUse
|
||||||
*/
|
*/
|
||||||
public function buildForEvaluation(string $classFQN, array $annotationsToUse): string
|
public function buildForEvaluation(string $classFQN, array $annotationsToUse, array $attributesToUse): string
|
||||||
{
|
{
|
||||||
if ($this->description === null) {
|
if ($this->description === null) {
|
||||||
throw ShouldNotHappen::fromMessage('The test description may not be empty.');
|
throw ShouldNotHappen::fromMessage('The test description may not be empty.');
|
||||||
@ -122,12 +130,17 @@ final class TestCaseMethodFactory
|
|||||||
|
|
||||||
$datasetsCode = '';
|
$datasetsCode = '';
|
||||||
$annotations = ['@test'];
|
$annotations = ['@test'];
|
||||||
|
$attributes = [];
|
||||||
|
|
||||||
foreach ($annotationsToUse as $annotation) {
|
foreach ($annotationsToUse as $annotation) {
|
||||||
/** @phpstan-ignore-next-line */
|
/** @phpstan-ignore-next-line */
|
||||||
$annotations = (new $annotation())->__invoke($this, $annotations);
|
$annotations = (new $annotation())->__invoke($this, $annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($attributesToUse as $attribute) {
|
||||||
|
$attributes = (new $attribute())->__invoke($this, $attributes);
|
||||||
|
}
|
||||||
|
|
||||||
if (count($this->datasets) > 0) {
|
if (count($this->datasets) > 0) {
|
||||||
$dataProviderName = $methodName . '_dataset';
|
$dataProviderName = $methodName . '_dataset';
|
||||||
$annotations[] = "@dataProvider $dataProviderName";
|
$annotations[] = "@dataProvider $dataProviderName";
|
||||||
@ -138,10 +151,15 @@ final class TestCaseMethodFactory
|
|||||||
static fn ($annotation) => sprintf("\n * %s", $annotation), $annotations,
|
static fn ($annotation) => sprintf("\n * %s", $annotation), $annotations,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$attributes = implode('', array_map(
|
||||||
|
static fn ($attribute) => sprintf("\n %s", $attribute), $attributes,
|
||||||
|
));
|
||||||
|
|
||||||
return <<<EOF
|
return <<<EOF
|
||||||
|
|
||||||
/**$annotations
|
/**$annotations
|
||||||
*/
|
*/
|
||||||
|
$attributes
|
||||||
public function $methodName()
|
public function $methodName()
|
||||||
{
|
{
|
||||||
return \$this->__runTest(
|
return \$this->__runTest(
|
||||||
|
|||||||
@ -37,7 +37,7 @@ final class Kernel
|
|||||||
public static function boot(): self
|
public static function boot(): self
|
||||||
{
|
{
|
||||||
foreach (self::$bootstrappers as $bootstrapper) {
|
foreach (self::$bootstrappers as $bootstrapper) {
|
||||||
//@phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
(new $bootstrapper())->__invoke();
|
(new $bootstrapper())->__invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ namespace Pest\Mixins;
|
|||||||
|
|
||||||
use BadMethodCallException;
|
use BadMethodCallException;
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use Error;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Pest\Exceptions\InvalidExpectationValue;
|
use Pest\Exceptions\InvalidExpectationValue;
|
||||||
use Pest\Support\Arr;
|
use Pest\Support\Arr;
|
||||||
@ -282,7 +283,7 @@ final class Expectation
|
|||||||
{
|
{
|
||||||
$this->toBeObject();
|
$this->toBeObject();
|
||||||
|
|
||||||
//@phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
Assert::assertTrue(property_exists($this->value, $name));
|
Assert::assertTrue(property_exists($this->value, $name));
|
||||||
|
|
||||||
if (func_num_args() > 1) {
|
if (func_num_args() > 1) {
|
||||||
@ -533,7 +534,7 @@ final class Expectation
|
|||||||
{
|
{
|
||||||
Assert::assertIsString($this->value);
|
Assert::assertIsString($this->value);
|
||||||
|
|
||||||
//@phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
Assert::assertJson($this->value);
|
Assert::assertJson($this->value);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -579,7 +580,7 @@ final class Expectation
|
|||||||
try {
|
try {
|
||||||
Assert::assertTrue(Arr::has($array, $key));
|
Assert::assertTrue(Arr::has($array, $key));
|
||||||
|
|
||||||
/* @phpstan-ignore-next-line */
|
/* @phpstan-ignore-next-line */
|
||||||
} catch (ExpectationFailedException $exception) {
|
} catch (ExpectationFailedException $exception) {
|
||||||
throw new ExpectationFailedException("Failed asserting that an array has the key '$key'", $exception->getComparisonFailure());
|
throw new ExpectationFailedException("Failed asserting that an array has the key '$key'", $exception->getComparisonFailure());
|
||||||
}
|
}
|
||||||
@ -822,8 +823,12 @@ final class Expectation
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
($this->value)();
|
($this->value)();
|
||||||
} catch (Throwable $e) { // @phpstan-ignore-line
|
} catch (Throwable $e) {
|
||||||
if (!class_exists($exception)) {
|
if (!class_exists($exception)) {
|
||||||
|
if ($e instanceof Error && $e->getMessage() === "Class \"$exception\" not found") {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
Assert::assertStringContainsString($exception, $e->getMessage());
|
Assert::assertStringContainsString($exception, $e->getMessage());
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
@ -5,6 +5,10 @@ declare(strict_types=1);
|
|||||||
namespace Pest\PendingCalls;
|
namespace Pest\PendingCalls;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use Pest\Factories\Covers\CoversClass;
|
||||||
|
use Pest\Factories\Covers\CoversFunction;
|
||||||
|
use Pest\Factories\Covers\CoversNothing;
|
||||||
use Pest\Factories\TestCaseMethodFactory;
|
use Pest\Factories\TestCaseMethodFactory;
|
||||||
use Pest\Support\Backtrace;
|
use Pest\Support\Backtrace;
|
||||||
use Pest\Support\HigherOrderCallables;
|
use Pest\Support\HigherOrderCallables;
|
||||||
@ -45,9 +49,11 @@ final class TestCall
|
|||||||
/**
|
/**
|
||||||
* Asserts that the test throws the given `$exceptionClass` when called.
|
* Asserts that the test throws the given `$exceptionClass` when called.
|
||||||
*/
|
*/
|
||||||
public function throws(string $exception, string $exceptionMessage = null): TestCall
|
public function throws(string|int $exception, string $exceptionMessage = null, int $exceptionCode = null): TestCall
|
||||||
{
|
{
|
||||||
if (class_exists($exception)) {
|
if (is_int($exception)) {
|
||||||
|
$exceptionCode = $exception;
|
||||||
|
} elseif (class_exists($exception)) {
|
||||||
$this->testCaseMethod
|
$this->testCaseMethod
|
||||||
->proxies
|
->proxies
|
||||||
->add(Backtrace::file(), Backtrace::line(), 'expectException', [$exception]);
|
->add(Backtrace::file(), Backtrace::line(), 'expectException', [$exception]);
|
||||||
@ -61,6 +67,12 @@ final class TestCall
|
|||||||
->add(Backtrace::file(), Backtrace::line(), 'expectExceptionMessage', [$exceptionMessage]);
|
->add(Backtrace::file(), Backtrace::line(), 'expectExceptionMessage', [$exceptionMessage]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_int($exceptionCode)) {
|
||||||
|
$this->testCaseMethod
|
||||||
|
->proxies
|
||||||
|
->add(Backtrace::file(), Backtrace::line(), 'expectExceptionCode', [$exceptionCode]);
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +81,7 @@ final class TestCall
|
|||||||
*
|
*
|
||||||
* @param (callable(): bool)|bool $condition
|
* @param (callable(): bool)|bool $condition
|
||||||
*/
|
*/
|
||||||
public function throwsIf(callable|bool $condition, string $exception, string $exceptionMessage = null): TestCall
|
public function throwsIf(callable|bool $condition, string|int $exception, string $exceptionMessage = null, int $exceptionCode = null): TestCall
|
||||||
{
|
{
|
||||||
$condition = is_callable($condition)
|
$condition = is_callable($condition)
|
||||||
? $condition
|
? $condition
|
||||||
@ -78,7 +90,7 @@ final class TestCall
|
|||||||
};
|
};
|
||||||
|
|
||||||
if ($condition()) {
|
if ($condition()) {
|
||||||
return $this->throws($exception, $exceptionMessage);
|
return $this->throws($exception, $exceptionMessage, $exceptionCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -160,6 +172,63 @@ final class TestCall
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the covered classes or methods.
|
||||||
|
*/
|
||||||
|
public function covers(string ...$classesOrFunctions): TestCall
|
||||||
|
{
|
||||||
|
foreach ($classesOrFunctions as $classOrFunction) {
|
||||||
|
$isClass = class_exists($classOrFunction);
|
||||||
|
$isMethod = function_exists($classOrFunction);
|
||||||
|
|
||||||
|
if (!$isClass && !$isMethod) {
|
||||||
|
throw new InvalidArgumentException(sprintf('No class or method named "%s" has been found.', $classOrFunction));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($isClass) {
|
||||||
|
$this->coversClass($classOrFunction);
|
||||||
|
} else {
|
||||||
|
$this->coversFunction($classOrFunction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the covered classes.
|
||||||
|
*/
|
||||||
|
public function coversClass(string ...$classes): TestCall
|
||||||
|
{
|
||||||
|
foreach ($classes as $class) {
|
||||||
|
$this->testCaseMethod->covers[] = new CoversClass($class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the covered functions.
|
||||||
|
*/
|
||||||
|
public function coversFunction(string ...$functions): TestCall
|
||||||
|
{
|
||||||
|
foreach ($functions as $function) {
|
||||||
|
$this->testCaseMethod->covers[] = new CoversFunction($function);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets that the current test covers nothing.
|
||||||
|
*/
|
||||||
|
public function coversNothing(): TestCall
|
||||||
|
{
|
||||||
|
$this->testCaseMethod->covers = [new CoversNothing()];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Informs the test runner that no expectations happen in this test,
|
* Informs the test runner that no expectations happen in this test,
|
||||||
* and its purpose is simply to check whether the given code can
|
* and its purpose is simply to check whether the given code can
|
||||||
|
|||||||
@ -156,11 +156,11 @@ final class DatasetsRepository
|
|||||||
$datasets[$index] = iterator_to_array($datasets[$index]);
|
$datasets[$index] = iterator_to_array($datasets[$index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
foreach ($datasets[$index] as $key => $values) {
|
foreach ($datasets[$index] as $key => $values) {
|
||||||
$values = is_array($values) ? $values : [$values];
|
$values = is_array($values) ? $values : [$values];
|
||||||
$processedDataset[] = [
|
$processedDataset[] = [
|
||||||
'label' => self::getDatasetDescription($key, $values), //@phpstan-ignore-line
|
'label' => self::getDatasetDescription($key, $values), // @phpstan-ignore-line
|
||||||
'values' => $values,
|
'values' => $values,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ final class DatasetsRepository
|
|||||||
$result = $tmp;
|
$result = $tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -85,7 +85,7 @@ final class Container
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//@phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
return $this->get($candidate);
|
return $this->get($candidate);
|
||||||
},
|
},
|
||||||
$constructor->getParameters()
|
$constructor->getParameters()
|
||||||
|
|||||||
@ -40,7 +40,7 @@ final class HigherOrderMessageCollection
|
|||||||
public function chain(object $target): void
|
public function chain(object $target): void
|
||||||
{
|
{
|
||||||
foreach ($this->messages as $message) {
|
foreach ($this->messages as $message) {
|
||||||
//@phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
$target = $message->call($target) ?? $target;
|
$target = $message->call($target) ?? $target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use Symfony\Component\Console\Output\ConsoleOutput;
|
|||||||
it('has plugin')->assertTrue(class_exists(CoveragePlugin::class));
|
it('has plugin')->assertTrue(class_exists(CoveragePlugin::class));
|
||||||
|
|
||||||
it('adds coverage if --coverage exist', function () {
|
it('adds coverage if --coverage exist', function () {
|
||||||
$plugin = new CoveragePlugin(new ConsoleOutput());
|
$plugin = new CoveragePlugin(new ConsoleOutput());
|
||||||
$testSuite = TestSuite::getInstance();
|
$testSuite = TestSuite::getInstance();
|
||||||
|
|
||||||
expect($plugin->coverage)->toBeFalse();
|
expect($plugin->coverage)->toBeFalse();
|
||||||
|
|||||||
78
tests/Features/Covers.php
Normal file
78
tests/Features/Covers.php
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Factories\Attributes\Covers;
|
||||||
|
use Pest\PendingCalls\TestCall;
|
||||||
|
use Pest\TestSuite;
|
||||||
|
|
||||||
|
$runCounter = 0;
|
||||||
|
|
||||||
|
class TestCoversClass1
|
||||||
|
{
|
||||||
|
}
|
||||||
|
class TestCoversClass2
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestCoversClass3
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoversFunction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
it('uses the correct PHPUnit attribute for class', function () {
|
||||||
|
$attributes = (new ReflectionClass($this))->getAttributes();
|
||||||
|
|
||||||
|
expect($attributes[0]->getName())->toBe('PHPUnit\Framework\Attributes\CoversClass');
|
||||||
|
expect($attributes[0]->getArguments()[0])->toBe('P\Tests\Features\TestCoversClass1');
|
||||||
|
})->coversClass(TestCoversClass1::class);
|
||||||
|
|
||||||
|
it('uses the correct PHPUnit attribute for function', function () {
|
||||||
|
$attributes = (new ReflectionClass($this))->getAttributes();
|
||||||
|
|
||||||
|
expect($attributes[1]->getName())->toBe('PHPUnit\Framework\Attributes\CoversFunction');
|
||||||
|
expect($attributes[1]->getArguments()[0])->toBe('foo');
|
||||||
|
})->coversFunction('foo');
|
||||||
|
|
||||||
|
it('removes duplicated attributes', function () {
|
||||||
|
$attributes = (new ReflectionClass($this))->getAttributes();
|
||||||
|
|
||||||
|
expect($attributes[2]->getName())->toBe('PHPUnit\Framework\Attributes\CoversClass');
|
||||||
|
expect($attributes[2]->getArguments()[0])->toBe('P\Tests\Features\TestCoversClass2');
|
||||||
|
expect($attributes[3]->getName())->toBe('PHPUnit\Framework\Attributes\CoversClass');
|
||||||
|
expect($attributes[3]->getArguments()[0])->toBe('Pest\Factories\Attributes\Covers');
|
||||||
|
expect($attributes[4]->getName())->toBe('PHPUnit\Framework\Attributes\CoversFunction');
|
||||||
|
expect($attributes[4]->getArguments()[0])->toBe('bar');
|
||||||
|
expect($attributes[5]->getName())->toBe('PHPUnit\Framework\Attributes\CoversFunction');
|
||||||
|
expect($attributes[5]->getArguments()[0])->toBe('baz');
|
||||||
|
})
|
||||||
|
->coversClass(TestCoversClass2::class, TestCoversClass1::class, Covers::class)
|
||||||
|
->coversFunction('bar', 'foo', 'baz');
|
||||||
|
|
||||||
|
it('guesses if the given argument is a class or function', function () {
|
||||||
|
$attributes = (new ReflectionClass($this))->getAttributes();
|
||||||
|
|
||||||
|
expect($attributes[6]->getName())->toBe('PHPUnit\Framework\Attributes\CoversClass');
|
||||||
|
expect($attributes[6]->getArguments()[0])->toBe('P\Tests\Features\TestCoversClass3');
|
||||||
|
expect($attributes[7]->getName())->toBe('PHPUnit\Framework\Attributes\CoversFunction');
|
||||||
|
expect($attributes[7]->getArguments()[0])->toBe('testCoversFunction');
|
||||||
|
})->covers(TestCoversClass3::class, 'testCoversFunction');
|
||||||
|
|
||||||
|
it('appends CoversNothing to method attributes', function () {
|
||||||
|
$phpDoc = (new ReflectionClass($this))->getMethod($this->getName());
|
||||||
|
|
||||||
|
expect(str_contains($phpDoc->getDocComment(), '* @coversNothing'))->toBeTrue();
|
||||||
|
})->coversNothing();
|
||||||
|
|
||||||
|
it('does not append CoversNothing to other methods', function () {
|
||||||
|
$phpDoc = (new ReflectionClass($this))->getMethod($this->getName());
|
||||||
|
|
||||||
|
expect(str_contains($phpDoc->getDocComment(), '* @coversNothing'))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws exception if no class nor method has been found', function () {
|
||||||
|
$testCall = new TestCall(TestSuite::getInstance(), 'filename', 'description', fn () => 'closure');
|
||||||
|
|
||||||
|
$testCall->covers('fakeName');
|
||||||
|
})->throws(InvalidArgumentException::class, 'No class or method named "fakeName" has been found.');
|
||||||
@ -14,10 +14,18 @@ it('catch exceptions and messages', function () {
|
|||||||
throw new Exception('Something bad happened');
|
throw new Exception('Something bad happened');
|
||||||
})->throws(Exception::class, 'Something bad happened');
|
})->throws(Exception::class, 'Something bad happened');
|
||||||
|
|
||||||
|
it('catch exceptions, messages and code', function () {
|
||||||
|
throw new Exception('Something bad happened', 1);
|
||||||
|
})->throws(Exception::class, 'Something bad happened', 1);
|
||||||
|
|
||||||
it('can just define the message', function () {
|
it('can just define the message', function () {
|
||||||
throw new Exception('Something bad happened');
|
throw new Exception('Something bad happened');
|
||||||
})->throws('Something bad happened');
|
})->throws('Something bad happened');
|
||||||
|
|
||||||
|
it('can just define the code', function () {
|
||||||
|
throw new Exception('Something bad happened', 1);
|
||||||
|
})->throws(1);
|
||||||
|
|
||||||
it('not catch exceptions if given condition is false', function () {
|
it('not catch exceptions if given condition is false', function () {
|
||||||
$this->assertTrue(true);
|
$this->assertTrue(true);
|
||||||
})->throwsIf(false, Exception::class);
|
})->throwsIf(false, Exception::class);
|
||||||
@ -30,10 +38,22 @@ it('catch exceptions and messages if given condition is true', function () {
|
|||||||
throw new Exception('Something bad happened');
|
throw new Exception('Something bad happened');
|
||||||
})->throwsIf(true, Exception::class, 'Something bad happened');
|
})->throwsIf(true, Exception::class, 'Something bad happened');
|
||||||
|
|
||||||
|
it('catch exceptions, messages and code if given condition is true', function () {
|
||||||
|
throw new Exception('Something bad happened', 1);
|
||||||
|
})->throwsIf(true, Exception::class, 'Something bad happened', 1);
|
||||||
|
|
||||||
it('can just define the message if given condition is true', function () {
|
it('can just define the message if given condition is true', function () {
|
||||||
throw new Exception('Something bad happened');
|
throw new Exception('Something bad happened');
|
||||||
})->throwsIf(true, 'Something bad happened');
|
})->throwsIf(true, 'Something bad happened');
|
||||||
|
|
||||||
|
it('can just define the code if given condition is true', function () {
|
||||||
|
throw new Exception('Something bad happened', 1);
|
||||||
|
})->throwsIf(true, 1);
|
||||||
|
|
||||||
it('can just define the message if given condition is 1', function () {
|
it('can just define the message if given condition is 1', function () {
|
||||||
throw new Exception('Something bad happened');
|
throw new Exception('Something bad happened');
|
||||||
})->throwsIf(1, 'Something bad happened');
|
})->throwsIf(1, 'Something bad happened');
|
||||||
|
|
||||||
|
it('can just define the code if given condition is 1', function () {
|
||||||
|
throw new Exception('Something bad happened', 1);
|
||||||
|
})->throwsIf(1, 1);
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class Number
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
public int $value
|
public int $value
|
||||||
) {
|
) {
|
||||||
//..
|
// ..
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ class Char
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
public string $value
|
public string $value
|
||||||
) {
|
) {
|
||||||
//..
|
// ..
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ class Symbol
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
public string $value
|
public string $value
|
||||||
) {
|
) {
|
||||||
//..
|
// ..
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,11 +69,11 @@ expect()->pipe('toBe', function ($next, $expected) use ($state) {
|
|||||||
assertInstanceOf(Char::class, $expected);
|
assertInstanceOf(Char::class, $expected);
|
||||||
assertEquals($this->value->value, $expected->value);
|
assertEquals($this->value->value, $expected->value);
|
||||||
|
|
||||||
//returning nothing stops pipeline execution
|
// returning nothing stops pipeline execution
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//calling $next(); let the pipeline to keep running
|
// calling $next(); let the pipeline to keep running
|
||||||
$next();
|
$next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use PHPUnit\Framework\ExpectationFailedException;
|
|||||||
expect(true)->toBeTrue()->and(false)->toBeFalse();
|
expect(true)->toBeTrue()->and(false)->toBeFalse();
|
||||||
|
|
||||||
test('strict comparisons', function () {
|
test('strict comparisons', function () {
|
||||||
$nuno = new stdClass();
|
$nuno = new stdClass();
|
||||||
$dries = new stdClass();
|
$dries = new stdClass();
|
||||||
|
|
||||||
expect($nuno)->toBe($nuno)->not->toBe($dries);
|
expect($nuno)->toBe($nuno)->not->toBe($dries);
|
||||||
|
|||||||
@ -3,24 +3,24 @@
|
|||||||
use PHPUnit\Framework\ExpectationFailedException;
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
test('pass', function () {
|
test('pass', function () {
|
||||||
$object = new stdClass();
|
$object = new stdClass();
|
||||||
$object->name = 'Jhon';
|
$object->name = 'Jhon';
|
||||||
$object->age = 21;
|
$object->age = 21;
|
||||||
|
|
||||||
expect($object)->toHaveProperties(['name', 'age']);
|
expect($object)->toHaveProperties(['name', 'age']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('failures', function () {
|
test('failures', function () {
|
||||||
$object = new stdClass();
|
$object = new stdClass();
|
||||||
$object->name = 'Jhon';
|
$object->name = 'Jhon';
|
||||||
|
|
||||||
expect($object)->toHaveProperties(['name', 'age']);
|
expect($object)->toHaveProperties(['name', 'age']);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
test('not failures', function () {
|
test('not failures', function () {
|
||||||
$object = new stdClass();
|
$object = new stdClass();
|
||||||
$object->name = 'Jhon';
|
$object->name = 'Jhon';
|
||||||
$object->age = 21;
|
$object->age = 21;
|
||||||
|
|
||||||
expect($object)->not->toHaveProperties(['name', 'age']);
|
expect($object)->not->toHaveProperties(['name', 'age']);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|||||||
@ -58,3 +58,19 @@ test('closure missing parameter', function () {
|
|||||||
test('closure missing type-hint', function () {
|
test('closure missing type-hint', function () {
|
||||||
expect(function () {})->toThrow(function ($e) {});
|
expect(function () {})->toThrow(function ($e) {});
|
||||||
})->throws(InvalidArgumentException::class, 'The given closure\'s parameter must be type-hinted as the class string.');
|
})->throws(InvalidArgumentException::class, 'The given closure\'s parameter must be type-hinted as the class string.');
|
||||||
|
|
||||||
|
it('can handle a non-defined exception', function () {
|
||||||
|
expect(function () {
|
||||||
|
throw new NonExistingException();
|
||||||
|
})->toThrow(NonExistingException::class);
|
||||||
|
})->throws(Error::class, 'Class "NonExistingException" not found');
|
||||||
|
|
||||||
|
it('can handle a class not found Error', function () {
|
||||||
|
expect(function () {
|
||||||
|
throw new NonExistingException();
|
||||||
|
})->toThrow('Class "NonExistingException" not found');
|
||||||
|
|
||||||
|
expect(function () {
|
||||||
|
throw new NonExistingException();
|
||||||
|
})->toThrow(Error::class, 'Class "NonExistingException" not found');
|
||||||
|
});
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
use PHPUnit\Framework\ExpectationFailedException;
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
$this->unlessObject = new stdClass();
|
$this->unlessObject = new stdClass();
|
||||||
$this->unlessObject->trueValue = true;
|
$this->unlessObject->trueValue = true;
|
||||||
$this->unlessObject->foo = 'foo';
|
$this->unlessObject->foo = 'foo';
|
||||||
});
|
});
|
||||||
|
|
||||||
it('pass', function () {
|
it('pass', function () {
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
use PHPUnit\Framework\ExpectationFailedException;
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
$this->whenObject = new stdClass();
|
$this->whenObject = new stdClass();
|
||||||
$this->whenObject->trueValue = true;
|
$this->whenObject->trueValue = true;
|
||||||
$this->whenObject->foo = 'foo';
|
$this->whenObject->foo = 'foo';
|
||||||
});
|
});
|
||||||
|
|
||||||
it('pass', function () {
|
it('pass', function () {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ it('gets file name from closure', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('gets property values', function () {
|
it('gets property values', function () {
|
||||||
$class = new class() {
|
$class = new class() {
|
||||||
private $foo = 'bar';
|
private $foo = 'bar';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use Pest\TestSuite;
|
|||||||
|
|
||||||
it('does not allow to add the same test description twice', function () {
|
it('does not allow to add the same test description twice', function () {
|
||||||
$testSuite = new TestSuite(getcwd(), 'tests');
|
$testSuite = new TestSuite(getcwd(), 'tests');
|
||||||
$method = new TestCaseMethodFactory('foo', 'bar', null);
|
$method = new TestCaseMethodFactory('foo', 'bar', null);
|
||||||
|
|
||||||
$testSuite->tests->set($method);
|
$testSuite->tests->set($method);
|
||||||
$testSuite->tests->set($method);
|
$testSuite->tests->set($method);
|
||||||
@ -43,7 +43,7 @@ it('can return an array of all test suite filenames', function () {
|
|||||||
it('can filter the test suite filenames to those with the only method', function () {
|
it('can filter the test suite filenames to those with the only method', function () {
|
||||||
$testSuite = new TestSuite(getcwd(), 'tests');
|
$testSuite = new TestSuite(getcwd(), 'tests');
|
||||||
|
|
||||||
$testWithOnly = new TestCaseMethodFactory('a', 'b', null);
|
$testWithOnly = new TestCaseMethodFactory('a', 'b', null);
|
||||||
$testWithOnly->only = true;
|
$testWithOnly->only = true;
|
||||||
$testSuite->tests->set($testWithOnly);
|
$testSuite->tests->set($testWithOnly);
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ it('does not filter the test suite filenames to those with the only method when
|
|||||||
|
|
||||||
$test = function () {};
|
$test = function () {};
|
||||||
|
|
||||||
$testWithOnly = new TestCaseMethodFactory('a', 'b', null);
|
$testWithOnly = new TestCaseMethodFactory('a', 'b', null);
|
||||||
$testWithOnly->only = true;
|
$testWithOnly->only = true;
|
||||||
$testSuite->tests->set($testWithOnly);
|
$testSuite->tests->set($testWithOnly);
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ test('visual snapshot of help command output', function () {
|
|||||||
|
|
||||||
if (getenv('REBUILD_SNAPSHOTS')) {
|
if (getenv('REBUILD_SNAPSHOTS')) {
|
||||||
$outputBuffer = new BufferedOutput();
|
$outputBuffer = new BufferedOutput();
|
||||||
$plugin = new Help($outputBuffer);
|
$plugin = new Help($outputBuffer);
|
||||||
|
|
||||||
$plugin();
|
$plugin();
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
test('visual snapshot of test suite on success', function () {
|
test('visual snapshot of test suite on success', function () {
|
||||||
$testsPath = dirname(__DIR__);
|
$testsPath = dirname(__DIR__);
|
||||||
$snapshot = implode(DIRECTORY_SEPARATOR, [
|
$snapshot = implode(DIRECTORY_SEPARATOR, [
|
||||||
$testsPath,
|
$testsPath,
|
||||||
'.snapshots',
|
'.snapshots',
|
||||||
'success.txt',
|
'success.txt',
|
||||||
|
|||||||
Reference in New Issue
Block a user