mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 07:47:22 +01:00
feat: toHavePrivateMethodsBesides, toHaveProtectedMethodsBesides, toHavePublicMethodsBesides
This commit is contained in:
@ -31,14 +31,15 @@ final class Laravel extends AbstractPreset
|
|||||||
->not->toImplement(Throwable::class)
|
->not->toImplement(Throwable::class)
|
||||||
->ignoring('App\Exceptions');
|
->ignoring('App\Exceptions');
|
||||||
|
|
||||||
$this->expectations[] = expect('App\Http\Controllers')
|
|
||||||
->classes()
|
|
||||||
->toHaveSuffix('Controller');
|
|
||||||
|
|
||||||
$this->expectations[] = expect('App')
|
$this->expectations[] = expect('App')
|
||||||
->not->toHaveSuffix('Controller')
|
->not->toHaveSuffix('Controller')
|
||||||
->ignoring('App\Http\Controllers');
|
->ignoring('App\Http\Controllers');
|
||||||
|
|
||||||
|
$this->expectations[] = expect('App\Http\Controllers')
|
||||||
|
->classes()
|
||||||
|
->toHaveSuffix('Controller')
|
||||||
|
->not->toHavePublicMethodsBesides(['__construct', '__invoke', 'index', 'show', 'create', 'store', 'edit', 'update', 'destroy']);
|
||||||
|
|
||||||
$this->expectations[] = expect('App\Http\Middleware')
|
$this->expectations[] = expect('App\Http\Middleware')
|
||||||
->classes()
|
->classes()
|
||||||
->toHaveMethod('handle');
|
->toHaveMethod('handle');
|
||||||
|
|||||||
@ -20,6 +20,7 @@ final class Relaxed extends AbstractPreset
|
|||||||
$this->eachUserNamespace(
|
$this->eachUserNamespace(
|
||||||
fn (Expectation $namespace): ArchExpectation => $namespace->not->toUseStrictTypes(),
|
fn (Expectation $namespace): ArchExpectation => $namespace->not->toUseStrictTypes(),
|
||||||
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toBeFinal(),
|
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toBeFinal(),
|
||||||
|
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toHavePrivateMethodsBesides([]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ final class Strict extends AbstractPreset
|
|||||||
fn (Expectation $namespace): ArchExpectation => $namespace->toUseStrictTypes(),
|
fn (Expectation $namespace): ArchExpectation => $namespace->toUseStrictTypes(),
|
||||||
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->toBeFinal(),
|
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->toBeFinal(),
|
||||||
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toBeAbstract(),
|
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toBeAbstract(),
|
||||||
|
fn (Expectation $namespace): ArchExpectation => $namespace->classes()->not->toHaveProtectedMethodsBesides([])
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->expectations[] = expect([
|
$this->expectations[] = expect([
|
||||||
|
|||||||
@ -588,6 +588,30 @@ final class Expectation
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not supported.
|
||||||
|
*/
|
||||||
|
public function toHavePublicMethodsBesides(): never
|
||||||
|
{
|
||||||
|
throw InvalidExpectation::fromMethods(['toHavePublicMethodsBesides']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not supported.
|
||||||
|
*/
|
||||||
|
public function toHaveProtectedMethodsBesides(): never
|
||||||
|
{
|
||||||
|
throw InvalidExpectation::fromMethods(['toHaveProtectedMethodsBesides']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not supported.
|
||||||
|
*/
|
||||||
|
public function toHavePrivateMethodsBesides(): never
|
||||||
|
{
|
||||||
|
throw InvalidExpectation::fromMethods(['toHavePrivateMethodsBesides']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that the given expectation target is enum.
|
* Asserts that the given expectation target is enum.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -224,6 +224,93 @@ final class OppositeExpectation
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the given expectation target not to have the public methods besides the given methods.
|
||||||
|
*/
|
||||||
|
public function toHavePublicMethodsBesides(array|string $methods): ArchExpectation
|
||||||
|
{
|
||||||
|
$methods = is_array($methods) ? $methods : [$methods];
|
||||||
|
|
||||||
|
return Targeted::make(
|
||||||
|
$this->original,
|
||||||
|
function (ObjectDescription $object) use ($methods): bool {
|
||||||
|
$reflectionMethods = isset($object->reflectionClass)
|
||||||
|
? Reflection::getMethodsFromReflectionClass($object->reflectionClass, ReflectionMethod::IS_PUBLIC)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
foreach ($reflectionMethods as $reflectionMethod) {
|
||||||
|
if (! in_array($reflectionMethod->name, $methods, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
count($methods) === 0
|
||||||
|
? 'not to have public methods'
|
||||||
|
: sprintf("not to have public methods besides '%s'", implode("', '", $methods)),
|
||||||
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'public function')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the given expectation target not to have the protected methods besides the given methods.
|
||||||
|
*/
|
||||||
|
public function toHaveProtectedMethodsBesides(array|string $methods): ArchExpectation
|
||||||
|
{
|
||||||
|
$methods = is_array($methods) ? $methods : [$methods];
|
||||||
|
|
||||||
|
return Targeted::make(
|
||||||
|
$this->original,
|
||||||
|
function (ObjectDescription $object) use ($methods): bool {
|
||||||
|
$reflectionMethods = isset($object->reflectionClass)
|
||||||
|
? Reflection::getMethodsFromReflectionClass($object->reflectionClass, ReflectionMethod::IS_PROTECTED)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
foreach ($reflectionMethods as $reflectionMethod) {
|
||||||
|
if (! in_array($reflectionMethod->name, $methods, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
count($methods) === 0
|
||||||
|
? 'not to have protected methods'
|
||||||
|
: sprintf("not to have protected methods besides '%s'", implode("', '", $methods)),
|
||||||
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'protected function')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the given expectation target not to have the private methods besides the given methods.
|
||||||
|
*/
|
||||||
|
public function toHavePrivateMethodsBesides(array|string $methods): ArchExpectation
|
||||||
|
{
|
||||||
|
$methods = is_array($methods) ? $methods : [$methods];
|
||||||
|
|
||||||
|
return Targeted::make(
|
||||||
|
$this->original,
|
||||||
|
function (ObjectDescription $object) use ($methods): bool {
|
||||||
|
$reflectionMethods = isset($object->reflectionClass)
|
||||||
|
? Reflection::getMethodsFromReflectionClass($object->reflectionClass, ReflectionMethod::IS_PRIVATE)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
foreach ($reflectionMethods as $reflectionMethod) {
|
||||||
|
if (! in_array($reflectionMethod->name, $methods, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
count($methods) === 0
|
||||||
|
? 'not to have private methods'
|
||||||
|
: sprintf("not to have private methods besides '%s'", implode("', '", $methods)),
|
||||||
|
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'private function')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that the given expectation target is not enum.
|
* Asserts that the given expectation target is not enum.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -19,7 +19,7 @@ abstract class Subscriber // @pest-arch-ignore-line
|
|||||||
/**
|
/**
|
||||||
* Creates a new TeamCityLogger instance.
|
* Creates a new TeamCityLogger instance.
|
||||||
*/
|
*/
|
||||||
final protected function logger(): TeamCityLogger
|
final protected function logger(): TeamCityLogger // @pest-arch-ignore-line
|
||||||
{
|
{
|
||||||
return $this->logger;
|
return $this->logger;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ final class CleanConsoleOutput extends ConsoleOutput
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
protected function doWrite(string $message, bool $newline): void
|
protected function doWrite(string $message, bool $newline): void // @pest-arch-ignore-line
|
||||||
{
|
{
|
||||||
if ($this->isOpeningHeadline($message)) {
|
if ($this->isOpeningHeadline($message)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -258,12 +258,12 @@ final class Reflection
|
|||||||
* @param ReflectionClass<object> $reflectionClass
|
* @param ReflectionClass<object> $reflectionClass
|
||||||
* @return array<int, ReflectionMethod>
|
* @return array<int, ReflectionMethod>
|
||||||
*/
|
*/
|
||||||
public static function getMethodsFromReflectionClass(ReflectionClass $reflectionClass): array
|
public static function getMethodsFromReflectionClass(ReflectionClass $reflectionClass, int $filter = ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED | ReflectionMethod::IS_PRIVATE): array
|
||||||
{
|
{
|
||||||
$getMethods = fn (ReflectionClass $reflectionClass): array => array_filter(
|
$getMethods = fn (ReflectionClass $reflectionClass): array => array_filter(
|
||||||
array_map(
|
array_map(
|
||||||
fn (ReflectionMethod $method): \ReflectionMethod => $method,
|
fn (ReflectionMethod $method): \ReflectionMethod => $method,
|
||||||
$reflectionClass->getMethods(),
|
$reflectionClass->getMethods($filter),
|
||||||
), fn (ReflectionMethod $method): bool => $method->getDeclaringClass()->getName() === $reflectionClass->getName(),
|
), fn (ReflectionMethod $method): bool => $method->getDeclaringClass()->getName() === $reflectionClass->getName(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
PASS Tests\Arch
|
PASS Tests\Arch
|
||||||
✓ arch "base" preset
|
✓ arch "php" preset
|
||||||
✓ arch "strict" preset
|
✓ arch "strict" preset
|
||||||
✓ arch "security" preset
|
✓ arch "security" preset
|
||||||
✓ globals
|
✓ globals
|
||||||
@ -831,6 +831,10 @@
|
|||||||
✓ opposite missing prefix
|
✓ opposite missing prefix
|
||||||
✓ opposite has prefix
|
✓ opposite has prefix
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toHavePrivateMethodsBesides
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
|
||||||
PASS Tests\Features\Expect\toHaveProperties
|
PASS Tests\Features\Expect\toHaveProperties
|
||||||
✓ pass
|
✓ pass
|
||||||
✓ failures
|
✓ failures
|
||||||
@ -849,6 +853,14 @@
|
|||||||
✓ failures with message and Any matcher
|
✓ failures with message and Any matcher
|
||||||
✓ not failures
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toHaveProtectedMethodsBesides
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toHavePublicMethodsBesides
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
|
||||||
PASS Tests\Features\Expect\toHaveSameSize
|
PASS Tests\Features\Expect\toHaveSameSize
|
||||||
✓ failures with wrong type
|
✓ failures with wrong type
|
||||||
✓ pass
|
✓ pass
|
||||||
@ -1547,4 +1559,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, 17 todos, 24 skipped, 1078 passed (2632 assertions)
|
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 24 skipped, 1084 passed (2644 assertions)
|
||||||
12
tests/Features/Expect/toHavePrivateMethodsBesides.php
Normal file
12
tests/Features/Expect/toHavePrivateMethodsBesides.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Arch\Exceptions\ArchExpectationFailedException;
|
||||||
|
use Tests\Fixtures\Arch\ToHavePublicMethodsBesides\UserController;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(UserController::class)->not->toHavePrivateMethodsBesides(['privateMethod']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(UserController::class)->not->toHavePrivateMethodsBesides([]);
|
||||||
|
})->throws(ArchExpectationFailedException::class);
|
||||||
12
tests/Features/Expect/toHaveProtectedMethodsBesides.php
Normal file
12
tests/Features/Expect/toHaveProtectedMethodsBesides.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Arch\Exceptions\ArchExpectationFailedException;
|
||||||
|
use Tests\Fixtures\Arch\ToHavePublicMethodsBesides\UserController;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(UserController::class)->not->toHaveProtectedMethodsBesides(['protectedMethod']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(UserController::class)->not->toHaveProtectedMethodsBesides([]);
|
||||||
|
})->throws(ArchExpectationFailedException::class);
|
||||||
12
tests/Features/Expect/toHavePublicMethodsBesides.php
Normal file
12
tests/Features/Expect/toHavePublicMethodsBesides.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Arch\Exceptions\ArchExpectationFailedException;
|
||||||
|
use Tests\Fixtures\Arch\ToHavePublicMethodsBesides\UserController;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(UserController::class)->not->toHavePublicMethodsBesides(['publicMethod']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(UserController::class)->not->toHavePublicMethodsBesides([]);
|
||||||
|
})->throws(ArchExpectationFailedException::class);
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Fixtures\Arch\ToHavePublicMethodsBesides;
|
||||||
|
|
||||||
|
class UserController
|
||||||
|
{
|
||||||
|
public function publicMethod(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function protectedMethod(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function privateMethod(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 19 skipped, 1064 passed (2602 assertions)')
|
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 19 skipped, 1070 passed (2612 assertions)')
|
||||||
->toContain('Parallel: 3 processes');
|
->toContain('Parallel: 3 processes');
|
||||||
})->skipOnWindows();
|
})->skipOnWindows();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user