Skip to content

Commit

Permalink
Update to use PHPUnit 10 syntax (#1163)
Browse files Browse the repository at this point in the history
  • Loading branch information
spiralbot committed Nov 8, 2024
1 parent feee88a commit c3d75eb
Show file tree
Hide file tree
Showing 9 changed files with 23 additions and 136 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"require": {
"php": ">=8.1",
"psr/container": "^1.1|^2.0",
"spiral/security": "^3.14.6"
"spiral/security": "^3.15"
},
"require-dev": {
"mockery/mockery": "^1.5",
Expand Down
17 changes: 4 additions & 13 deletions src/Config/Proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,18 @@

namespace Spiral\Core\Config;

use Psr\Container\ContainerInterface;

class Proxy extends Binding
{
/**
* @template T
* @param class-string<T> $interface
* @param null|\Closure(ContainerInterface, \Stringable|string|null): T $fallbackFactory Factory that will be used
* to create an instance if the value is resolved from a proxy.
* @param class-string $interface
*/
public function __construct(
protected readonly string $interface,
public readonly bool $singleton = false,
public readonly ?\Closure $fallbackFactory = null,
) {
\interface_exists($interface) or throw new \InvalidArgumentException(
"Interface `{$interface}` does not exist.",
);
$this->singleton and $this->fallbackFactory !== null and throw new \InvalidArgumentException(
'Singleton proxies must not have a fallback factory.',
);
if (!\interface_exists($interface)) {
throw new \InvalidArgumentException(\sprintf('Interface `%s` does not exist.', $interface));
}
}

public function __toString(): string
Expand Down
10 changes: 0 additions & 10 deletions src/Exception/Container/RecursiveProxyException.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,4 @@
*/
class RecursiveProxyException extends ContainerException
{
public function __construct(
public readonly string $alias,
public readonly ?string $bindingScope = null,
public readonly ?array $callingScope = null,
) {
$message = "Recursive proxy detected for `$alias`.";
$bindingScope === null or $message .= "\nBinding scope: `$bindingScope`.";
$callingScope === null or $message .= "\nCalling scope: `" . \implode('.', $callingScope) . '`.';
parent::__construct($message);
}
}
3 changes: 1 addition & 2 deletions src/Exception/Shared/InvalidContainerScopeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@ public function __construct(
protected readonly string $id,
Container|string|null $scopeOrContainer = null,
protected readonly ?string $requiredScope = null,
\Throwable|null $previous = null,
) {
$this->scope = \is_string($scopeOrContainer)
? $scopeOrContainer
: Introspector::scopeName($scopeOrContainer);

$req = $this->requiredScope !== null ? ", `$this->requiredScope` is required" : '';

parent::__construct("Unable to resolve `$id` in the `$this->scope` scope{$req}.", previous: $previous);
parent::__construct("Unable to resolve `$id` in the `$this->scope` scope{$req}.");
}
}
12 changes: 0 additions & 12 deletions src/Internal/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@
use Spiral\Core\Exception\Container\InjectionException;
use Spiral\Core\Exception\Container\NotCallableException;
use Spiral\Core\Exception\Container\NotFoundException;
use Spiral\Core\Exception\Container\RecursiveProxyException;
use Spiral\Core\Exception\Resolver\ValidationException;
use Spiral\Core\Exception\Resolver\WrongTypeException;
use Spiral\Core\Exception\Scope\BadScopeException;
use Spiral\Core\FactoryInterface;
use Spiral\Core\Internal\Common\DestructorTrait;
use Spiral\Core\Internal\Common\Registry;
use Spiral\Core\Internal\Factory\Ctx;
use Spiral\Core\Internal\Proxy\RetryContext;
use Spiral\Core\InvokerInterface;
use Spiral\Core\Options;
use Spiral\Core\ResolverInterface;
Expand Down Expand Up @@ -200,15 +198,6 @@ private function resolveAlias(

private function resolveProxy(Config\Proxy $binding, string $alias, Stringable|string|null $context): mixed
{
if ($context instanceof RetryContext) {
return $binding->fallbackFactory === null
? throw new RecursiveProxyException(
$alias,
$this->scope->getScopeName(),
)
: ($binding->fallbackFactory)($this->container, $context->context);
}

$result = Proxy::create(new \ReflectionClass($binding->getInterface()), $context, new Attribute\Proxy());

if ($binding->singleton) {
Expand Down Expand Up @@ -327,7 +316,6 @@ private function resolveWithoutBinding(
} catch (ContainerExceptionInterface $e) {
$className = match (true) {
$e instanceof NotFoundException => NotFoundException::class,
$e instanceof RecursiveProxyException => throw $e,
default => ContainerException::class,
};
throw new $className($this->tracer->combineTraceMessage(\sprintf(
Expand Down
36 changes: 13 additions & 23 deletions src/Internal/Proxy/Resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,27 @@ public static function resolve(
throw new ContainerException(
$scope === null
? "Unable to resolve `{$alias}` in a Proxy."
: \sprintf('Unable to resolve `%s` in a Proxy in `%s` scope.', $alias, \implode('.', $scope)),
: "Unable to resolve `{$alias}` in a Proxy in `{$scope}` scope.",
previous: $e,
);
}

if (!Proxy::isProxy($result)) {
return $result;
}

/**
* If we got a Proxy again, that we should retry with the new context
* to try to get the instance from the Proxy Fallback Factory.
* If there is no the Proxy Fallback Factory, {@see RecursiveProxyException} will be thrown.
*/
try {
/** @psalm-suppress TooManyArguments */
$result = $c->get($alias, new RetryContext($context));
} catch (RecursiveProxyException $e) {
throw new RecursiveProxyException($e->alias, $e->bindingScope, self::getScope($c));
if (Proxy::isProxy($result)) {
$scope = self::getScope($c);
throw new RecursiveProxyException(
$scope === null
? "Recursive proxy detected for `{$alias}`."
: "Recursive proxy detected for `{$alias}` in `{$scope}` scope.",
);
}

// If Container returned a Proxy after the retry, then we have a recursion.
return Proxy::isProxy($result)
? throw new RecursiveProxyException($alias, null, self::getScope($c))
: $result;
return $result;
}

/**
* @return list<non-empty-string|null>|null
* @return non-empty-string|null
*/
private static function getScope(ContainerInterface $c): ?array
private static function getScope(ContainerInterface $c): ?string
{
if (!$c instanceof Container) {
if (!Proxy::isProxy($c)) {
Expand All @@ -74,9 +64,9 @@ private static function getScope(ContainerInterface $c): ?array
$c = null;
}

return \array_reverse(\array_map(
return \implode('.', \array_reverse(\array_map(
static fn (?string $name): string => $name ?? 'null',
Introspector::scopeNames($c),
));
)));
}
}
26 changes: 0 additions & 26 deletions src/Internal/Proxy/RetryContext.php

This file was deleted.

4 changes: 1 addition & 3 deletions tests/InjectableConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Spiral\Tests\Core\Fixtures\IntKeysConfig;
use Spiral\Tests\Core\Fixtures\TestConfig;

#[\PHPUnit\Framework\Attributes\CoversClass(\Spiral\Core\InjectableConfig::class)]
class InjectableConfigTest extends TestCase
{
use AliasTrait;
Expand Down Expand Up @@ -101,9 +102,6 @@ public function testGetError(): void
$config['keyC'];
}

/**
* @covers \Spiral\Core\InjectableConfig::__set_state()
*/
public function testSerialize(): void
{
$config = new TestConfig([
Expand Down
49 changes: 3 additions & 46 deletions tests/Scope/ProxyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Psr\Container\ContainerInterface;
use ReflectionParameter;
use Spiral\Core\Attribute\Proxy;
use Spiral\Core\Config\Proxy as ProxyConfig;
use Spiral\Core\Container;
use Spiral\Core\Container\InjectorInterface;
use Spiral\Core\ContainerScope;
Expand Down Expand Up @@ -302,40 +301,14 @@ public function __toString(): string
/**
* Proxy gets a proxy of the same type.
*/
public function testRecursiveProxyNotSingleton(): void
public function testRecursiveProxy(): void
{
$root = new Container();
$root->bind(UserInterface::class, new ProxyConfig(UserInterface::class));
$root->bind(UserInterface::class, new \Spiral\Core\Config\Proxy(UserInterface::class));

$this->expectException(RecursiveProxyException::class);
$this->expectExceptionMessage(
<<<MSG
Recursive proxy detected for `Spiral\Tests\Core\Scope\Stub\UserInterface`.
Binding scope: `root`.
Calling scope: `root.null`.
MSG,
);

$root->runScope(
new Scope(),
fn(#[Proxy] UserInterface $user) => $user->getName(),
);
}

/**
* Proxy gets a proxy of the same type as a singleton.
*/
public function testRecursiveProxySingleton(): void
{
$root = new Container();
$root->bind(UserInterface::class, new ProxyConfig(UserInterface::class, singleton: true));

$this->expectException(RecursiveProxyException::class);
$this->expectExceptionMessage(
<<<MSG
Recursive proxy detected for `Spiral\Tests\Core\Scope\Stub\UserInterface`.
Calling scope: `root.null`.
MSG,
'Recursive proxy detected for `Spiral\Tests\Core\Scope\Stub\UserInterface` in `root.null` scope.',
);

$root->runScope(
Expand Down Expand Up @@ -363,22 +336,6 @@ static function (#[Proxy] ContainerInterface $proxy, ContainerInterface $scoped)
);
}

public function testProxyFallbackFactory()
{
$root = new Container();
$root->bind(UserInterface::class, new ProxyConfig(
interface: UserInterface::class,
fallbackFactory: static fn(): UserInterface => new User('Foo'),
));

$name = $root->runScope(
new Scope(),
fn(#[Proxy] UserInterface $user) => $user->getName(),
);

self::assertSame('Foo', $name);
}

/*
// Proxy::$attachContainer=true tests
Expand Down

0 comments on commit c3d75eb

Please sign in to comment.