Fixed variadic arguments do not work in async message annotation. (#1386)

This commit is contained in:
李铭昕 2020-03-04 15:40:21 +08:00 committed by GitHub
parent 33098dc04c
commit 9e0c21adb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 172 additions and 1 deletions

View File

@ -4,6 +4,10 @@
- [#1362](https://github.com/hyperf/hyperf/pull/1362) Added `getPoolNames()` for `Hyperf\Pool\SimplePool\PoolFactory`.
## Fixed
- [#1386](https://github.com/hyperf/hyperf/pull/1386) Fixed variadic arguments do not work in async message annotation.
# v1.1.18 - 2020-02-27
## Added

View File

@ -50,7 +50,17 @@ class AsyncQueueAspect extends AbstractAspect
$class = $proceedingJoinPoint->className;
$method = $proceedingJoinPoint->methodName;
$arguments = $proceedingJoinPoint->getArguments();
$arguments = [];
$parameters = $proceedingJoinPoint->getReflectMethod()->getParameters();
foreach ($parameters as $parameter) {
$arg = $proceedingJoinPoint->arguments['keys'][$parameter->getName()];
if ($parameter->isVariadic()) {
$arguments = array_merge($arguments, $arg);
} else {
$arguments[] = $arg;
}
}
$pool = 'default';
$delay = 0;

View File

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\AsyncQueue;
use Hyperf\AsyncQueue\Annotation\AsyncQueueMessage;
use Hyperf\AsyncQueue\AnnotationJob;
use Hyperf\AsyncQueue\Aspect\AsyncQueueAspect;
use Hyperf\AsyncQueue\Driver\DriverFactory;
use Hyperf\AsyncQueue\Driver\DriverInterface;
use Hyperf\AsyncQueue\Environment;
use Hyperf\Di\Annotation\AnnotationCollector;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\Ast;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Context;
use HyperfTest\AsyncQueue\Stub\FooProxy;
use Mockery;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
/**
* @internal
* @coversNothing
*/
class AsyncQueueAspectTest extends TestCase
{
protected function tearDown()
{
Mockery::close();
Context::set(FooProxy::class, null);
}
public function testNotAsyncMessage()
{
$container = $this->getContainer();
$proxy = $container->get(FooProxy::class);
$proxy->dump($id = rand(10000, 99999), $uuid = uniqid(), $data = [
'id' => rand(0, 9999),
]);
$this->assertSame([$id, $uuid, $data], Context::get(FooProxy::class));
}
public function testAsyncMessage()
{
$container = $this->getContainer();
$proxy = $container->get(FooProxy::class);
$proxy->async($data = [
'id' => rand(0, 9999),
]);
$this->assertSame($data, Context::get(FooProxy::class));
}
public function testAsyncMessageVariadic()
{
$container = $this->getContainer();
$proxy = $container->get(FooProxy::class);
$proxy->variadic($id = rand(10000, 99999), $uuid = uniqid(), $data = [
'id' => rand(0, 9999),
]);
$this->assertSame([$id, $uuid, $data], Context::get(FooProxy::class));
}
protected function getContainer()
{
$container = Mockery::mock(ContainerInterface::class);
ApplicationContext::setContainer($container);
$aspect = new Aspect();
$aspect->collectClass(AsyncQueueAspect::class);
AnnotationCollector::collectMethod(FooProxy::class, 'async', AsyncQueueMessage::class, new AsyncQueueMessage());
AnnotationCollector::collectMethod(FooProxy::class, 'variadic', AsyncQueueMessage::class, new AsyncQueueMessage());
$ast = new Ast();
$code = $ast->proxy(FooProxy::class, $proxy = FooProxy::class . 'Proxy');
if (! is_dir($dir = BASE_PATH . '/runtime/container/proxy/')) {
mkdir($dir, 0777, true);
}
file_put_contents($file = $dir . 'FooProxy.proxy.php', $code);
require_once $file;
$container->shouldReceive('get')->with(FooProxy::class)->andReturn(new $proxy());
$container->shouldReceive('get')->with(AsyncQueueAspect::class)->andReturnUsing(function ($_) use ($container) {
return new AsyncQueueAspect($container);
});
$container->shouldReceive('get')->with(Environment::class)->andReturn(new Environment());
$container->shouldReceive('get')->with(DriverFactory::class)->andReturnUsing(function ($_) {
$factory = Mockery::mock(DriverFactory::class);
$driver = Mockery::mock(DriverInterface::class);
$driver->shouldReceive('push')->andReturnUsing(function ($job) {
$this->assertInstanceOf(AnnotationJob::class, $job);
$origin = new FooProxy();
$origin->{$job->method}(...$job->params);
return true;
});
$factory->shouldReceive('get')->andReturn($driver);
return $factory;
});
return $container;
}
}

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\AsyncQueue\Stub;
use Hyperf\AsyncQueue\Annotation\AsyncQueueMessage;
use Hyperf\Utils\Context;
class FooProxy
{
public function dump(...$params)
{
Context::set(FooProxy::class, $params);
}
/**
* @AsyncQueueMessage
*/
public function variadic(...$params)
{
Context::set(FooProxy::class, $params);
}
/**
* @AsyncQueueMessage
* @param mixed $params
*/
public function async($params)
{
Context::set(FooProxy::class, $params);
}
}