before params as associative array

This commit is contained in:
icefox 2026-01-07 12:06:14 -03:00
parent d35c3df06d
commit 6946059f07
No known key found for this signature in database
11 changed files with 154 additions and 8 deletions

View file

@ -62,6 +62,6 @@ final class AspectStackingTest extends TestCase
$tracker = (object) ['before' => false, 'after' => false];
$this->instance->multipleAspects(15, $tracker);
$this->assertEquals([15, $tracker], LoggingAspect::$logs[0]['args']);
$this->assertEquals(['value' => 15, 'tracker' => $tracker], LoggingAspect::$logs[0]['args']);
}
}

View file

@ -15,7 +15,7 @@ class BasicAspect
) {
}
public function before(mixed ...$args): void
public function before(array $args): void
{
$this->object = end($args);
$this->object->before = true;

View file

@ -18,7 +18,7 @@ class ConfigurableAspect
) {
}
public function before(mixed ...$args): void
public function before(array $args): void
{
if ($this->enabled) {
self::$executionLog[] = [

View file

@ -15,7 +15,7 @@ class LoggingAspect
) {
}
public function before(mixed ...$args): void
public function before(array $args): void
{
self::$logs[] = ['type' => 'logging_before', 'args' => $args];
}

View file

@ -0,0 +1,35 @@
<?php
namespace Tests\Aspects;
use Attribute;
use IceFox\Aspect\AspectContext;
#[Attribute(Attribute::TARGET_METHOD)]
class ParameterKeyAspect
{
public static array $capturedKeys = [];
public static array $capturedArgs = [];
public function __construct(
private readonly AspectContext $context,
) {
}
public function before(array $args): void
{
self::$capturedKeys = array_keys($args);
self::$capturedArgs = $args;
}
public function after(mixed $result): mixed
{
return $result;
}
public static function reset(): void
{
self::$capturedKeys = [];
self::$capturedArgs = [];
}
}

View file

@ -17,7 +17,7 @@ class ThrowingAspect
) {
}
public function before(mixed ...$args): void
public function before(array $args): void
{
if (self::$throwInBefore) {
throw new RuntimeException('Exception thrown in before()');

View file

@ -15,7 +15,7 @@ class TrackingAspect
) {
}
public function before(mixed ...$args): void
public function before(array $args): void
{
self::$calls[] = ['event' => 'before', 'args' => $args];
}

View file

@ -0,0 +1,26 @@
<?php
namespace Tests\Classes;
use Tests\Aspects\ParameterKeyAspect;
class ParameterKeyTestClass
{
#[ParameterKeyAspect]
public function methodWithNamedParams(string $firstName, string $lastName, int $age): string
{
return "$firstName $lastName is $age years old";
}
#[ParameterKeyAspect]
public function methodWithSingleParam(array $data): array
{
return $data;
}
#[ParameterKeyAspect]
public function methodWithMixedTypes(int $id, string $name, bool $active, ?object $metadata): string
{
return "ID: $id, Name: $name, Active: " . ($active ? 'yes' : 'no');
}
}

View file

@ -0,0 +1,69 @@
<?php
use PHPUnit\Framework\TestCase;
use Tests\Classes\ParameterKeyTestClass;
use Tests\Aspects\ParameterKeyAspect;
final class ParameterKeyTest extends TestCase
{
private ParameterKeyTestClass $instance;
protected function setUp(): void
{
$this->instance = new ParameterKeyTestClass();
ParameterKeyAspect::reset();
}
public function testBeforeReceivesAssociativeArrayWithParameterNames(): void
{
$this->instance->methodWithNamedParams('John', 'Doe', 30);
// Verify that the keys are parameter names, not numeric indices
$this->assertEquals(['firstName', 'lastName', 'age'], ParameterKeyAspect::$capturedKeys);
// Verify the values are correctly mapped to parameter names
$this->assertEquals('John', ParameterKeyAspect::$capturedArgs['firstName']);
$this->assertEquals('Doe', ParameterKeyAspect::$capturedArgs['lastName']);
$this->assertEquals(30, ParameterKeyAspect::$capturedArgs['age']);
}
public function testSingleParameterHasCorrectKey(): void
{
$testData = ['key1' => 'value1', 'key2' => 'value2'];
$this->instance->methodWithSingleParam($testData);
// Verify the parameter name is used as the key
$this->assertEquals(['data'], ParameterKeyAspect::$capturedKeys);
$this->assertEquals($testData, ParameterKeyAspect::$capturedArgs['data']);
}
public function testMixedTypesHaveCorrectKeys(): void
{
$metadata = (object) ['info' => 'test'];
$this->instance->methodWithMixedTypes(42, 'TestName', true, $metadata);
// Verify all parameter names are present as keys
$this->assertEquals(['id', 'name', 'active', 'metadata'], ParameterKeyAspect::$capturedKeys);
// Verify each parameter value is accessible by its name
$this->assertEquals(42, ParameterKeyAspect::$capturedArgs['id']);
$this->assertEquals('TestName', ParameterKeyAspect::$capturedArgs['name']);
$this->assertTrue(ParameterKeyAspect::$capturedArgs['active']);
$this->assertSame($metadata, ParameterKeyAspect::$capturedArgs['metadata']);
}
public function testParametersCanBeAccessedByName(): void
{
$this->instance->methodWithNamedParams('Jane', 'Smith', 25);
// Verify we can access parameters by their name using array key syntax
$this->assertArrayHasKey('firstName', ParameterKeyAspect::$capturedArgs);
$this->assertArrayHasKey('lastName', ParameterKeyAspect::$capturedArgs);
$this->assertArrayHasKey('age', ParameterKeyAspect::$capturedArgs);
// Verify numeric keys do NOT exist
$this->assertArrayNotHasKey(0, ParameterKeyAspect::$capturedArgs);
$this->assertArrayNotHasKey(1, ParameterKeyAspect::$capturedArgs);
$this->assertArrayNotHasKey(2, ParameterKeyAspect::$capturedArgs);
}
}

View file

@ -9,6 +9,7 @@ use Tests\Aspects\TrackingAspect;
use Tests\Aspects\ThrowingAspect;
use Tests\Aspects\ModifyingAspect;
use Tests\Aspects\ConfigurableAspect;
use Tests\Aspects\ParameterKeyAspect;
use Tests\Classes\CallsImportedClass;
use Tests\Classes\WrappedClass;
use Tests\Classes\ParameterTypesClass;
@ -16,12 +17,13 @@ use Tests\Classes\StackedAspectsClass;
use Tests\Classes\ThrowingClass;
use Tests\Classes\ModifyingClass;
use Tests\Classes\ConfigurableClass;
use Tests\Classes\ParameterKeyTestClass;
$cacheDir = sys_get_temp_dir() . '/cache/php-aop-cache';
$useCache = false;
$weaver = new AspectWeaver(
[BasicAspect::class, LoggingAspect::class, TrackingAspect::class, ThrowingAspect::class, ModifyingAspect::class, ConfigurableAspect::class],
[BasicAspect::class, LoggingAspect::class, TrackingAspect::class, ThrowingAspect::class, ModifyingAspect::class, ConfigurableAspect::class, ParameterKeyAspect::class],
$cacheDir,
$useCache,
new NullLogger(),
@ -36,6 +38,7 @@ $loader = AspectBuilder::begin()
ModifyingClass::class,
ConfigurableClass::class,
CallsImportedClass::class,
ParameterKeyTestClass::class,
])
->build($weaver)
->register();