-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement error logging and better testing set up
- Loading branch information
Maxime Rainville
committed
Dec 3, 2024
1 parent
38c064f
commit 950ed93
Showing
5 changed files
with
132 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
namespace ArchiPro\Silverstripe\EventDispatcher\Service; | ||
|
||
use ArchiPro\EventDispatcher\AsyncEventDispatcher; | ||
use ArchiPro\EventDispatcher\ListenerProvider; | ||
use ColinODell\PsrTestLogger\TestLogger; | ||
use SilverStripe\Core\Injector\Injector; | ||
|
||
/** | ||
* Extension of the AsyncEventDispatcher for testing purposes. | ||
* | ||
* This service will throw exceptions when errors occur to make it easier to debug issues. | ||
*/ | ||
class TestEventService extends EventService | ||
{ | ||
private ?TestLogger $logger = null; | ||
|
||
public function __construct() | ||
{ | ||
$listenerProvider = Injector::inst()->get(ListenerProvider::class); | ||
|
||
// The test logger is useful but we don't want to force people to install it in production. | ||
if (class_exists(TestLogger::class)) { | ||
$this->logger = new TestLogger(); | ||
} | ||
$dispatcher = new AsyncEventDispatcher($listenerProvider, $this->logger, AsyncEventDispatcher::THROW_ON_ERROR); | ||
parent::__construct($dispatcher, $listenerProvider); | ||
} | ||
|
||
/** | ||
* Bootstrap the TestEventService. Will replace the default EventService with a TestEventService. | ||
*/ | ||
public static function bootstrap(): self | ||
{ | ||
$service = new self(); | ||
Injector::inst()->registerService($service, AsyncEventDispatcher::class); | ||
return $service; | ||
} | ||
|
||
/** | ||
* Return a logger that can be used to see if an array errors were thrown by the event loop. | ||
*/ | ||
public function getLogger(): TestLogger | ||
{ | ||
if (!$this->logger) { | ||
throw new \RuntimeException( | ||
'To use the EventService\'s test logger, you must install colinodell/psr-testlogger. ' . | ||
'`composer require --dev colinodell/psr-testlogger`' | ||
); | ||
} | ||
return $this->logger; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
|
||
namespace ArchiPro\Silverstripe\EventDispatcher\Tests\Service; | ||
|
||
use ArchiPro\Silverstripe\EventDispatcher\Service\TestEventService; | ||
use Exception; | ||
use Revolt\EventLoop; | ||
use Revolt\EventLoop\UncaughtThrowable; | ||
use SilverStripe\Dev\SapphireTest; | ||
|
||
class TestEventServiceTest extends SapphireTest | ||
{ | ||
private TestEventService $service; | ||
|
||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
$this->service = TestEventService::bootstrap(); | ||
} | ||
|
||
public function testEventDispatchLogger(): void | ||
{ | ||
// Create test event | ||
$event = new class () {}; | ||
|
||
// Add test listener | ||
$this->service->addListener(get_class($event), function ($event) { | ||
throw new Exception('Test exception'); | ||
}); | ||
|
||
// Dispatch event | ||
$result = $this->service->dispatch($event); | ||
|
||
EventLoop::run(); | ||
|
||
$this->assertCount( | ||
1, | ||
$this->service->getLogger()->records, | ||
'Running the event loop will cause an error to be logged' | ||
); | ||
} | ||
|
||
public function testEventDispatchThrow(): void | ||
{ | ||
// Create test event | ||
$event = new class () {}; | ||
|
||
// Add test listener | ||
$this->service->addListener(get_class($event), function ($event) { | ||
throw new Exception('Test exception'); | ||
}); | ||
|
||
$this->expectException( | ||
UncaughtThrowable::class, | ||
'Dispatching an event with a listener that throws an exception will throw an UncaughtThrowable' | ||
); | ||
|
||
// Dispatch event | ||
$result = $this->service->dispatch($event)->await(); | ||
} | ||
} |