refacto: toHaveMethod and toHaveMethods

This commit is contained in:
Nuno Maduro
2024-09-02 19:38:38 +01:00
parent bb8677549a
commit dde943b993
5 changed files with 76 additions and 8 deletions

View File

@ -577,17 +577,31 @@ final class Expectation
/** /**
* Asserts that the given expectation target has a specific method. * Asserts that the given expectation target has a specific method.
*
* @param array<int, string>|string $method
*/ */
public function toHaveMethod(string $method): ArchExpectation public function toHaveMethod(array|string $method): ArchExpectation
{ {
$methods = is_array($method) ? $method : [$method];
return Targeted::make( return Targeted::make(
$this, $this,
fn (ObjectDescription $object): bool => $object->reflectionClass->hasMethod($method), fn (ObjectDescription $object): bool => count(array_filter($methods, fn (string $method): bool => $object->reflectionClass->hasMethod($method))) === count($methods),
sprintf("to have method '%s'", $method), sprintf("to have method '%s'", implode("', '", $methods)),
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')), FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
); );
} }
/**
* Asserts that the given expectation target has a specific methods.
*
* @param array<int, string> $methods
*/
public function toHaveMethods(array $methods): ArchExpectation
{
return $this->toHaveMethod($methods);
}
/** /**
* Not supported. * Not supported.
*/ */

View File

@ -214,17 +214,34 @@ final class OppositeExpectation
/** /**
* Asserts that the given expectation target does not have a specific method. * Asserts that the given expectation target does not have a specific method.
*
* @param array<int, string>|string $method
*/ */
public function toHaveMethod(string $method): ArchExpectation public function toHaveMethod(array|string $method): ArchExpectation
{ {
$methods = is_array($method) ? $method : [$method];
return Targeted::make( return Targeted::make(
$this->original, $this->original,
fn (ObjectDescription $object): bool => ! $object->reflectionClass->hasMethod($method), fn (ObjectDescription $object): bool => array_filter(
'to not have method', $methods,
fn (string $method): bool => $object->reflectionClass->hasMethod($method),
) === [],
'to not have methods: '.implode(', ', $methods),
FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')), FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')),
); );
} }
/**
* Asserts that the given expectation target does not have the given methods.
*
* @param array<int, string> $methods
*/
public function toHaveMethods(array $methods): ArchExpectation
{
return $this->toHaveMethod($methods);
}
/** /**
* Asserts that the given expectation target not to have the public methods besides the given methods. * Asserts that the given expectation target not to have the public methods besides the given methods.
* *

View File

@ -819,6 +819,14 @@
✓ class has method via a parent class ✓ class has method via a parent class
✓ class has method via a trait ✓ class has method via a trait
✓ failure when the class has no method ✓ failure when the class has no method
✓ class has no method
PASS Tests\Features\Expect\toHaveMethods
✓ class has method
✓ opposite class has method
✓ class has method via a parent class
✓ class has method via a trait
✓ failure when the class has no method
✓ class has no method ✓ class has no method
PASS Tests\Features\Expect\toHaveMethodsDocumented PASS Tests\Features\Expect\toHaveMethodsDocumented
@ -1559,4 +1567,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, 28 skipped, 1079 passed (2609 assertions) Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 28 skipped, 1085 passed (2617 assertions)

View File

@ -0,0 +1,29 @@
<?php
use Pest\Arch\Exceptions\ArchExpectationFailedException;
test('class has method')
->expect('Tests\Fixtures\Arch\ToHaveMethod\HasMethod\HasMethod')
->toHaveMethods(['foo']);
test('opposite class has method')
->throws(ArchExpectationFailedException::class)
->expect('Tests\Fixtures\Arch\ToHaveMethod\HasMethod\HasMethod')
->not->toHaveMethods(['foo']);
test('class has method via a parent class')
->expect('Tests\Fixtures\Arch\ToHaveMethod\HasMethod\HasMethodViaParent')
->toHaveMethods(['foo']);
test('class has method via a trait')
->expect('Tests\Fixtures\Arch\ToHaveMethod\HasMethod\HasMethodViaTrait')
->toHaveMethods(['foo']);
test('failure when the class has no method')
->throws(ArchExpectationFailedException::class)
->expect('Tests\Fixtures\Arch\ToHaveMethod\HasNoMethod\HasNoMethodClass')
->toHaveMethods(['foo']);
test('class has no method')
->expect('Tests\Fixtures\Arch\ToHaveMethod\HasNoMethod\HasNoMethodClass')
->not->toHaveMethods(['foo']);

View File

@ -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, 1069 passed (2585 assertions)') ->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 19 skipped, 1075 passed (2593 assertions)')
->toContain('Parallel: 3 processes'); ->toContain('Parallel: 3 processes');
})->skipOnWindows(); })->skipOnWindows();