.State 0000666 00000000012 13371317246 0005631 0 ustar 00 finalized
.gitignore 0000666 00000000030 13371317246 0006540 0 ustar 00 /vendor/
/composer.lock
Bucket.php 0000666 00000006504 13371317246 0006512 0 ustar 00 setData($data);
return;
}
/**
* Send this object on the event channel.
*
* @param string $eventId Event ID.
* @param \Hoa\Event\Source $source Source.
* @return void
*/
public function send($eventId, Source $source)
{
return Event::notify($eventId, $source, $this);
}
/**
* Set source.
*
* @param \Hoa\Event\Source $source Source.
* @return \Hoa\Event\Source
*/
public function setSource(Source $source)
{
$old = $this->_source;
$this->_source = $source;
return $old;
}
/**
* Get source.
*
* @return \Hoa\Event\Source
*/
public function getSource()
{
return $this->_source;
}
/**
* Set data.
*
* @param mixed $data Data.
* @return mixed
*/
public function setData($data)
{
$old = $this->_data;
$this->_data = $data;
return $old;
}
/**
* Get data.
*
* @return mixed
*/
public function getData()
{
return $this->_data;
}
}
CHANGELOG.md 0000666 00000004546 13371317246 0006401 0 ustar 00 # 1.17.01.13
* Quality: Happy new year! (Alexis von Glasow, 2017-01-11T23:09:35+01:00)
# 1.16.11.19
* Documentation: New `README.md` file. (Ivan Enderlin, 2016-10-18T16:34:43+02:00)
* Documentation: Update `support` properties. (Ivan Enderlin, 2016-10-05T20:36:30+02:00)
# 1.16.03.15
* Fix a typo (Metalaka, 2016-01-28T09:05:40+01:00)
* CHANGELOG: Add a missing newline. (Ivan Enderlin, 2016-01-11T09:37:32+01:00)
# 1.16.01.11
* Quality: Drop PHP5.4. (Ivan Enderlin, 2016-01-11T09:15:26+01:00)
* Quality: Run devtools:cs. (Ivan Enderlin, 2016-01-09T09:01:10+01:00)
* Core: Remove `Hoa\Core`. (Ivan Enderlin, 2016-01-09T08:14:54+01:00)
* Consistency: Use `Hoa\Consistency`. (Ivan Enderlin, 2015-12-08T11:10:00+01:00)
* Documentation: Fix typos. (Ivan Enderlin, 2015-11-23T22:05:56+01:00)
* Exception: Use `Hoa\Exception`. (Ivan Enderlin, 2015-11-20T07:40:34+01:00)
# 0.15.11.23
* Documentation: Fix typos. (Ivan Enderlin, 2015-11-23T22:05:56+01:00)
* Exception: Use `Hoa\Exception`. (Ivan Enderlin, 2015-11-20T07:40:34+01:00)
* Test: Fix a conflict between 2 test suites. (Ivan Enderlin, 2015-11-23T21:29:28+01:00)
* Test: Write test suite for `Hoa\Event\Listens`. (Ivan Enderlin, 2015-11-23T21:25:49+01:00)
* Listener: Add the `Listens` trait. (Ivan Enderlin, 2015-11-20T06:45:11+01:00)
* Documentation: Fix a typo. (Ivan Enderlin, 2015-11-23T13:01:56+01:00)
* Improve readability by adding constants to registered events container. (Metalaka, 2015-11-20T19:53:32+01:00)
* Add a `.gitignore` file. (Metalaka, 2015-11-20T19:37:52+01:00)
* README: Complete description and add usage. (Ivan Enderlin, 2015-11-13T08:43:08+01:00)
* Test: Write test suite for `Hoa\Event\Event`. (Ivan Enderlin, 2015-11-11T17:04:41+01:00)
* Test: Write test suite for `Hoa\Event\Exception`. (Ivan Enderlin, 2015-11-11T16:46:12+01:00)
* Composer: Add a keyword. (Ivan Enderlin, 2015-11-11T13:38:35+01:00)
* Test: Write test suite for `Hoa\Event\Listener`. (Ivan Enderlin, 2015-11-11T13:27:40+01:00)
* Test: Write test suite for `Hoa\Event\Source`. (Ivan Enderlin, 2015-11-10T21:56:37+01:00)
* Test: Write test suite for `Hoa\Event\Listenable`. (Ivan Enderlin, 2015-11-10T21:56:24+01:00)
* Test: Write test suite for `Hoa\Event\Bucket`. (Ivan Enderlin, 2015-11-10T21:55:45+01:00)
* Split from `Hoa\Core`. (Ivan Enderlin, 2015-11-10T21:28:31+01:00)
(first snapshot)
Event.php 0000666 00000016550 13371317246 0006360 0 ustar 00 new self(),
self::KEY_SOURCE => null
];
}
return self::$_register[$eventId][self::KEY_EVENT];
}
/**
* Declare a new object in the observable collection.
* Note: Hoa's libraries use hoa://Event/AnID for their observable objects;
*
* @param string $eventId Event ID.
* @param \Hoa\Event\Source|string $source Observable object or class.
* @return void
* @throws \Hoa\Event\Exception
*/
public static function register($eventId, $source)
{
if (true === self::eventExists($eventId)) {
throw new Exception(
'Cannot redeclare an event with the same ID, i.e. the event ' .
'ID %s already exists.',
0,
$eventId
);
}
if (is_object($source) && !($source instanceof Source)) {
throw new Exception(
'The source must implement \Hoa\Event\Source ' .
'interface; given %s.',
1,
get_class($source)
);
} else {
$reflection = new \ReflectionClass($source);
if (false === $reflection->implementsInterface('\Hoa\Event\Source')) {
throw new Exception(
'The source must implement \Hoa\Event\Source ' .
'interface; given %s.',
2,
$source
);
}
}
if (!isset(self::$_register[$eventId][self::KEY_EVENT])) {
self::$_register[$eventId][self::KEY_EVENT] = new self();
}
self::$_register[$eventId][self::KEY_SOURCE] = $source;
return;
}
/**
* Undeclare an object in the observable collection.
*
* @param string $eventId Event ID.
* @param bool $hard If false, just delete the source, else,
* delete source and attached callables.
* @return void
*/
public static function unregister($eventId, $hard = false)
{
if (false !== $hard) {
unset(self::$_register[$eventId]);
} else {
self::$_register[$eventId][self::KEY_SOURCE] = null;
}
return;
}
/**
* Attach an object to an event.
* It can be a callable or an accepted callable form (please, see the
* \Hoa\Consistency\Xcallable class).
*
* @param mixed $callable Callable.
* @return \Hoa\Event\Event
*/
public function attach($callable)
{
$callable = xcallable($callable);
$this->_callable[$callable->getHash()] = $callable;
return $this;
}
/**
* Detach an object to an event.
* Please see $this->attach() method.
*
* @param mixed $callable Callable.
* @return \Hoa\Event\Event
*/
public function detach($callable)
{
unset($this->_callable[xcallable($callable)->getHash()]);
return $this;
}
/**
* Check if at least one callable is attached to an event.
*
* @return bool
*/
public function isListened()
{
return !empty($this->_callable);
}
/**
* Notify, i.e. send data to observers.
*
* @param string $eventId Event ID.
* @param \Hoa\Event\Source $source Source.
* @param \Hoa\Event\Bucket $data Data.
* @return void
* @throws \Hoa\Event\Exception
*/
public static function notify($eventId, Source $source, Bucket $data)
{
if (false === self::eventExists($eventId)) {
throw new Exception(
'Event ID %s does not exist, cannot send notification.',
3,
$eventId
);
}
$data->setSource($source);
$event = self::getEvent($eventId);
foreach ($event->_callable as $callable) {
$callable($data);
}
return;
}
/**
* Check whether an event exists.
*
* @param string $eventId Event ID.
* @return bool
*/
public static function eventExists($eventId)
{
return
array_key_exists($eventId, self::$_register) &&
self::$_register[$eventId][self::KEY_SOURCE] !== null;
}
}
/**
* Flex entity.
*/
Consistency::flexEntity('Hoa\Event\Event');
Exception.php 0000666 00000003606 13371317246 0007233 0 ustar 00 _source = $source;
$this->addIds($ids);
return;
}
/**
* Add acceptable ID (or reset).
*
* @param array $ids Accepted ID.
* @return void
*/
public function addIds(array $ids)
{
foreach ($ids as $id) {
$this->_callables[$id] = [];
}
return;
}
/**
* Attach a callable to a listenable component.
*
* @param string $listenerId Listener ID.
* @param mixed $callable Callable.
* @return \Hoa\Event\Listener
* @throws \Hoa\Event\Exception
*/
public function attach($listenerId, $callable)
{
if (false === $this->listenerExists($listenerId)) {
throw new Exception(
'Cannot listen %s because it is not defined.',
0,
$listenerId
);
}
$callable = xcallable($callable);
$this->_callables[$listenerId][$callable->getHash()] = $callable;
return $this;
}
/**
* Detach a callable from a listenable component.
*
* @param string $listenerId Listener ID.
* @param mixed $callable Callable.
* @return \Hoa\Event\Listener
*/
public function detach($listenerId, $callable)
{
unset($this->_callables[$listenerId][xcallable($callable)->getHash()]);
return $this;
}
/**
* Detach all callables from a listenable component.
*
* @param string $listenerId Listener ID.
* @return \Hoa\Event\Listener
*/
public function detachAll($listenerId)
{
unset($this->_callables[$listenerId]);
return $this;
}
/**
* Check if a listener exists.
*
* @param string $listenerId Listener ID.
* @return bool
*/
public function listenerExists($listenerId)
{
return array_key_exists($listenerId, $this->_callables);
}
/**
* Send/fire a bucket to a listener.
*
* @param string $listenerId Listener ID.
* @param \Hoa\Event\Bucket $data Data.
* @return array
* @throws \Hoa\Event\Exception
*/
public function fire($listenerId, Bucket $data)
{
if (false === $this->listenerExists($listenerId)) {
throw new Exception(
'Cannot fire on %s because it is not defined.',
1,
$listenerId
);
}
$data->setSource($this->_source);
$out = [];
foreach ($this->_callables[$listenerId] as $callable) {
$out[] = $callable($data);
}
return $out;
}
}
Listens.php 0000666 00000006033 13371317246 0006713 0 ustar 00 getListener();
if (null === $listener) {
throw new Exception(
'Cannot attach a callable to the listener %s because ' .
'it has not been initialized yet.',
0,
get_class($this)
);
}
$listener->attach($listenerId, $callable);
return $this;
}
/**
* Set listener.
*
* @param \Hoa\Event\Listener $listener Listener.
* @return \Hoa\Event\Listener
*/
protected function setListener(Listener $listener)
{
$old = $this->_listener;
$this->_listener = $listener;
return $old;
}
/**
* Get listener.
*
* @return \Hoa\Event\Listener
*/
protected function getListener()
{
return $this->_listener;
}
}
README.md 0000666 00000012560 13371317246 0006042 0 ustar 00
---
Hoa is a modular, extensible and
structured set of PHP libraries.
Moreover, Hoa aims at being a bridge between industrial and research worlds.
# Hoa\Event
[![Help on IRC](https://img.shields.io/badge/help-%23hoaproject-ff0066.svg)](https://webchat.freenode.net/?channels=#hoaproject)
[![Help on Gitter](https://img.shields.io/badge/help-gitter-ff0066.svg)](https://gitter.im/hoaproject/central)
[![Documentation](https://img.shields.io/badge/documentation-hack_book-ff0066.svg)](https://central.hoa-project.net/Documentation/Library/Event)
[![Board](https://img.shields.io/badge/organisation-board-ff0066.svg)](https://waffle.io/hoaproject/event)
This library allows to use events and listeners in PHP. This is an observer
design-pattern implementation.
[Learn more](https://central.hoa-project.net/Documentation/Library/Event).
## Installation
With [Composer](https://getcomposer.org/), to include this library into
your dependencies, you need to
require [`hoa/event`](https://packagist.org/packages/hoa/event):
```sh
$ composer require hoa/event '~1.0'
```
For more installation procedures, please read [the Source
page](https://hoa-project.net/Source.html).
## Testing
Before running the test suites, the development dependencies must be installed:
```sh
$ composer install
```
Then, to run all the test suites:
```sh
$ vendor/bin/hoa test:run
```
For more information, please read the [contributor
guide](https://hoa-project.net/Literature/Contributor/Guide.html).
## Quick usage
We propose a quick overview of how to use events and listeners.
### Events
An event is:
* **Asynchronous** when registering, because the observable may not exist yet
while observers start to observe,
* **Anonymous** when using, because the observable has no idea how many and
what observers are observing,
* It aims at a **large** diffusion of data through isolated components.
Wherever is the observable, we can observe its data.
In Hoa, an event channel has the following form:
`hoa://Event/LibraryName/AnId:pseudo-class#anAnchor`. For instance, the
`hoa://Event/Exception` channel contains all exceptions that have been thrown.
The `hoa://Event/Stream/StreamName:close-before` contains all streams that are
about to close. Thus, the following example will observe all thrown exceptions:
```php
Hoa\Event\Event::getEvent('hoa://Event/Exception')->attach(
function (Hoa\Event\Bucket $bucket) {
var_dump(
$bucket->getSource(),
$bucket->getData()
);
}
);
```
Because `attach` expects a callable and because Hoa's callable implementation is
smart, we can directly attach a stream to an event, like:
```php
Hoa\Event\Event::getEvent('hoa://Event/Exception')->attach(
new Hoa\File\Write('Foo.log')
);
```
This way, all exceptions will be printed on the `Foo.log` file.
### Listeners
Contrary to an event, a listener is:
* **Synchronous** when registering, because the observable must exist before
observers can observe,
* **Identified** when using, because the observable knows how many observers
are observing,
* It aims at a **close** diffusion of data. The observers must have an access
to the observable to observe.
The `Hoa\Event\Listenable` interface requires the `on` method to be present to
register a listener to a listener ID. For instance, the following example
listens the `message` listener ID, i.e. when a message is received by the
WebSocket server, the closure is executed:
```php
$server = new Hoa\Websocket\Server(…);
$server->on('message', function (Hoa\Event\Bucket $bucket) {
var_dump(
$bucket->getSource(),
$bucket->getData()
);
});
```
## Documentation
The
[hack book of `Hoa\Event`](https://central.hoa-project.net/Documentation/Library/Event) contains
detailed information about how to use this library and how it works.
To generate the documentation locally, execute the following commands:
```sh
$ composer require --dev hoa/devtools
$ vendor/bin/hoa devtools:documentation --open
```
More documentation can be found on the project's website:
[hoa-project.net](https://hoa-project.net/).
## Getting help
There are mainly two ways to get help:
* On the [`#hoaproject`](https://webchat.freenode.net/?channels=#hoaproject)
IRC channel,
* On the forum at [users.hoa-project.net](https://users.hoa-project.net).
## Contribution
Do you want to contribute? Thanks! A detailed [contributor
guide](https://hoa-project.net/Literature/Contributor/Guide.html) explains
everything you need to know.
## License
Hoa is under the New BSD License (BSD-3-Clause). Please, see
[`LICENSE`](https://hoa-project.net/LICENSE) for details.
Source.php 0000666 00000003540 13371317246 0006532 0 ustar 00 when($result = new SUT('foo'))
->then
->object($result)
->isInstanceOf('Hoa\Event\Bucket')
->string($result->getData())
->isEqualTo('foo');
}
public function case_send()
{
$self = $this;
$this
->given(
$eventId = 'hoa://Event/Test',
$source = new \Mock\Hoa\Event\Source(),
LUT::register($eventId, $source),
$bucket = new SUT('foo'),
LUT::getEvent($eventId)->attach(
function (SUT $receivedBucket) use ($self, $bucket, &$called) {
$called = true;
$self
->object($receivedBucket)
->isIdenticalTo($bucket);
}
)
)
->when($result = $bucket->send($eventId, $source))
->then
->variable($result)
->isNull()
->boolean($called)
->isTrue();
}
public function case_set_source()
{
$this
->given(
$bucket = new SUT(),
$sourceA = new \Mock\Hoa\Event\Source()
)
->when($result = $bucket->setSource($sourceA))
->then
->variable($result)
->isNull()
->object($bucket->getSource())
->isIdenticalTo($sourceA)
->given($sourceB = new \Mock\Hoa\Event\Source())
->when($result = $bucket->setSource($sourceB))
->then
->object($result)
->isIdenticalTo($sourceA)
->object($bucket->getSource())
->isIdenticalTo($sourceB);
}
public function case_set_data()
{
$this
->given(
$bucket = new SUT(),
$datumA = 'foo'
)
->when($result = $bucket->setData($datumA))
->then
->variable($result)
->isNull()
->string($bucket->getData())
->isEqualTo($datumA)
->given($datumB = 'bar')
->when($result = $bucket->setData($datumB))
->then
->string($result)
->isEqualTo($datumA)
->string($bucket->getData())
->isEqualTo($datumB);
}
}
Test/Unit/Event.php 0000666 00000022470 13371317246 0010214 0 ustar 00 given($eventId = 'hoa://Event/Test')
->when($result = SUT::getEvent($eventId))
->then
->object($result)
->isInstanceOf('Hoa\Event\Event')
->object(SUT::getEvent($eventId))
->isIdenticalTo($result);
}
public function case_register_source_instance()
{
$this
->given(
$eventId = 'hoa://Event/Test',
$source = new \Mock\Hoa\Event\Source()
)
->when($result = SUT::register($eventId, $source))
->then
->variable($result)
->isNull()
->boolean(SUT::eventExists($eventId))
->isTrue();
}
public function case_register_source_name()
{
$this
->given(
$eventId = 'hoa://Event/Test',
$source = 'Mock\Hoa\Event\Source'
)
->when($result = SUT::register($eventId, $source))
->then
->variable($result)
->isNull()
->boolean(SUT::eventExists($eventId))
->isTrue();
}
public function case_register_redeclare()
{
$this
->given(
$eventId = 'hoa://Event/Test',
$source = new \Mock\Hoa\Event\Source(),
SUT::register($eventId, $source)
)
->exception(function () use ($eventId, $source) {
SUT::register($eventId, $source);
})
->isInstanceOf('Hoa\Event\Exception');
}
public function case_register_not_a_source_instance()
{
$this
->given(
$eventId = 'hoa://Event/Test',
$source = new \StdClass()
)
->exception(function () use ($eventId, $source) {
$result = SUT::register($eventId, $source);
})
->isInstanceOf('Hoa\Event\Exception');
}
public function case_register_not_a_source_name()
{
$this
->given(
$eventId = 'hoa://Event/Test',
$source = 'StdClass'
)
->exception(function () use ($eventId, $source) {
$result = SUT::register($eventId, $source);
})
->isInstanceOf('Hoa\Event\Exception');
}
public function case_unregister()
{
$this
->given(
$eventId = 'hoa://Event/Test',
$source = new \Mock\Hoa\Event\Source(),
SUT::register($eventId, $source)
)
->when($result = SUT::unregister($eventId))
->then
->boolean(SUT::eventExists($eventId))
->isFalse();
}
public function case_unregister_hard()
{
$this
->given(
$eventId = 'hoa://Event/Test',
$source = new \Mock\Hoa\Event\Source(),
SUT::register($eventId, $source),
$event = SUT::getEvent($eventId)
)
->when($result = SUT::unregister($eventId, true))
->then
->boolean(SUT::eventExists($eventId))
->isFalse()
->object(SUT::getEvent($eventId))
->isNotIdenticalTo($event);
}
public function case_unregister_not_registered()
{
$this
->given($eventId = 'hoa://Event/Test')
->when($result = SUT::unregister($eventId))
->then
->variable($result)
->isNull();
}
public function case_attach()
{
$this
->given(
$event = SUT::getEvent('hoa://Event/Test'),
$callable = function () { }
)
->when($result = $event->attach($callable))
->then
->object($result)
->isIdenticalTo($event)
->boolean($event->isListened())
->isTrue();
}
public function case_detach()
{
$this
->given(
$event = SUT::getEvent('hoa://Event/Test'),
$callable = function () { },
$event->attach($callable)
)
->when($result = $event->detach($callable))
->then
->object($result)
->isIdenticalTo($event)
->boolean($event->isListened())
->isFalse();
}
public function case_detach_unattached()
{
$this
->given(
$event = SUT::getEvent('hoa://Event/Test'),
$callable = function () { }
)
->when($result = $event->detach($callable))
->then
->object($result)
->isIdenticalTo($event)
->boolean($event->isListened())
->isFalse();
}
public function case_is_listened()
{
$this
->given($event = SUT::getEvent('hoa://Event/Test'))
->when($result = $event->isListened())
->then
->boolean($event->isListened())
->isFalse();
}
public function case_notify()
{
$self = $this;
$this
->given(
$eventId = 'hoa://Event/Test',
$source = new \Mock\Hoa\Event\Source(),
$bucket = new LUT\Bucket(),
SUT::register($eventId, $source),
SUT::getEvent($eventId)->attach(
function (LUT\Bucket $receivedBucket) use ($self, $source, $bucket, &$called) {
$called = true;
$this
->object($receivedBucket)
->isIdenticalTo($bucket)
->object($receivedBucket->getSource())
->isIdenticalTo($source);
}
)
)
->when($result = SUT::notify($eventId, $source, $bucket))
->then
->variable($result)
->isNull()
->boolean($called)
->isTrue();
}
public function case_notify_unregistered_event_id()
{
$this
->given(
$eventId = 'hoa://Event/Test',
$source = new \Mock\Hoa\Event\Source(),
$data = new LUT\Bucket()
)
->exception(function () use ($eventId, $source, $data) {
SUT::notify($eventId, $source, $data);
})
->isInstanceOf('Hoa\Event\Exception');
}
public function case_event_exists()
{
$this
->given(
$eventId = 'hoa://Event/Test',
$source = new \Mock\Hoa\Event\Source(),
SUT::register($eventId, $source)
)
->when($result = SUT::eventExists($eventId))
->then
->boolean($result)
->isTrue();
}
public function case_event_not_exists()
{
$this
->given($eventId = 'hoa://Event/Test')
->when($result = SUT::eventExists($eventId))
->then
->boolean($result)
->isFalse();
}
}
Test/Unit/Exception.php 0000666 00000004176 13371317246 0011074 0 ustar 00 when($result = new SUT('foo', 0))
->then
->object($result)
->isInstanceOf('Hoa\Exception\Exception');
}
}
Test/Unit/Listenable.php 0000666 00000004163 13371317246 0011214 0 ustar 00 when($result = new \Mock\Hoa\Event\Listenable())
->then
->object($result)
->isInstanceOf('Hoa\Event\Listenable');
}
}
Test/Unit/Listener.php 0000666 00000020000 13371317246 0010703 0 ustar 00 given(
$source = new \Mock\Hoa\Event\Listenable(),
$ids = ['foo', 'bar', 'baz']
)
->when($result = new SUT($source, $ids))
->then
->object($result)
->isInstanceOf('Hoa\Event\Listener')
->boolean($result->listenerExists('foo'))
->isTrue()
->boolean($result->listenerExists('bar'))
->isTrue()
->boolean($result->listenerExists('baz'))
->isTrue();
}
public function case_attach()
{
$this
->given(
$source = new \Mock\Hoa\Event\Listenable(),
$listenerId = 'foo',
$listener = new SUT($source, ['foo', 'bar']),
$callable = function () {
return 42;
}
)
->when($result = $listener->attach($listenerId, $callable))
->then
->object($result)
->isIdenticalTo($listener)
->array($listener->fire($listenerId, new LUT\Bucket()))
->isEqualTo([42]);
}
public function case_attach_to_an_undefined_listener()
{
$this
->given(
$source = new \Mock\Hoa\Event\Listenable(),
$listenerId = 'bar',
$listener = new SUT($source, ['foo', 'baz']),
$callable = function () { }
)
->exception(function () use ($listener, $listenerId, $callable) {
$listener->attach($listenerId, $callable);
})
->isInstanceOf('Hoa\Event\Exception');
}
public function case_detach()
{
$this
->given(
$source = new \Mock\Hoa\Event\Listenable(),
$listenerId = 'foo',
$listener = new SUT($source, ['foo', 'bar']),
$callable = function () {
return 42;
},
$listener->attach($listenerId, $callable)
)
->when($result = $listener->detach($listenerId, $callable))
->then
->object($result)
->isIdenticalTo($listener)
->array($listener->fire($listenerId, new LUT\Bucket()))
->isEmpty();
}
public function case_detach_an_undefined_listener()
{
$this
->given(
$source = new \Mock\Hoa\Event\Listenable(),
$listenerId = 'bar',
$listener = new SUT($source, ['foo', 'baz']),
$callable = function () { }
)
->when($result = $listener->detach($listenerId, $callable))
->then
->object($result)
->isIdenticalTo($listener);
}
public function case_detach_all()
{
$this
->given(
$source = new \Mock\Hoa\Event\Listenable(),
$listenerId = 'foo',
$listener = new SUT($source, ['foo', 'bar'])
)
->when($result = $listener->detachAll($listenerId))
->then
->object($result)
->isIdenticalTo($listener)
->boolean($listener->listenerExists($listenerId))
->isFalse();
}
public function case_detach_all_with_an_undefined_listener()
{
$this
->given(
$source = new \Mock\Hoa\Event\Listenable(),
$listenerId = 'bar',
$listener = new SUT($source, ['foo', 'baz'])
)
->when($result = $listener->detachAll($listenerId))
->then
->object($result)
->isIdenticalTo($listener);
}
public function case_listener_exists()
{
$this
->given(
$source = new \Mock\Hoa\Event\Listenable(),
$ids = [],
$listener = new SUT($source, $ids)
)
->when($listener->addIds(['foo']))
->then
->boolean($listener->listenerExists('foo'))
->isTrue()
->boolean($listener->listenerExists('bar'))
->isFalse()
->when($listener->addIds(['bar']))
->then
->boolean($listener->listenerExists('bar'))
->isTrue();
}
public function case_fire()
{
$self = $this;
$this
->given(
$source = new \Mock\Hoa\Event\Listenable(),
$ids = ['foo', 'bar'],
$listener = new SUT($source, $ids),
$listenerId = 'foo',
$bucket = new LUT\Bucket(),
$listener->attach(
$listenerId,
function (LUT\Bucket $receivedBucket) use ($self, $bucket, $source, &$called) {
$called = true;
$self
->object($receivedBucket)
->isIdenticalTo($bucket)
->object($receivedBucket->getSource())
->isIdenticalTo($source);
return 42;
}
)
)
->when($result = $listener->fire($listenerId, $bucket))
->then
->array($result)
->isEqualTo([42])
->boolean($called)
->isTrue();
}
public function case_fire_an_undefined_listenerId()
{
$this
->given(
$source = new \Mock\Hoa\Event\Listenable(),
$ids = [],
$listener = new SUT($source, $ids)
)
->exception(function () use ($listener) {
$listener->fire('foo', new LUT\Bucket());
})
->isInstanceOf('Hoa\Event\Exception');
}
}
Test/Unit/Listens.php 0000666 00000010374 13371317246 0010554 0 ustar 00 given(
$listenable = new _Listenable(),
$listener = new LUT\Listener($listenable, ['foo'])
)
->when($result = $listenable->_setListener($listener))
->then
->variable($result)
->isNull();
}
public function case_get_listener()
{
$this
->given(
$listenable = new _Listenable(),
$listener = new LUT\Listener($listenable, ['foo']),
$listenable->_setListener($listener)
)
->when($result = $listenable->_getListener())
->then
->object($result)
->isIdenticalTo($listener);
}
public function case_on()
{
$this
->given(
$listenable = new _Listenable(),
$listener = new LUT\Listener($listenable, ['foo']),
$listenable->_setListener($listener),
$callable = function () use (&$called) {
$called = true;
return 42;
}
)
->when($result = $listenable->on('foo', $callable))
->then
->object($result)
->isIdenticalTo($listenable)
->when($listenable->doSomethingThatFires())
->then
->boolean($called)
->isTrue();
}
public function case_on_unregistered_listener()
{
$this
->given(
$listenable = new _Listenable(),
$listener = new LUT\Listener($listenable, ['foo']),
$listenable->_setListener($listener)
)
->exception(function () use ($listenable) {
$listenable->on('bar', null);
})
->isInstanceOf('Hoa\Event\Exception');
}
}
class _Listenable implements LUT\Listenable
{
use SUT;
public function _setListener(LUT\Listener $listener)
{
return $this->setListener($listener);
}
public function _getListener()
{
return $this->getListener();
}
public function doSomethingThatFires()
{
$this->getListener()->fire('foo', new LUT\Bucket('bar'));
return;
}
}
Test/Unit/Source.php 0000666 00000004137 13371317246 0010373 0 ustar 00 when($result = new \Mock\Hoa\Event\Source())
->then
->object($result)
->isInstanceOf('Hoa\Event\Source');
}
}
composer.json 0000666 00000002223 13371317246 0007300 0 ustar 00 {
"name" : "hoa/event",
"description": "The Hoa\\Event library.",
"type" : "library",
"keywords" : ["library", "event", "listener", "observer"],
"homepage" : "https://hoa-project.net/",
"license" : "BSD-3-Clause",
"authors" : [
{
"name" : "Ivan Enderlin",
"email": "ivan.enderlin@hoa-project.net"
},
{
"name" : "Hoa community",
"homepage": "https://hoa-project.net/"
}
],
"support": {
"email" : "support@hoa-project.net",
"irc" : "irc://chat.freenode.net/hoaproject",
"forum" : "https://users.hoa-project.net/",
"docs" : "https://central.hoa-project.net/Documentation/Library/Event",
"source": "https://central.hoa-project.net/Resource/Library/Event"
},
"require": {
"hoa/consistency": "~1.0",
"hoa/exception" : "~1.0"
},
"require-dev": {
"hoa/test": "~2.0"
},
"autoload": {
"psr-4": {
"Hoa\\Event\\": "."
}
},
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
}
}