-
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.
Merge pull request #4 from archiprocode/pulls/0/better-error-handler
Add support for TestEventService
- Loading branch information
Showing
7 changed files
with
193 additions
and
11 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,24 @@ | ||
--- | ||
Name: events | ||
Name: event-service | ||
After: | ||
- '#coreservices' | ||
--- | ||
SilverStripe\Core\Injector\Injector: | ||
# Define the listener provider | ||
ArchiPro\EventDispatcher\ListenerProvider: | ||
class: ArchiPro\EventDispatcher\ListenerProvider | ||
|
||
# Default event dispatcher | ||
ArchiPro\EventDispatcher\AsyncEventDispatcher: | ||
class: ArchiPro\EventDispatcher\AsyncEventDispatcher | ||
constructor: | ||
listenerProvider: '%$ArchiPro\EventDispatcher\ListenerProvider' | ||
errorhandler: [ArchiPro\Silverstripe\EventDispatcher\Service\EventService, handleError] | ||
Psr\EventDispatcher\EventDispatcherInterface: | ||
alias: '%$ArchiPro\EventDispatcher\AsyncEventDispatcher' | ||
|
||
# Bootstrap the event service | ||
ArchiPro\Silverstripe\EventDispatcher\Service\EventService: | ||
constructor: | ||
constructor: | ||
dispatcher: '%$ArchiPro\EventDispatcher\AsyncEventDispatcher' | ||
listenerProvider: '%$ArchiPro\EventDispatcher\ListenerProvider' | ||
listenerProvider: '%$ArchiPro\EventDispatcher\ListenerProvider' |
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,65 @@ | ||
<?php | ||
|
||
namespace ArchiPro\Silverstripe\EventDispatcher\Service; | ||
|
||
use ArchiPro\EventDispatcher\AsyncEventDispatcher; | ||
use ArchiPro\EventDispatcher\ListenerProvider; | ||
use Closure; | ||
use ColinODell\PsrTestLogger\TestLogger; | ||
use SilverStripe\Core\Injector\Injector; | ||
use Throwable; | ||
|
||
/** | ||
* 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; | ||
|
||
public function __construct() | ||
{ | ||
if (!class_exists(TestLogger::class)) { | ||
throw new \Exception( | ||
'To use the TestEventService, you must require the "colinodell/psr-testlogger" ' . | ||
'package in your dev dependencies.' | ||
); | ||
} | ||
|
||
$this->logger = new TestLogger(); | ||
|
||
$listenerProvider = Injector::inst()->get(ListenerProvider::class); | ||
$dispatcher = new AsyncEventDispatcher( | ||
$listenerProvider, | ||
Closure::fromCallable([$this, 'recordError']) | ||
); | ||
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; | ||
} | ||
|
||
/** | ||
* Catch errors and store them for later inspection. | ||
*/ | ||
private function recordError(Throwable $message): void | ||
{ | ||
$this->logger->error($message->getMessage(), ['exception' => $message]); | ||
} | ||
|
||
/** | ||
* Test logger where exception thrown by listeners are logged. | ||
*/ | ||
public function getTestLogger(): 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
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,46 @@ | ||
<?php | ||
|
||
namespace ArchiPro\Silverstripe\EventDispatcher\Tests\Service; | ||
|
||
use ArchiPro\Silverstripe\EventDispatcher\Service\TestEventService; | ||
use Exception; | ||
use Revolt\EventLoop; | ||
use SilverStripe\Dev\SapphireTest; | ||
|
||
class TestEventServiceTest extends SapphireTest | ||
{ | ||
private TestEventService $service; | ||
|
||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
$this->service = TestEventService::bootstrap(); | ||
} | ||
|
||
public function testGetTestLogger(): void | ||
{ | ||
// Create test event | ||
$event = new class () {}; | ||
|
||
// Add test listener | ||
$this->service->addListener(get_class($event), function ($event) { | ||
throw new Exception('Test exception'); | ||
}); | ||
|
||
$this->assertFalse( | ||
$this->service->getTestLogger()->hasErrorRecords(), | ||
'No exceptions have been thrown yet' | ||
); | ||
|
||
// Dispatch event | ||
$this->service->dispatch($event); | ||
|
||
EventLoop::run(); | ||
|
||
$this->assertCount( | ||
1, | ||
$this->service->getTestLogger()->records, | ||
'Running the event loop will cause an error to be logged' | ||
); | ||
} | ||
} |