Merge pull request #7

This commit is contained in:
Jeremy Mikola
2016-09-14 15:36:37 -04:00
8 changed files with 103 additions and 17 deletions
+21 -1
View File
@@ -1,7 +1,27 @@
language: php
sudo: false
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
before_script: composer install --dev
matrix:
fast_finish: true
allow_failures:
- php: hhvm
- env: SYMFONY_VERSION=3.0.*
include:
- php: 5.3
env: COMPOSER_FLAGS="--prefer-lowest"
before_install:
- travis_retry composer self-update
install:
- composer update ${COMPOSER_FLAGS} --no-interaction
+24 -9
View File
@@ -2,21 +2,36 @@
[![Build Status](https://travis-ci.org/jmikola/WildcardEventDispatcher.png?branch=master)](https://travis-ci.org/jmikola/WildcardEventDispatcher)
This library implements an event dispatcher, based on [Symfony2's interface][],
This library implements an event dispatcher, based on [Symfony's interface][],
with wildcard syntax inspired by AMQP topic exchanges. Listeners may be bound to
a wildcard pattern and be notified if a dispatched event's name matches that
pattern. Literal event name matching is still supported.
If you are interested in using this library in a Symfony2 project, you may also
If you are interested in using this library in a Symfony project, you may also
want to take a look at the corresponding [bundle][].
[Symfony2's interface]: https://github.com/symfony/EventDispatcher
[Symfony's interface]: https://github.com/symfony/EventDispatcher
[bundle]: https://github.com/jmikola/JmikolaWildcardEventDispatcherBundle
## Usage ##
## Installation
The library is published as a [package][] and is installable via [Composer][]:
```
$ composer require jmikola/wildcard-event-dispatcher=~1.0
```
[package]: https://packagist.org/packages/jmikola/wildcard-event-dispatcher
[Composer]: http://getcomposer.org/
### Compatibility
This library requires Symfony 2.3 or above.
## Usage
WildcardEventDispatcher implements EventDispatcherInterface and may be used as
you would Symfony2's standard EventDispatcher:
you would Symfony's standard EventDispatcher:
```php
<?php
@@ -50,9 +65,9 @@ $dispatcher = new WildcardEventDispatcher(new EventDispatcher());
[composes]: http://en.wikipedia.org/wiki/Object_composition
## Wildcard Syntax ##
## Wildcard Syntax
### Single-word Wildcard ###
### Single-word Wildcard
Consider the scenario where the same listener is defined for multiple events,
all of which share a common prefix:
@@ -90,7 +105,7 @@ and followed by another word. The matching of `core` alone may not make sense,
but this is implemented in order to be consistent with AMQP. A trailing `*`
after a non-empty sequence may match the preceding sequence sans `.*`.
### Multi-word Wildcard ###
### Multi-word Wildcard
Suppose there was a `core` event in your application named `core.foo.bar`. The
aforementioned `core.*` pattern would not catch this event. You could use:
@@ -130,7 +145,7 @@ $dispatcher = new WildcardEventDispatcher();
$dispatcher->addListener('#', $allListener);
```
### Additional Wildcard Documentation ###
### Additional Wildcard Documentation
When in doubt, the unit tests for `ListenerPattern` are a good resource for
inferring how wildcards will be interpreted. This library aims to mimic the
+1 -2
View File
@@ -8,10 +8,9 @@
"authors": [
{ "name": "Jeremy Mikola", "email": "jmikola@gmail.com" }
],
"minimum-stability": "dev",
"require": {
"php": ">=5.3.2",
"symfony/event-dispatcher": "~2.0"
"symfony/event-dispatcher": "^2.3 || ^3.0"
},
"autoload": {
"psr-0": { "Jmikola": "src/" }
@@ -15,7 +15,7 @@ class LazyListenerPattern extends ListenerPattern
* @param string $eventPattern
* @param callback $listenerProvider
* @param integer $priority
* @throws InvalidArgumentException if the listener provider is not a callback
* @throws \InvalidArgumentException if the listener provider is not a callback
*/
public function __construct($eventPattern, $listenerProvider, $priority = 0)
{
@@ -16,7 +16,7 @@ class WildcardEventDispatcher implements EventDispatcherInterface
/**
* Constructor.
*
* If an EventDispatcherInterface is not provided , a new EventDispatcher
* If an EventDispatcherInterface is not provided, a new EventDispatcher
* will be composed.
*
* @param EventDispatcherInterface $dispatcher
@@ -195,4 +195,22 @@ class WildcardEventDispatcher implements EventDispatcherInterface
}
}
}
/**
* @see EventDispatcherInterface::getListenerPriority()
* @throws \InvalidArgumentException if $eventName contains a wildcard pattern
* @throws \BadMethodCallException if this method is not implemented on the composed EventDispatcher
*/
public function getListenerPriority($eventName, $listener)
{
if ($this->hasWildcards($eventName)) {
throw new \InvalidArgumentException('Wildcard patterns are not supported');
}
if ( ! method_exists($this->dispatcher, 'getListenerPriority')) {
throw new \BadMethodCallException('getListenerPriority() is not implemented');
}
return $this->dispatcher->getListenerPriority($eventName, $listener);
}
}
@@ -86,6 +86,6 @@ class ListenerPatternTest extends \PHPUnit_Framework_TestCase
private function getMockEventDispatcher()
{
return $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
return $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
}
}
@@ -127,7 +127,7 @@ class WildcardEventDispatcherFunctionalTest extends \PHPUnit_Framework_TestCase
private function assertNumberListenersAdded($expected, $eventName = null)
{
return isset($eventName)
? $this->assertEquals($expected, count($this->dispatcher->getListeners($eventName)))
? $this->assertCount($expected, $this->dispatcher->getListeners($eventName))
: $this->assertEquals($expected, array_sum(array_map('count', $this->dispatcher->getListeners())));
}
}
@@ -146,9 +146,43 @@ class EventDispatcherTest extends \PHPUnit_Framework_TestCase
$this->dispatcher->removeSubscriber($subscriber);
}
public function testGetListenerPriorityInvokesMethodOnInnerDispather()
{
if ( ! method_exists('Symfony\Component\EventDispatcher\EventDispatcherInterface', 'getListenerPriority')) {
$this->markTestSkipped('getListenerPriority() does not exist on EventDispatcherInterface');
}
$this->innerDispatcher->expects($this->once())
->method('getListenerPriority')
->with('core.request', 'callback')
->will($this->returnValue(1));
$this->assertSame(1, $this->dispatcher->getListenerPriority('core.request', 'callback'));
}
/**
* @expectedException InvalidArgumentException
*/
public function testGetListenerPriorityRequiresEventNameWithoutWildcards()
{
$this->dispatcher->getListenerPriority('core.*', 'callback');
}
/**
* @expectedException BadMethodCallException
*/
public function testGetListenerPriorityRequiresMethodOnInnerDispather()
{
if (method_exists('Symfony\Component\EventDispatcher\EventDispatcherInterface', 'getListenerPriority')) {
$this->markTestSkipped('getListenerPriority() exists on EventDispatcherInterface');
}
$this->dispatcher->getListenerPriority('core.request', 'callback');
}
private function getMockEventDispatcher()
{
return $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
return $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
}
}