PHPUnit: Testován přítomnosti listeneru v eventech potomků Nette\Object

před 7 lety

Filip Procházka
Moderator | 4693
+
0
-

Ahoj, právě jsem si potřeboval otestovat, že objekt má událost a v ní cíl, který potřebuju. Třeba by se to mohlo hodit :)

/**
 * @author Filip Procházka
 */
class Test extends \PHPUnit_Framework_TestCase
{

    /**
     * @param array|\Nette\Callback|\Closure $callback
     * @param Nette\Object $object
     * @param string $eventName
     */
    public function assertEventHasCallback($callback, $object, $eventName)
    {
        $this->assertInstanceOf('Nette\Object', $object, 'Object supports events');
        $this->assertObjectHasAttribute($eventName, $object, 'Object has event');

        $event = $object->$eventName;
        $this->assertNotEmpty($event, 'Event contains listeners');

        if (is_array($callback)) {
            $this->assertContainsOnly('array', $event, TRUE, 'Event contains only arrays');

        } elseif ($callback instanceof Nette\Callback) {
            $this->assertContainsOnly('Nette\Callback', $event, FALSE, 'Event contains only instances of Nette\Callback');
        }

        $targetIndex = array_search($callback, $event);
        $this->assertNotNull($targetIndex, 'Similar listener is in event');
        $target = $event[$targetIndex];

        if (is_array($callback)) {
            $this->assertNotNull($target[0]);
            $this->assertSame($callback[0], $target[0], 'Target matches');

            if (isset($callback[1])) {
                $this->assertNotNull($target[1]);
                $this->assertSame($callback[1], $target[1], 'Target matches');
            }
        }

        if ($callback instanceof Nette\Callback) {
            $this->assertNotNull($target->native[0]);
            $this->assertSame($callback->native[0], $target->native[0], 'Target matches');

            if (isset($callback->native[1])) {
                $this->assertNotNull($target->native[1]);
                $this->assertSame($callback->native[1], $target->native[1], 'Target matches');
            }
        }
    }

}

Takto striktní je to schválně. A pak v testu

$this->assertEventHasCallback(callback($targetObject, 'Metoda'), $objectWithEvent, 'onSomething');

// pokud máte averzi vůči Nette\Callback
$this->assertEventHasCallback(array($targetObject, 'Metoda'), $objectWithEvent, 'onSomething');

Aktualizovaná verze buderepozitáři Kdyby na githubu

Kdyby si někdo všiml chybku, nebo mu tam něco chybělo, budu rád za odezvu :)

Editoval HosipLan (12. 7. 2011 16:51)

před 7 lety

Patrik Votoček
Člen | 2249
+
0
-

vypadá to dobře příští týden to testnu :-)

možná bych si pohrál s Foo::bar vs array('Foo', 'bar').

$objectWithEvent->onSomething[] = "Foo::bar";

$this->assertEventHasCallback(array('Foo', 'bar'), $objectWithEvent, 'onSomething'); //Fail i když je to OK

před 7 lety

Filip Procházka
Moderator | 4693
+
0
-

Přemýšlel jsem nad tím a přijde mi to až moc komplikované, řešit všechny možnosti. Pokud to dopíšeš tak se zlobit nebudu, ale já to nepotřebuju :)

před 7 lety

David Grudl
Nette Core | 6786
+
0
-

Nejjednodušší je testovat (string) callback(...), tím se to normalizuje.