rector/vendor/evenement/evenement/tests/Evenement/Tests/EventEmitterTest.php
Tomas Votruba aae549741f Updated Rector to commit 0cb3fd0feb464b4568e07607a05c794637aa2862
0cb3fd0feb [Php73] Handle crash Type Error on JsonThrowOnErrorRector (#4626)
2023-08-01 10:55:14 +00:00

346 lines
12 KiB
PHP

<?php
declare (strict_types=1);
/*
* This file is part of Evenement.
*
* (c) Igor Wiedler <igor@wiedler.ch>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace RectorPrefix202308\Evenement\Tests;
use RectorPrefix202308\Evenement\EventEmitter;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
class EventEmitterTest extends TestCase
{
private $emitter;
public function setUp()
{
$this->emitter = new EventEmitter();
}
public function testAddListenerWithLambda()
{
$this->emitter->on('foo', function () {
});
}
public function testAddListenerWithMethod()
{
$listener = new Listener();
$this->emitter->on('foo', [$listener, 'onFoo']);
}
public function testAddListenerWithStaticMethod()
{
$this->emitter->on('bar', ['RectorPrefix202308\\Evenement\\Tests\\Listener', 'onBar']);
}
public function testAddListenerWithInvalidListener()
{
try {
$this->emitter->on('foo', 'not a callable');
$this->fail();
} catch (\Exception $e) {
} catch (\TypeError $e) {
}
}
public function testOnce()
{
$listenerCalled = 0;
$this->emitter->once('foo', function () use(&$listenerCalled) {
$listenerCalled++;
});
$this->assertSame(0, $listenerCalled);
$this->emitter->emit('foo');
$this->assertSame(1, $listenerCalled);
$this->emitter->emit('foo');
$this->assertSame(1, $listenerCalled);
}
public function testOnceWithArguments()
{
$capturedArgs = [];
$this->emitter->once('foo', function ($a, $b) use(&$capturedArgs) {
$capturedArgs = array($a, $b);
});
$this->emitter->emit('foo', array('a', 'b'));
$this->assertSame(array('a', 'b'), $capturedArgs);
}
public function testEmitWithoutArguments()
{
$listenerCalled = \false;
$this->emitter->on('foo', function () use(&$listenerCalled) {
$listenerCalled = \true;
});
$this->assertSame(\false, $listenerCalled);
$this->emitter->emit('foo');
$this->assertSame(\true, $listenerCalled);
}
public function testEmitWithOneArgument()
{
$test = $this;
$listenerCalled = \false;
$this->emitter->on('foo', function ($value) use(&$listenerCalled, $test) {
$listenerCalled = \true;
$test->assertSame('bar', $value);
});
$this->assertSame(\false, $listenerCalled);
$this->emitter->emit('foo', ['bar']);
$this->assertSame(\true, $listenerCalled);
}
public function testEmitWithTwoArguments()
{
$test = $this;
$listenerCalled = \false;
$this->emitter->on('foo', function ($arg1, $arg2) use(&$listenerCalled, $test) {
$listenerCalled = \true;
$test->assertSame('bar', $arg1);
$test->assertSame('baz', $arg2);
});
$this->assertSame(\false, $listenerCalled);
$this->emitter->emit('foo', ['bar', 'baz']);
$this->assertSame(\true, $listenerCalled);
}
public function testEmitWithNoListeners()
{
$this->emitter->emit('foo');
$this->emitter->emit('foo', ['bar']);
$this->emitter->emit('foo', ['bar', 'baz']);
}
public function testEmitWithTwoListeners()
{
$listenersCalled = 0;
$this->emitter->on('foo', function () use(&$listenersCalled) {
$listenersCalled++;
});
$this->emitter->on('foo', function () use(&$listenersCalled) {
$listenersCalled++;
});
$this->assertSame(0, $listenersCalled);
$this->emitter->emit('foo');
$this->assertSame(2, $listenersCalled);
}
public function testRemoveListenerMatching()
{
$listenersCalled = 0;
$listener = function () use(&$listenersCalled) {
$listenersCalled++;
};
$this->emitter->on('foo', $listener);
$this->emitter->removeListener('foo', $listener);
$this->assertSame(0, $listenersCalled);
$this->emitter->emit('foo');
$this->assertSame(0, $listenersCalled);
}
public function testRemoveListenerNotMatching()
{
$listenersCalled = 0;
$listener = function () use(&$listenersCalled) {
$listenersCalled++;
};
$this->emitter->on('foo', $listener);
$this->emitter->removeListener('bar', $listener);
$this->assertSame(0, $listenersCalled);
$this->emitter->emit('foo');
$this->assertSame(1, $listenersCalled);
}
public function testRemoveAllListenersMatching()
{
$listenersCalled = 0;
$this->emitter->on('foo', function () use(&$listenersCalled) {
$listenersCalled++;
});
$this->emitter->removeAllListeners('foo');
$this->assertSame(0, $listenersCalled);
$this->emitter->emit('foo');
$this->assertSame(0, $listenersCalled);
}
public function testRemoveAllListenersNotMatching()
{
$listenersCalled = 0;
$this->emitter->on('foo', function () use(&$listenersCalled) {
$listenersCalled++;
});
$this->emitter->removeAllListeners('bar');
$this->assertSame(0, $listenersCalled);
$this->emitter->emit('foo');
$this->assertSame(1, $listenersCalled);
}
public function testRemoveAllListenersWithoutArguments()
{
$listenersCalled = 0;
$this->emitter->on('foo', function () use(&$listenersCalled) {
$listenersCalled++;
});
$this->emitter->on('bar', function () use(&$listenersCalled) {
$listenersCalled++;
});
$this->emitter->removeAllListeners();
$this->assertSame(0, $listenersCalled);
$this->emitter->emit('foo');
$this->emitter->emit('bar');
$this->assertSame(0, $listenersCalled);
}
public function testCallablesClosure()
{
$calledWith = null;
$this->emitter->on('foo', function ($data) use(&$calledWith) {
$calledWith = $data;
});
$this->emitter->emit('foo', ['bar']);
self::assertSame('bar', $calledWith);
}
public function testCallablesClass()
{
$listener = new Listener();
$this->emitter->on('foo', [$listener, 'onFoo']);
$this->emitter->emit('foo', ['bar']);
self::assertSame(['bar'], $listener->getData());
}
public function testCallablesClassInvoke()
{
$listener = new Listener();
$this->emitter->on('foo', $listener);
$this->emitter->emit('foo', ['bar']);
self::assertSame(['bar'], $listener->getMagicData());
}
public function testCallablesStaticClass()
{
$this->emitter->on('foo', '\\Evenement\\Tests\\Listener::onBar');
$this->emitter->emit('foo', ['bar']);
self::assertSame(['bar'], Listener::getStaticData());
}
public function testCallablesFunction()
{
$this->emitter->on('foo', 'RectorPrefix202308\\Evenement\\Tests\\setGlobalTestData');
$this->emitter->emit('foo', ['bar']);
self::assertSame('bar', $GLOBALS['evenement-evenement-test-data']);
unset($GLOBALS['evenement-evenement-test-data']);
}
public function testListeners()
{
$onA = function () {
};
$onB = function () {
};
$onC = function () {
};
$onceA = function () {
};
$onceB = function () {
};
$onceC = function () {
};
self::assertCount(0, $this->emitter->listeners('event'));
$this->emitter->on('event', $onA);
self::assertCount(1, $this->emitter->listeners('event'));
self::assertSame([$onA], $this->emitter->listeners('event'));
$this->emitter->once('event', $onceA);
self::assertCount(2, $this->emitter->listeners('event'));
self::assertSame([$onA, $onceA], $this->emitter->listeners('event'));
$this->emitter->once('event', $onceB);
self::assertCount(3, $this->emitter->listeners('event'));
self::assertSame([$onA, $onceA, $onceB], $this->emitter->listeners('event'));
$this->emitter->on('event', $onB);
self::assertCount(4, $this->emitter->listeners('event'));
self::assertSame([$onA, $onB, $onceA, $onceB], $this->emitter->listeners('event'));
$this->emitter->removeListener('event', $onceA);
self::assertCount(3, $this->emitter->listeners('event'));
self::assertSame([$onA, $onB, $onceB], $this->emitter->listeners('event'));
$this->emitter->once('event', $onceC);
self::assertCount(4, $this->emitter->listeners('event'));
self::assertSame([$onA, $onB, $onceB, $onceC], $this->emitter->listeners('event'));
$this->emitter->on('event', $onC);
self::assertCount(5, $this->emitter->listeners('event'));
self::assertSame([$onA, $onB, $onC, $onceB, $onceC], $this->emitter->listeners('event'));
$this->emitter->once('event', $onceA);
self::assertCount(6, $this->emitter->listeners('event'));
self::assertSame([$onA, $onB, $onC, $onceB, $onceC, $onceA], $this->emitter->listeners('event'));
$this->emitter->removeListener('event', $onB);
self::assertCount(5, $this->emitter->listeners('event'));
self::assertSame([$onA, $onC, $onceB, $onceC, $onceA], $this->emitter->listeners('event'));
$this->emitter->emit('event');
self::assertCount(2, $this->emitter->listeners('event'));
self::assertSame([$onA, $onC], $this->emitter->listeners('event'));
}
public function testOnceCallIsNotRemovedWhenWorkingOverOnceListeners()
{
$aCalled = \false;
$aCallable = function () use(&$aCalled) {
$aCalled = \true;
};
$bCalled = \false;
$bCallable = function () use(&$bCalled, $aCallable) {
$bCalled = \true;
$this->emitter->once('event', $aCallable);
};
$this->emitter->once('event', $bCallable);
self::assertFalse($aCalled);
self::assertFalse($bCalled);
$this->emitter->emit('event');
self::assertFalse($aCalled);
self::assertTrue($bCalled);
$this->emitter->emit('event');
self::assertTrue($aCalled);
self::assertTrue($bCalled);
}
public function testEventNameMustBeStringOn()
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('event name must not be null');
$this->emitter->on(null, function () {
});
}
public function testEventNameMustBeStringOnce()
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('event name must not be null');
$this->emitter->once(null, function () {
});
}
public function testEventNameMustBeStringRemoveListener()
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('event name must not be null');
$this->emitter->removeListener(null, function () {
});
}
public function testEventNameMustBeStringEmit()
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('event name must not be null');
$this->emitter->emit(null);
}
public function testListenersGetAll()
{
$a = function () {
};
$b = function () {
};
$c = function () {
};
$d = function () {
};
$this->emitter->once('event2', $c);
$this->emitter->on('event', $a);
$this->emitter->once('event', $b);
$this->emitter->on('event', $c);
$this->emitter->once('event', $d);
self::assertSame(['event' => [$a, $c, $b, $d], 'event2' => [$c]], $this->emitter->listeners());
}
public function testOnceNestedCallRegression()
{
$first = 0;
$second = 0;
$this->emitter->once('event', function () use(&$first, &$second) {
$first++;
$this->emitter->once('event', function () use(&$second) {
$second++;
});
$this->emitter->emit('event');
});
$this->emitter->emit('event');
self::assertSame(1, $first);
self::assertSame(1, $second);
}
}