From dde943b993237b7e25de5ad905e8454ef159d3ca Mon Sep 17 00:00:00 2001 From: Nuno Maduro Date: Mon, 2 Sep 2024 19:38:38 +0100 Subject: [PATCH] refacto: `toHaveMethod` and `toHaveMethods` --- src/Expectation.php | 20 +++++++++++++--- src/Expectations/OppositeExpectation.php | 23 ++++++++++++++++--- tests/.snapshots/success.txt | 10 +++++++- tests/Features/Expect/toHaveMethods.php | 29 ++++++++++++++++++++++++ tests/Visual/Parallel.php | 2 +- 5 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 tests/Features/Expect/toHaveMethods.php diff --git a/src/Expectation.php b/src/Expectation.php index 41adc06b..d3fc3f5d 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -577,17 +577,31 @@ final class Expectation /** * Asserts that the given expectation target has a specific method. + * + * @param array|string $method */ - public function toHaveMethod(string $method): ArchExpectation + public function toHaveMethod(array|string $method): ArchExpectation { + $methods = is_array($method) ? $method : [$method]; + return Targeted::make( $this, - fn (ObjectDescription $object): bool => $object->reflectionClass->hasMethod($method), - sprintf("to have method '%s'", $method), + fn (ObjectDescription $object): bool => count(array_filter($methods, fn (string $method): bool => $object->reflectionClass->hasMethod($method))) === count($methods), + sprintf("to have method '%s'", implode("', '", $methods)), FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')), ); } + /** + * Asserts that the given expectation target has a specific methods. + * + * @param array $methods + */ + public function toHaveMethods(array $methods): ArchExpectation + { + return $this->toHaveMethod($methods); + } + /** * Not supported. */ diff --git a/src/Expectations/OppositeExpectation.php b/src/Expectations/OppositeExpectation.php index 2282c740..123b658b 100644 --- a/src/Expectations/OppositeExpectation.php +++ b/src/Expectations/OppositeExpectation.php @@ -214,17 +214,34 @@ final class OppositeExpectation /** * Asserts that the given expectation target does not have a specific method. + * + * @param array|string $method */ - public function toHaveMethod(string $method): ArchExpectation + public function toHaveMethod(array|string $method): ArchExpectation { + $methods = is_array($method) ? $method : [$method]; + return Targeted::make( $this->original, - fn (ObjectDescription $object): bool => ! $object->reflectionClass->hasMethod($method), - 'to not have method', + fn (ObjectDescription $object): bool => array_filter( + $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')), ); } + /** + * Asserts that the given expectation target does not have the given methods. + * + * @param array $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. * diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index a619ca9e..bce78c62 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -819,6 +819,14 @@ ✓ class has method via a parent class ✓ class has method via a trait ✓ 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 PASS Tests\Features\Expect\toHaveMethodsDocumented @@ -1559,4 +1567,4 @@ WARN Tests\Visual\Version - visual snapshot of help command output - Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 28 skipped, 1079 passed (2609 assertions) \ No newline at end of file + Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 28 skipped, 1085 passed (2617 assertions) \ No newline at end of file diff --git a/tests/Features/Expect/toHaveMethods.php b/tests/Features/Expect/toHaveMethods.php new file mode 100644 index 00000000..f149251c --- /dev/null +++ b/tests/Features/Expect/toHaveMethods.php @@ -0,0 +1,29 @@ +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']); diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php index 22b244db..045d72f1 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -16,7 +16,7 @@ $run = function () { test('parallel', function () use ($run) { 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'); })->skipOnWindows();