1
0
mirror of https://github.com/danog/amp.git synced 2024-12-02 17:37:50 +01:00
amp/test/WeakClosureTest.php

141 lines
4.6 KiB
PHP
Raw Normal View History

2021-09-29 16:00:33 +02:00
<?php
namespace Amp;
use Amp\PHPUnit\AsyncTestCase;
2021-10-15 00:50:40 +02:00
use Revolt\EventLoop;
2021-09-29 16:00:33 +02:00
class WeakClosureTest extends AsyncTestCase
2021-09-29 16:00:33 +02:00
{
public function provideObjectFactories(): iterable
{
2021-12-02 19:01:05 +01:00
yield 'binding' => [
2021-12-02 19:12:06 +01:00
fn (&$count, &$id) => new class($count, $id) {
2021-12-02 19:01:05 +01:00
private string $callbackId;
2021-09-29 16:00:33 +02:00
2021-12-02 19:12:06 +01:00
public function __construct(int &$count, &$id)
2021-09-29 16:00:33 +02:00
{
2021-12-02 19:12:06 +01:00
$this->callbackId = $id = EventLoop::repeat(
2021-12-02 19:01:05 +01:00
0.001,
weakClosure(function (string $callbackId) use (&$count): void {
2021-12-02 19:01:05 +01:00
AsyncTestCase::assertNotNull($this);
AsyncTestCase::assertStringContainsString('anonymous', \get_class($this));
AsyncTestCase::assertSame($callbackId, $this->callbackId);
++$count;
})
);
2021-09-29 16:00:33 +02:00
}
public function __destruct()
{
2021-12-02 19:01:05 +01:00
EventLoop::cancel($this->callbackId);
2021-09-29 16:00:33 +02:00
}
2021-12-02 19:01:05 +01:00
},
];
yield 'static' => [
2021-12-02 19:12:06 +01:00
fn (&$count, &$id) => new class($count, $id) {
2021-12-02 19:01:05 +01:00
private string $callbackId = '';
2021-09-29 16:00:33 +02:00
2021-12-02 19:12:06 +01:00
public function __construct(int &$count, &$id)
2021-09-29 16:00:33 +02:00
{
2021-12-02 19:01:05 +01:00
$callbackIdRef = &$this->callbackId;
$this->callbackId = $id = EventLoop::repeat(0.001, weakClosure(static function (string $callbackId) use (
2021-11-14 18:35:07 +01:00
&$count,
2021-12-02 19:01:05 +01:00
&$callbackIdRef
2021-09-29 16:00:33 +02:00
): void {
2021-12-02 19:01:05 +01:00
AsyncTestCase::assertSame($callbackId, $callbackIdRef);
2021-09-29 16:00:33 +02:00
++$count;
}));
}
public function __destruct()
{
2021-12-02 19:01:05 +01:00
EventLoop::cancel($this->callbackId);
2021-09-29 16:00:33 +02:00
}
2021-12-02 19:01:05 +01:00
},
];
yield 'fromCallable' => [
2021-12-02 19:12:06 +01:00
fn (&$count, &$id) => new class($count, $id) {
2021-12-02 19:01:05 +01:00
private string $callbackId = '';
2021-09-29 16:00:33 +02:00
private int $count;
2021-12-02 19:12:06 +01:00
public function __construct(int &$count, &$id)
2021-09-29 16:00:33 +02:00
{
$this->count = &$count;
2021-12-02 19:12:06 +01:00
$this->callbackId = $id = EventLoop::repeat(
0.001,
weakClosure(\Closure::fromCallable([$this, 'callback']))
2021-12-02 19:12:06 +01:00
);
2021-09-29 16:00:33 +02:00
}
2021-12-02 19:01:05 +01:00
private function callback(string $callbackId): void
2021-09-29 16:00:33 +02:00
{
AsyncTestCase::assertNotNull($this);
AsyncTestCase::assertStringContainsString('anonymous', \get_class($this));
2021-12-02 19:01:05 +01:00
AsyncTestCase::assertSame($callbackId, $this->callbackId);
2021-09-29 16:00:33 +02:00
++$this->count;
}
public function __destruct()
{
2021-12-02 19:01:05 +01:00
EventLoop::cancel($this->callbackId);
2021-09-29 16:00:33 +02:00
}
2021-12-02 19:01:05 +01:00
},
];
yield '__invoke' => [
2021-12-02 19:12:06 +01:00
fn (&$count, &$id) => new class($count, $id) {
2021-12-02 19:01:05 +01:00
private string $callbackId = '';
2021-09-29 16:00:33 +02:00
private int $count;
2021-12-02 19:12:06 +01:00
public function __construct(int &$count, &$id)
2021-09-29 16:00:33 +02:00
{
$this->count = &$count;
$this->callbackId = $id = EventLoop::repeat(0.001, weakClosure(\Closure::fromCallable($this)));
2021-09-29 16:00:33 +02:00
}
2021-12-02 19:01:05 +01:00
public function __invoke(string $callbackId): void
2021-09-29 16:00:33 +02:00
{
AsyncTestCase::assertNotNull($this);
AsyncTestCase::assertStringContainsString('anonymous', \get_class($this));
2021-12-02 19:01:05 +01:00
AsyncTestCase::assertSame($callbackId, $this->callbackId);
2021-09-29 16:00:33 +02:00
++$this->count;
}
public function __destruct()
{
2021-12-02 19:01:05 +01:00
EventLoop::cancel($this->callbackId);
2021-09-29 16:00:33 +02:00
}
2021-12-02 19:01:05 +01:00
},
2021-09-29 16:00:33 +02:00
];
}
/**
* @dataProvider provideObjectFactories
*/
public function test(callable $factory): void
{
2021-12-02 19:01:05 +01:00
$this->setTimeout(0.2);
2021-09-29 16:00:33 +02:00
$count = 0;
2021-12-02 19:12:06 +01:00
$id = null;
2021-09-29 16:00:33 +02:00
2021-12-02 19:12:06 +01:00
$object = $factory($count, $id);
2021-09-29 16:00:33 +02:00
2021-12-02 19:01:05 +01:00
delay(0.05);
self::assertGreaterThan(1, $count);
2021-12-02 19:12:06 +01:00
// Ensure the callback isn't cancelled, yet
EventLoop::enable($id);
2021-09-29 16:00:33 +02:00
2021-12-02 19:12:06 +01:00
unset($object); // Should destroy object and cancel loop watcher.
// Ensure the callback is already cancelled
$this->expectException(EventLoop\InvalidCallbackError::class);
$this->expectExceptionCode(EventLoop\InvalidCallbackError::E_INVALID_IDENTIFIER);
EventLoop::enable($id);
2021-09-29 16:00:33 +02:00
}
}