PHP Classes

File: specs/Spec/PimpleContainerMediatorSpec.php

Recommend this page to a friend!
  Classes of Michael Cummings  >  PHP Event Mediator  >  specs/Spec/PimpleContainerMediatorSpec.php  >  Download  
File: specs/Spec/PimpleContainerMediatorSpec.php
Role: Unit test script
Content type: text/plain
Description: Unit test script
Class: PHP Event Mediator
Emit and listen to events using a mediator object
Author: By
Last change: Added global NS to build-in functions and constants using PHP BackSlasher for possible performance gain. See https://veewee.github.io/blog/optimizing-php-performance-by-fq-function-calls/ and https://github.com/nilportugues/php-backslasher for details.
Date: 3 years ago
Size: 18,567 bytes
 

Contents

Class file image Download
<?php
declare(strict_types = 1);
/**
 * Contains PhpSpec PimpleContainerMediatorSpec class.
 *
 * PHP version 7.0
 *
 * LICENSE:
 * This file is part of Event Mediator - A general event mediator (dispatcher)
 * which has minimal dependencies so it is easy to drop in and use.
 * Copyright (C) 2015-2016 Michael Cummings
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, you may write to
 *
 * Free Software Foundation, Inc.
 * 59 Temple Place, Suite 330
 * Boston, MA 02111-1307 USA
 *
 * or find a electronic copy at
 * <http://spdx.org/licenses/GPL-2.0.html>.
 *
 * You should also be able to find a copy of this license in the included
 * LICENSE file.
 *
 * @author    Michael Cummings <mgcummings@yahoo.com>
 * @copyright 2015-2016 Michael Cummings
 * @license   GPL-2.0
 */
namespace Spec\EventMediator;

use EventMediator\Event;
use PhpSpec\ObjectBehavior;
use Pimple\Container;
use Prophecy\Argument;

/**
 * Class PimpleContainerMediatorSpec
 *
 * @mixin \EventMediator\PimpleContainerMediator
 *
 * @method void shouldImplement($interface)
 * @method void shouldHaveListeners()
 * @method void shouldNotHaveListeners()
 * @method void shouldReturn($result)
 * @method void duringAddServiceListener()
 * @method void duringGetServiceListeners($value)
 * @method void duringRemoveServiceListener()
 * @method void duringTrigger()
 * @method void willReturn($result)
 */
