86 lines
2.7 KiB
PHP
86 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit;
|
|
|
|
use Exception;
|
|
use Libs\Neuron;
|
|
use Libs\Synapsis;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* SynapsisTest - DuckBrain test harness
|
|
*
|
|
* Cubre la inyeccion de argumentos por nombre en resolve(): la clave de
|
|
* $named gana sobre el default de un opcional y sobre la resolucion DI por
|
|
* tipo, la coincidencia es por nombre y no por posicion, y las claves
|
|
* sobrantes se ignoran en silencio (riesgo documentado en design.md).
|
|
*/
|
|
final class SynapsisTest extends TestCase
|
|
{
|
|
#[Test]
|
|
public function namedValueWinsOverOptionalDefault(): void
|
|
{
|
|
$result = Synapsis::resolve(
|
|
fn ($config = 'default') => $config,
|
|
['config' => 'forced']
|
|
);
|
|
|
|
$this->assertSame('forced', $result, 'A named argument must take precedence over an optional default');
|
|
}
|
|
|
|
#[Test]
|
|
public function namedValueWinsOverTypeBasedResolution(): void
|
|
{
|
|
$real = new Exception('the real one', 422);
|
|
|
|
$result = Synapsis::resolve(
|
|
fn (Exception $exception) => $exception,
|
|
['exception' => $real]
|
|
);
|
|
|
|
$this->assertSame($real, $result, 'The injected instance must be the named one, not a container-built empty Exception');
|
|
}
|
|
|
|
#[Test]
|
|
public function namedParametersMatchByNameNotPosition(): void
|
|
{
|
|
$real = new Exception('matched by name');
|
|
|
|
[$b, $exception] = Synapsis::resolve(
|
|
fn (Neuron $b, Exception $exception) => [$b, $exception],
|
|
['exception' => $real]
|
|
);
|
|
|
|
$this->assertInstanceOf(Neuron::class, $b, 'Parameters without a named match must keep resolving through DI');
|
|
$this->assertSame($real, $exception, 'Position of the named parameter must not matter');
|
|
}
|
|
|
|
#[Test]
|
|
public function unmatchedNamedKeysAreIgnored(): void
|
|
{
|
|
$result = Synapsis::resolve(
|
|
fn ($x = 'untouched') => $x,
|
|
['foo' => 1]
|
|
);
|
|
|
|
$this->assertSame('untouched', $result, 'A key matching no parameter must be silently ignored');
|
|
}
|
|
|
|
#[Test]
|
|
public function renamedParameterFallsBackToContainerResolution(): void
|
|
{
|
|
$real = new Exception('never arrives');
|
|
|
|
// The handler renamed its parameter to $e, so the 'exception' key
|
|
// matches nothing and $e degrades to DI: a fresh empty Exception.
|
|
$result = Synapsis::resolve(
|
|
fn (Exception $e) => $e,
|
|
['exception' => $real]
|
|
);
|
|
|
|
$this->assertNotSame($real, $result, 'A renamed handler parameter must not receive the named value');
|
|
$this->assertSame('', $result->getMessage(), 'The degradation outcome is a container-built empty Exception');
|
|
}
|
|
}
|