mirror of
https://github.com/pestphp/pest.git
synced 2026-03-09 17:27:22 +01:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 049da041b2 | |||
| 4d7aa2b98f | |||
| 3f854713e6 | |||
| 011bd3ba82 | |||
| 4de70da0a0 | |||
| 6820d8b7aa | |||
| 6886558ed1 | |||
| b795a92840 | |||
| 2e622f6fd4 |
22
CHANGELOG.md
22
CHANGELOG.md
@ -2,6 +2,28 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
## [v2.10.1 (2023-07-31)](https://github.com/pestphp/pest/compare/v2.10.0...v2.10.1)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- `not->toHaveSuffix` and `toHavePrefix` expectations ([#888](https://github.com/pestphp/pest/pull/888))
|
||||||
|
|
||||||
|
## [v2.10.0 (2023-07-31)](https://github.com/pestphp/pest/compare/v2.9.5...v2.10.0)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `repeat` feature ([f3f35a2](https://github.com/pestphp/pest/commit/f3f35a2ed119f63eefd323a8c66d3387e908df3f))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- `-v` option ([86a6b32](https://github.com/pestphp/pest/commit/86a6b3271518742dc39761228687a5107551d279))
|
||||||
|
|
||||||
|
## [v2.9.5 (2023-07-22)](https://github.com/pestphp/pest/compare/v2.9.4...v2.9.5)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Assertions count on arch expectations ([632ffc2](https://github.com/pestphp/pest/commit/632ffc2f8e1fe45f739b12b818426ae14700079e))
|
||||||
|
|
||||||
## [v2.9.4 (2023-07-22)](https://github.com/pestphp/pest/compare/v2.9.3...v2.9.4)
|
## [v2.9.4 (2023-07-22)](https://github.com/pestphp/pest/compare/v2.9.3...v2.9.4)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@ -46,6 +46,7 @@ $bootPest = (static function (): void {
|
|||||||
];
|
];
|
||||||
|
|
||||||
foreach ($composerAutoloadFiles as $file) {
|
foreach ($composerAutoloadFiles as $file) {
|
||||||
|
|
||||||
if (file_exists($file)) {
|
if (file_exists($file)) {
|
||||||
require_once $file;
|
require_once $file;
|
||||||
define('PHPUNIT_COMPOSER_INSTALL', $file);
|
define('PHPUNIT_COMPOSER_INSTALL', $file);
|
||||||
|
|||||||
@ -42,6 +42,7 @@
|
|||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Tests\\Fixtures\\Covers\\": "tests/Fixtures/Covers",
|
"Tests\\Fixtures\\Covers\\": "tests/Fixtures/Covers",
|
||||||
"Tests\\Fixtures\\Inheritance\\": "tests/Fixtures/Inheritance",
|
"Tests\\Fixtures\\Inheritance\\": "tests/Fixtures/Inheritance",
|
||||||
|
"Tests\\Fixtures\\Arch\\": "tests/Fixtures/Arch",
|
||||||
"Tests\\": "tests/PHPUnit/"
|
"Tests\\": "tests/PHPUnit/"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@ -430,7 +430,7 @@ final class Expectation
|
|||||||
{
|
{
|
||||||
return Targeted::make(
|
return Targeted::make(
|
||||||
$this,
|
$this,
|
||||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && $object->reflectionClass->isReadOnly(),
|
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && $object->reflectionClass->isReadOnly() && assert(true), // @phpstan-ignore-line
|
||||||
'to be readonly',
|
'to be readonly',
|
||||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||||
);
|
);
|
||||||
@ -595,12 +595,12 @@ final class Expectation
|
|||||||
/**
|
/**
|
||||||
* Asserts that the given expectation target to have the given suffix.
|
* Asserts that the given expectation target to have the given suffix.
|
||||||
*/
|
*/
|
||||||
public function toHavePrefix(string $suffix): ArchExpectation
|
public function toHavePrefix(string $prefix): ArchExpectation
|
||||||
{
|
{
|
||||||
return Targeted::make(
|
return Targeted::make(
|
||||||
$this,
|
$this,
|
||||||
fn (ObjectDescription $object): bool => str_starts_with($object->reflectionClass->getName(), $suffix),
|
fn (ObjectDescription $object): bool => str_starts_with($object->reflectionClass->getShortName(), $prefix),
|
||||||
"to have prefix '{$suffix}'",
|
"to have prefix '{$prefix}'",
|
||||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -693,4 +693,17 @@ final class Expectation
|
|||||||
{
|
{
|
||||||
return ToBeUsedInNothing::make($this);
|
return ToBeUsedInNothing::make($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the given expectation dependency is an invokable class.
|
||||||
|
*/
|
||||||
|
public function toBeInvokable(): ArchExpectation
|
||||||
|
{
|
||||||
|
return Targeted::make(
|
||||||
|
$this,
|
||||||
|
fn (ObjectDescription $object): bool => $object->reflectionClass->hasMethod('__invoke'),
|
||||||
|
'to be invokable',
|
||||||
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class'))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,7 +109,7 @@ final class OppositeExpectation
|
|||||||
{
|
{
|
||||||
return Targeted::make(
|
return Targeted::make(
|
||||||
$this->original,
|
$this->original,
|
||||||
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && ! $object->reflectionClass->isReadOnly(),
|
fn (ObjectDescription $object): bool => ! enum_exists($object->name) && ! $object->reflectionClass->isReadOnly() && assert(true), // @phpstan-ignore-line
|
||||||
'not to be readonly',
|
'not to be readonly',
|
||||||
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||||
);
|
);
|
||||||
@ -291,17 +291,27 @@ final class OppositeExpectation
|
|||||||
/**
|
/**
|
||||||
* Not supported.
|
* Not supported.
|
||||||
*/
|
*/
|
||||||
public function toHavePrefix(string $suffix): never
|
public function toHavePrefix(string $prefix): ArchExpectation
|
||||||
{
|
{
|
||||||
throw InvalidExpectation::fromMethods(['not', 'toHavePrefix']);
|
return Targeted::make(
|
||||||
|
$this->original,
|
||||||
|
fn (ObjectDescription $object): bool => ! str_starts_with($object->reflectionClass->getShortName(), $prefix),
|
||||||
|
"not to have prefix '{$prefix}'",
|
||||||
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not supported.
|
* Not supported.
|
||||||
*/
|
*/
|
||||||
public function toHaveSuffix(string $suffix): never
|
public function toHaveSuffix(string $suffix): ArchExpectation
|
||||||
{
|
{
|
||||||
throw InvalidExpectation::fromMethods(['not', 'toHaveSuffix']);
|
return Targeted::make(
|
||||||
|
$this->original,
|
||||||
|
fn (ObjectDescription $object): bool => ! str_ends_with($object->reflectionClass->getName(), $suffix),
|
||||||
|
"not to have suffix '{$suffix}'",
|
||||||
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -355,6 +365,19 @@ final class OppositeExpectation
|
|||||||
throw InvalidExpectation::fromMethods(['not', 'toBeUsedInNothing']);
|
throw InvalidExpectation::fromMethods(['not', 'toBeUsedInNothing']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the given expectation dependency is not an invokable class.
|
||||||
|
*/
|
||||||
|
public function toBeInvokable(): ArchExpectation
|
||||||
|
{
|
||||||
|
return Targeted::make(
|
||||||
|
$this->original,
|
||||||
|
fn (ObjectDescription $object): bool => ! $object->reflectionClass->hasMethod('__invoke'),
|
||||||
|
'to not be invokable',
|
||||||
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle dynamic method calls into the original expectation.
|
* Handle dynamic method calls into the original expectation.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Pest;
|
|||||||
|
|
||||||
function version(): string
|
function version(): string
|
||||||
{
|
{
|
||||||
return '2.10.0';
|
return '2.11.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDirectory(string $file = ''): string
|
function testDirectory(string $file = ''): string
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
Pest Testing Framework 2.10.0.
|
Pest Testing Framework 2.11.0.
|
||||||
|
|
||||||
USAGE: pest <file> [options]
|
USAGE: pest <file> [options]
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
Pest Testing Framework 2.10.0.
|
Pest Testing Framework 2.11.0.
|
||||||
|
|
||||||
|
|||||||
@ -411,6 +411,14 @@
|
|||||||
✓ failures with custom message
|
✓ failures with custom message
|
||||||
✓ not failures
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeInvokable
|
||||||
|
✓ class is invokable
|
||||||
|
✓ opposite class is invokable
|
||||||
|
✓ class is invokable via a parent class
|
||||||
|
✓ class is invokable via a trait
|
||||||
|
✓ failure when the class is not invokable
|
||||||
|
✓ class is not invokable
|
||||||
|
|
||||||
PASS Tests\Features\Expect\toBeIterable
|
PASS Tests\Features\Expect\toBeIterable
|
||||||
✓ pass
|
✓ pass
|
||||||
✓ failures
|
✓ failures
|
||||||
@ -629,6 +637,12 @@
|
|||||||
✓ failures with custom message
|
✓ failures with custom message
|
||||||
✓ not failures
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toHavePrefix
|
||||||
|
✓ missing prefix
|
||||||
|
✓ has prefix
|
||||||
|
✓ opposite missing prefix
|
||||||
|
✓ opposite has prefix
|
||||||
|
|
||||||
PASS Tests\Features\Expect\toHaveProperties
|
PASS Tests\Features\Expect\toHaveProperties
|
||||||
✓ pass
|
✓ pass
|
||||||
✓ failures
|
✓ failures
|
||||||
@ -642,6 +656,12 @@
|
|||||||
✓ failures with message and Any matcher
|
✓ failures with message and Any matcher
|
||||||
✓ not failures
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toHaveSuffix
|
||||||
|
✓ missing suffix
|
||||||
|
✓ has suffix
|
||||||
|
✓ opposite missing suffix
|
||||||
|
✓ opposite has suffix
|
||||||
|
|
||||||
PASS Tests\Features\Expect\toMatch
|
PASS Tests\Features\Expect\toMatch
|
||||||
✓ pass
|
✓ pass
|
||||||
✓ failures
|
✓ failures
|
||||||
@ -1174,4 +1194,4 @@
|
|||||||
WARN Tests\Visual\Version
|
WARN Tests\Visual\Version
|
||||||
- visual snapshot of help command output
|
- visual snapshot of help command output
|
||||||
|
|
||||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 830 passed (1927 assertions)
|
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 844 passed (1947 assertions)
|
||||||
29
tests/Features/Expect/toBeInvokable.php
Normal file
29
tests/Features/Expect/toBeInvokable.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Arch\Exceptions\ArchExpectationFailedException;
|
||||||
|
|
||||||
|
test('class is invokable')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToBeInvokable\\IsInvokable\\InvokableClass')
|
||||||
|
->toBeInvokable();
|
||||||
|
|
||||||
|
test('opposite class is invokable')
|
||||||
|
->throws(ArchExpectationFailedException::class)
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToBeInvokable\\IsInvokable\\InvokableClass')
|
||||||
|
->not->toBeInvokable();
|
||||||
|
|
||||||
|
test('class is invokable via a parent class')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToBeInvokable\\IsInvokable\\InvokableClassViaParent')
|
||||||
|
->toBeInvokable();
|
||||||
|
|
||||||
|
test('class is invokable via a trait')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToBeInvokable\\IsInvokable\\InvokableClassViaTrait')
|
||||||
|
->toBeInvokable();
|
||||||
|
|
||||||
|
test('failure when the class is not invokable')
|
||||||
|
->throws(ArchExpectationFailedException::class)
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToBeInvokable\\IsNotInvokable\\IsNotInvokableClass')
|
||||||
|
->toBeInvokable();
|
||||||
|
|
||||||
|
test('class is not invokable')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToBeInvokable\\IsNotInvokable\\IsNotInvokableClass')
|
||||||
|
->not->toBeInvokable();
|
||||||
21
tests/Features/Expect/toHavePrefix.php
Normal file
21
tests/Features/Expect/toHavePrefix.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Arch\Exceptions\ArchExpectationFailedException;
|
||||||
|
|
||||||
|
test('missing prefix')
|
||||||
|
->throws(ArchExpectationFailedException::class)
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToHavePrefix\\HasNoPrefix')
|
||||||
|
->toHavePrefix('Prefix');
|
||||||
|
|
||||||
|
test('has prefix')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToHavePrefix\\HasPrefix')
|
||||||
|
->toHavePrefix('Prefix');
|
||||||
|
|
||||||
|
test('opposite missing prefix')
|
||||||
|
->throws(ArchExpectationFailedException::class)
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToHavePrefix\\HasPrefix')
|
||||||
|
->not->toHavePrefix('Prefix');
|
||||||
|
|
||||||
|
test('opposite has prefix')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToHavePrefix\\HasNoPrefix')
|
||||||
|
->not->toHavePrefix('Prefix');
|
||||||
21
tests/Features/Expect/toHaveSuffix.php
Normal file
21
tests/Features/Expect/toHaveSuffix.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Arch\Exceptions\ArchExpectationFailedException;
|
||||||
|
|
||||||
|
test('missing suffix')
|
||||||
|
->throws(ArchExpectationFailedException::class)
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToHaveSuffix\\HasNoSuffix')
|
||||||
|
->toHaveSuffix('Suffix');
|
||||||
|
|
||||||
|
test('has suffix')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToHaveSuffix\\HasSuffix')
|
||||||
|
->toHaveSuffix('Suffix');
|
||||||
|
|
||||||
|
test('opposite missing suffix')
|
||||||
|
->throws(ArchExpectationFailedException::class)
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToHaveSuffix\\HasSuffix')
|
||||||
|
->not->toHaveSuffix('Suffix');
|
||||||
|
|
||||||
|
test('opposite has suffix')
|
||||||
|
->expect('Tests\\Fixtures\\Arch\\ToHaveSuffix\\HasNoSuffix')
|
||||||
|
->not->toHaveSuffix('Suffix');
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToBeInvokable\IsInvokable;
|
||||||
|
|
||||||
|
class InvokableClass
|
||||||
|
{
|
||||||
|
public function __invoke(): void
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToBeInvokable\IsInvokable;
|
||||||
|
|
||||||
|
class InvokableClassViaParent extends ParentInvokableClass
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToBeInvokable\IsInvokable;
|
||||||
|
|
||||||
|
class InvokableClassViaTrait
|
||||||
|
{
|
||||||
|
use InvokableTrait;
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToBeInvokable\IsInvokable;
|
||||||
|
|
||||||
|
trait InvokableTrait
|
||||||
|
{
|
||||||
|
public function __invoke(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToBeInvokable\IsInvokable;
|
||||||
|
|
||||||
|
class ParentInvokableClass
|
||||||
|
{
|
||||||
|
public function __invoke(): void
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToBeInvokable\IsNotInvokable;
|
||||||
|
|
||||||
|
class IsNotInvokableClass
|
||||||
|
{
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToHavePrefix\HasNoPrefix;
|
||||||
|
|
||||||
|
class ClassWithout
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToHavePrefix\HasPrefix;
|
||||||
|
|
||||||
|
class PrefixClassWith
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToHaveSuffix\HasNoSuffix;
|
||||||
|
|
||||||
|
class ClassWithout
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToHaveSuffix\HasSuffix;
|
||||||
|
|
||||||
|
class ClassWithSuffix
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -16,7 +16,7 @@ $run = function () {
|
|||||||
|
|
||||||
test('parallel', function () use ($run) {
|
test('parallel', function () use ($run) {
|
||||||
expect($run('--exclude-group=integration'))
|
expect($run('--exclude-group=integration'))
|
||||||
->toContain('Tests: 1 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 15 skipped, 819 passed (1912 assertions)')
|
->toContain('Tests: 1 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 15 skipped, 833 passed (1932 assertions)')
|
||||||
->toContain('Parallel: 3 processes');
|
->toContain('Parallel: 3 processes');
|
||||||
})->skipOnWindows();
|
})->skipOnWindows();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user