class PimpleContainerMediatorSpec extends ObjectBehavior
{
    public function it_is_initializable()
    {
        $this->shouldHaveType('\\EventMediator\\PimpleContainerMediator');
        $this->shouldImplement('\\EventMediator\\ContainerMediatorInterface');
    }
    public function it_provides_fluent_interface_from_add_service_listener()
    {
        $this->addServiceListener('test', ['\DummyClass', 'method1'])
             ->shouldReturn($this);
    }
    public function it_provides_fluent_interface_from_add_service_subscriber(MockServiceSubscriber $sub)
    {
        $events = [
            'test1' => [
                [
                    [
                        'containerID1',
                        'method1'
                    ]
                ]
            ]
        ];
        $sub->getServiceSubscribedEvents()
            ->willReturn($events);
        $this->addServiceSubscriber($sub)
             ->shouldReturn($this);
    }
    public function it_provides_fluent_interface_from_remove_service_listener()
    {
        $this->removeServiceListener('test', ['\DummyClass', 'method1'])
             ->shouldReturn($this);
    }
    public function it_provides_fluent_interface_from_remove_service_subscriber(MockServiceSubscriber $sub)
    {
        $events = [
            'test1' => [
                [
                    [
                        'containerID1',
                        'method1'
                    ]
                ]
            ]
        ];
        $sub->getServiceSubscribedEvents()
            ->willReturn($events);
        $this->addServiceSubscriber($sub);
        $this->removeServiceSubscriber($sub)
             ->shouldReturn($this);
    }
    public function it_returns_empty_array_before_any_service_listeners_added()
    {
        $this->getServiceListeners()
             ->shouldHaveCount(0);
    }
    public function it_returns_empty_array_when_event_has_no_service_listeners()
    {
        $this->addServiceListener('test2', ['ContainerID1', 'method1'])
             ->getServiceListeners('test1')
             ->shouldHaveCount(0);
    }
    /**
     * @param MockListener $listener
     * @param Event        $event
     * @param Container    $container
     *
     * @throws \DomainException
     * @throws \InvalidArgumentException
     */
    public function it_should_call_service_listeners_for_their_events_when_event_is_triggered(
        MockListener $listener,
        Event $event,
        Container $container
    ) {
        $event->hasBeenHandled()
              ->willReturn(\false);
        $this->addServiceListener('test1', ['ContainerID1', 'method1']);
        $this->getServiceListeners()
             ->shouldHaveKey('test1');
        $container->offsetGet('ContainerID1')
                  ->willReturn($listener);
        $this->setServiceContainer($container);
        $listener->method1($event, 'test1', $this)
                 ->shouldBeCalled();
        $this->trigger('test1', $event);
    }
    /** @noinspection MoreThanThreeArgumentsInspection */
    /**
     * @param MockListener          $listener
     * @param Event                 $event
     * @param Container             $container
     * @param MockServiceSubscriber $sub
     *
     * @throws \DomainException
     * @throws \InvalidArgumentException
     * @throws \LengthException
     * @throws \LogicException
     */
    public function it_should_call_service_subscribers_for_their_events_when_event_is_triggered(
        MockListener $listener,
        Event $event,
        Container $container,
        MockServiceSubscriber $sub
    ) {
        $events = [
            'test1' => [
                [
                    [
                        'containerID1',
                        'method1'
                    ]
                ]
            ]
        ];
        $event->hasBeenHandled()
              ->willReturn(\false);
        $listener->method1($event, 'test1', $this)
                 ->willReturn($event);
        $sub->getServiceSubscribedEvents()
            ->willReturn($events);
        $this->addServiceSubscriber($sub);
        $this->getServiceListeners()
             ->shouldHaveKey('test1');
        $container->offsetGet('containerID1')
                  ->willReturn($listener);
        $this->setServiceContainer($container);
        $listener->method1($event, 'test1', $this)
                 ->shouldBeCalled();
        $this->getServiceByName('containerID1')
             ->shouldReturn($listener);
        $this->trigger('test1', $event);
    }
    public function it_should_have_less_service_listeners_if_one_is_removed()
    {
        $listeners = [
            ['event1', 'containerID1', 'method1', 0],
            ['event1', 'containerID1', 'method1', 'first'],
            ['event2', 'containerID1', 'method1', 0]
        ];
        foreach ($listeners as $listener) {
            list($event, $containerID, $method, $priority) = $listener;
            $this->addServiceListener($event, [$containerID, $method], $priority);
        }
        $this->getServiceListeners()
             ->shouldHaveCount(2);
        $this->getServiceListeners()
             ->shouldHaveKey('event1');
        $this->getServiceListeners()
             ->shouldHaveKey('event2');
        $this->getServiceListeners('event1')
             ->shouldHaveCount(2);
        $this->removeServiceListener('event1', ['containerID1', 'method1'], 'first');
        $this->getServiceListeners('event1')
             ->shouldHaveCount(1);
        $this->removeServiceListener('event1', ['containerID1', 'method1']);
        $this->getServiceListeners('event1')
             ->shouldHaveCount(0);
        $this->getServiceListeners()
             ->shouldHaveCount(1);
    }
    /**
     * @param MockServiceSubscriber $sub
     *
     * @throws \DomainException
     * @throws \InvalidArgumentException
     * @throws \LengthException
     */
    public function it_should_have_listener_after_adding_service_subscriber(MockServiceSubscriber $sub)
    {
        $events = [
            'test1' => [
                [
                    [
                        'containerID1',
                        'method1'
                    ],
                    [
                        'containerID1',
                        'method2'
                    ]
                ]
            ],
            'test2' => [
                [
                    [
                        'containerID1',
                        'method1'
                    ],
                    [
                        'containerID1',
                        'method2'
                    ]
                ]
            ]
        ];
        $this->getServiceListeners()
             ->shouldHaveCount(0);
        $sub->getServiceSubscribedEvents()
            ->willReturn($events);
        $this->addServiceSubscriber($sub);
        $this->getServiceListeners()
             ->shouldHaveCount(2);
        $this->getServiceListeners()
             ->shouldHaveKey('test1');
        $this->getServiceListeners()
             ->shouldHaveKey('test2');
    }
    /**
     * @param MockServiceSubscriber $sub
     *
     * @throws \DomainException
     * @throws \InvalidArgumentException
     * @throws \LengthException
     */
    public function it_should_have_no_service_listeners_if_only_service_subscriber_is_removed(
        MockServiceSubscriber $sub
    ) {
        $events = [
            'test1' => [
                [
                    [
                        'containerID1',
                        'method1'
                    ],
                    [
                        'containerID1',
                        'method2'
                    ]
                ]
            ],
            'test2' => [
                'last' => [
                    [
                        'containerID1',
                        'method1'
                    ]
                ],
                [
                    [
                        'containerID1',
                        'method2'
                    ]
                ]
            ],
            'test3' => [
                [
                    [
                        'containerID1',
                        'method1'
                    ]
                ]
            ]
        ];
        $sub->getServiceSubscribedEvents()
            ->willReturn($events);
        $this->addServiceSubscriber($sub);
        $this->getServiceListeners()
             ->shouldHaveCount(3);
        $this->removeServiceSubscriber($sub);
        $this->getServiceListeners()
             ->shouldHaveCount(0);
    }
    public function it_should_ignore_duplicate_service_listeners_for_the_same_event_and_priority()
    {
        $this->addServiceListener(
            'event',
            ['\Spec\EventMediator\MockListener', 'method1']
        );
        $this->addServiceListener(
            'event',
            ['\Spec\EventMediator\MockListener', 'method1']
        );
        $this->getServiceListeners('event')
             ->shouldHaveCount(1);
    }
    /**
     * @param MockListener $listener1
     * @param MockListener $listener2
     * @param Event        $event
     *
     * @throws \DomainException
     * @throws \InvalidArgumentException
     */
    public function it_should_only_call_listeners_for_current_events_when_event_triggers(
        MockListener $listener1,
        MockListener $listener2,
        Event $event
    ) {
        $this->addListener('test1', [$listener1, 'method1']);
        $this->addListener('test2', [$listener2, 'method2']);
        $this->getListeners()
             ->shouldHaveKey('test1');
        $this->getListeners()
             ->shouldHaveKey('test2');
        $event->hasBeenHandled()
              ->willReturn(\true);
        /** @noinspection PhpStrictTypeCheckingInspection */
        $listener2->method2($event, Argument::is('test2'), $this)
                  ->shouldBeCalled();
        /** @noinspection PhpStrictTypeCheckingInspection */
        $listener1->method1($event, Argument::any(), $this)
                  ->shouldNotHaveBeenCalled();
        $this->trigger('test2', $event);
    }
    public function it_should_return_all_listeners_if_event_name_is_empty(MockListener $listener)
    {
        $listeners = [
            ['event1', $listener, 'method1', 'first'],
            ['event2', $listener, 'method1', 0],
            ['event2', $listener, 'method1', 'first']
        ];
        foreach ($listeners as $aListener) {
            list($event, $object, $method, $priority) = $aListener;
            $this->addListener($event, [$object, $method], $priority);
        }
        $this->getListeners()
             ->shouldHaveCount(2);
        $this->getListeners()
             ->shouldHaveKey('event1');
        $this->getListeners()
             ->shouldHaveKey('event2');
    }
    /** @noinspection MoreThanThreeArgumentsInspection */
    /**
     * @param MockListener          $listener
     * @param Event                 $event
     * @param Container             $container
     * @param MockServiceSubscriber $sub
     *
     * @throws \DomainException
     * @throws \InvalidArgumentException
     * @throws \LengthException
     * @throws \LogicException
     */
    public function it_should_still_allow_service_subscriber_to_be_removed_after_event_has_been_triggered(
        MockListener $listener,
        Event $event,
        Container $container,
        MockServiceSubscriber $sub
    ) {
        $events = [
            'test1' => [
                [
                    [
                        'containerID1',
                        'method1'
                    ]
                ]
            ]
        ];
        $event->hasBeenHandled()
              ->willReturn(\false);
        $sub->getServiceSubscribedEvents()
            ->willReturn($events);
        $this->addServiceSubscriber($sub);
        $this->getServiceListeners()
             ->shouldHaveKey('test1');
        $container->offsetGet('containerID1')
                  ->willReturn($listener);
        $this->setServiceContainer($container);
        $listener->method1($event, 'test1', $this)
                 ->shouldBeCalled();
        $this->getServiceByName('containerID1')
             ->shouldReturn($listener);
        $this->trigger('test1', $event);
        $this->removeServiceSubscriber($sub);
        $this->getServiceListeners()
             ->shouldNotHaveKey('test1');
    }
    public function it_throws_exception_for_badly_formed_listener_when_trying_to_add_service_listener()
    {
        $mess = 'Service listener form MUST be ["containerID", "methodName"]';
        $this->shouldThrow(new \InvalidArgumentException($mess))
             ->during('addServiceListener', ['test', ['methodName']]);
    }
    public function it_throws_exception_for_empty_event_name_when_adding_service_listener()
    {
        $mess = 'Event name can NOT be empty';
        $this->shouldThrow(new \DomainException($mess))
             ->during('addServiceListener', ['', ['\DummyClass', 'method1']]);
    }
    public function it_throws_exception_for_empty_event_name_when_removing_service_listener()
    {
        $mess = 'Event name can NOT be empty';
        $this->shouldThrow(new \DomainException($mess))
             ->during('removeServiceListener', ['', ['\DummyClass', 'method1']]);
    }
    public function it_throws_exception_for_empty_listener_class_name_when_trying_to_add_service_listener()
    {
        $mess = 'Using any non-printable characters in the container ID is NOT allowed';
        $this->shouldThrow(new \InvalidArgumentException($mess))
             ->during('addServiceListener', ['test', ['', 'test1']]);
    }
    public function it_throws_exception_for_empty_listener_method_name_when_trying_to_add_service_listener()
    {
        $mess = 'Service listener method name format is invalid, was given ';
        $this->shouldThrow(new \InvalidArgumentException($mess))
             ->during('addServiceListener', ['test', ['\DummyClass', '']]);
    }
    /**
     * @param MockSubscriber $sub
     */
    public function it_throws_exception_for_incorrect_service_container_type_when_trying_to_set_container(
        MockSubscriber $sub
    ) {
        $mess = \sprintf(
            'Must be an instance of Pimple Container but given %s',
            \gettype($sub)
        );
        $this->shouldThrow(new \InvalidArgumentException($mess))
             ->during('setServiceContainer', [$sub]);
    }
    public function it_throws_exception_for_invalid_listener_types_when_trying_to_add_service_listener()
    {
        $listeners = [
            [123, 'method1'],
            [\true, 'method1'],
            [\null, 'method1']
        ];
        $mess = 'Service listener container ID MUST be a string, but was given ';
        foreach ($listeners as $listener) {
            list($class, $method) = $listener;
            $this->shouldThrow(new \InvalidArgumentException($mess . \gettype($class)))
                 ->during('addServiceListener', ['test', [$class, $method]]);
        }
    }
    public function it_throws_exception_for_non_string_listener_method_name_when_trying_to_add_service_listener()
    {
        $messages = [
            'array' => [],
            'integer' => 0,
            'NULL' => \null
        ];
        foreach ($messages as $mess => $methodName) {
            $mess = 'Service listener method name MUST be a string, but was given ' . $mess;
            $this->shouldThrow(new \InvalidArgumentException($mess))
                 ->during('addServiceListener', ['test', ['\DummyClass', $methodName]]);
        }
    }
    public function it_throws_exception_for_non_string_listener_method_name_when_trying_to_remove_service_listener()
    {
        $this->addServiceListener('test', ['\DummyClass', 'method1']);
        $messages = [
            'array' => [],
            'integer' => 0,
            'NULL' => \null
        ];
        foreach ($messages as $mess => $methodName) {
            $mess = 'Service listener method name MUST be a string, but was given ' . $mess;
            $this->shouldThrow(new \InvalidArgumentException($mess))
                 ->during('removeServiceListener', ['test', ['\DummyClass', $methodName]]);
        }
    }
    public function it_throws_exception_for_unknown_priorities_when_trying_to_add_service_listener()
    {
        $mess = 'Unknown priority was given only "first", "last", or integer may be used';
            $this->shouldThrow(new \InvalidArgumentException($mess))
                 ->during('addServiceListener', ['test', ['\DummyClass', 'method1'], 'Yoo!']);
    }
}
For more information send a message to info at phpclasses dot org.