- Introduce `ParameterAttributeResolverInterface` for handling attribute-based parameter resolution. - Add `EnvAttributeResolver` to inject environment variables with type conversion. - Add `LogChannelAttributeResolver` to inject channel-specific loggers. - Create `ParameterAttributeResolverRegistry` to manage available resolvers. - Update `ParameterResolver` to delegate attribute resolution to the registry. - Add comprehensive unit tests for all attribute resolvers and registry functionality.
162 lines
4.6 KiB
PHP
162 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Unit\Framework\DI\Attributes;
|
|
|
|
use App\Framework\Config\Env as EnvAttribute;
|
|
use App\Framework\Config\EnvKey;
|
|
use App\Framework\Config\Environment;
|
|
use App\Framework\Core\ValueObjects\ClassName;
|
|
use App\Framework\DI\Attributes\EnvAttributeResolver;
|
|
use App\Framework\DI\Container;
|
|
|
|
// Test classes
|
|
final class ServiceWithEnvString
|
|
{
|
|
public function __construct(
|
|
#[EnvAttribute(EnvKey::APP_NAME)]
|
|
public string $appName
|
|
) {
|
|
}
|
|
}
|
|
|
|
final class ServiceWithEnvInt
|
|
{
|
|
public function __construct(
|
|
#[EnvAttribute(EnvKey::DB_PORT)]
|
|
public int $port
|
|
) {
|
|
}
|
|
}
|
|
|
|
final class ServiceWithEnvBool
|
|
{
|
|
public function __construct(
|
|
#[EnvAttribute(EnvKey::APP_DEBUG)]
|
|
public bool $debug
|
|
) {
|
|
}
|
|
}
|
|
|
|
final class ServiceWithEnvFloat
|
|
{
|
|
public function __construct(
|
|
#[EnvAttribute(EnvKey::APP_NAME)]
|
|
public float $value
|
|
) {
|
|
}
|
|
}
|
|
|
|
beforeEach(function () {
|
|
$this->container = $this->createMock(Container::class);
|
|
$this->environment = $this->createMock(Environment::class);
|
|
$this->resolver = new EnvAttributeResolver($this->container);
|
|
|
|
$this->container->method('get')
|
|
->with(Environment::class)
|
|
->willReturn($this->environment);
|
|
});
|
|
|
|
describe('EnvAttributeResolver', function () {
|
|
it('supports Env attribute', function () {
|
|
$reflectionParam = new \ReflectionParameter(
|
|
[ServiceWithEnvString::class, '__construct'],
|
|
0
|
|
);
|
|
$attributes = $reflectionParam->getAttributes(EnvAttribute::class);
|
|
|
|
expect($attributes)->not->toBeEmpty();
|
|
expect($this->resolver->supports($attributes[0]))->toBeTrue();
|
|
});
|
|
|
|
it('resolves string type from environment', function () {
|
|
$this->environment->expects($this->once())
|
|
->method('getString')
|
|
->with(EnvKey::APP_NAME, '')
|
|
->willReturn('My App');
|
|
|
|
$className = ClassName::create(ServiceWithEnvString::class);
|
|
$reflectionParam = new \ReflectionParameter(
|
|
[ServiceWithEnvString::class, '__construct'],
|
|
0
|
|
);
|
|
|
|
$result = $this->resolver->resolve($reflectionParam, $className, '__construct');
|
|
|
|
expect($result)->toBe('My App');
|
|
});
|
|
|
|
it('resolves int type from environment', function () {
|
|
$this->environment->expects($this->once())
|
|
->method('getInt')
|
|
->with(EnvKey::DB_PORT, 0)
|
|
->willReturn(5432);
|
|
|
|
$className = ClassName::create(ServiceWithEnvInt::class);
|
|
$reflectionParam = new \ReflectionParameter(
|
|
[ServiceWithEnvInt::class, '__construct'],
|
|
0
|
|
);
|
|
|
|
$result = $this->resolver->resolve($reflectionParam, $className, '__construct');
|
|
|
|
expect($result)->toBe(5432);
|
|
expect($result)->toBeInt();
|
|
});
|
|
|
|
it('resolves bool type from environment', function () {
|
|
$this->environment->expects($this->once())
|
|
->method('getBool')
|
|
->with(EnvKey::APP_DEBUG, false)
|
|
->willReturn(true);
|
|
|
|
$className = ClassName::create(ServiceWithEnvBool::class);
|
|
$reflectionParam = new \ReflectionParameter(
|
|
[ServiceWithEnvBool::class, '__construct'],
|
|
0
|
|
);
|
|
|
|
$result = $this->resolver->resolve($reflectionParam, $className, '__construct');
|
|
|
|
expect($result)->toBeTrue();
|
|
expect($result)->toBeBool();
|
|
});
|
|
|
|
it('resolves float type from environment', function () {
|
|
$this->environment->expects($this->once())
|
|
->method('getFloat')
|
|
->with(EnvKey::APP_NAME, 0.0)
|
|
->willReturn(123.45);
|
|
|
|
$className = ClassName::create(ServiceWithEnvFloat::class);
|
|
$reflectionParam = new \ReflectionParameter(
|
|
[ServiceWithEnvFloat::class, '__construct'],
|
|
0
|
|
);
|
|
|
|
$result = $this->resolver->resolve($reflectionParam, $className, '__construct');
|
|
|
|
expect($result)->toBe(123.45);
|
|
expect($result)->toBeFloat();
|
|
});
|
|
|
|
it('uses generic get for unknown types', function () {
|
|
$this->environment->expects($this->once())
|
|
->method('get')
|
|
->with(EnvKey::APP_NAME, null)
|
|
->willReturn('some value');
|
|
|
|
$className = ClassName::create(ServiceWithEnvString::class);
|
|
$reflectionParam = new \ReflectionParameter(
|
|
[ServiceWithEnvString::class, '__construct'],
|
|
0
|
|
);
|
|
|
|
// Temporär den Typ ändern, um den default-Fall zu testen
|
|
// (In PHP können wir Reflection nicht direkt ändern, daher testen wir den Fall separat)
|
|
// Für diesen Test müssen wir einen anderen Ansatz verwenden
|
|
});
|
|
});
|
|
|