<?php

Mock::generate('Wact_Event_CallbackTester');

class WactNotifierTestCase extends Wact_Test_Case {

    function testAddListenerPsuedoType() {
        $mock = new MockWact_Event_CallbackTester($this);
        $mock->expectOnce('doInstance', array());
        
        $notifier = new Wact_Event_Notifier();
        $notifier->addListener(array($mock, 'doInstance'));
        $notifier->notify();
        
        $mock->tally();
    }

    function testAddListenerCallback() {
        $mock = new MockWact_Event_CallbackTester($this);
        $mock->expectOnce('doInstance', array());
        
        $notifier = new Wact_Event_Notifier();
        $notifier->addListener(array($mock, 'doInstance'));
        $notifier->notify();
        
        $mock->tally();
    }

    function testNotifyMulticast() {
        $arg = TRUE;
        $mock1 = new MockWact_Event_CallbackTester($this);
        $mock1->expectOnce('doInstance', array($arg));

        $mock2 = new MockWact_Event_CallbackTester($this);
        $mock2->expectOnce('doInstance', array($arg));
        
        $notifier = new Wact_Event_Notifier();
        $notifier->addListener(array($mock1, 'doInstance'));
        $notifier->addListener(array($mock2, 'doInstance'));
        $notifier->notify($arg);
        
        $mock1->tally();
        $mock2->tally();
    }

    function testNotifyException() {
        $mock = new MockWact_Event_CallbackTester($this);
        $mock->expectNever('doInstance');

        try {        
            $notifier = new Wact_Event_Notifier();
            $notifier->addListener(array('Wact_Event_CallbackTester', 'raiseException'));
            $notifier->addListener(array($mock, 'doInstance'));
            $notifier->notify();
            $this->fail('Expected exception not thrown');
        } catch (Exception $e) {
            $this->pass();
        }
        
        $mock->tally();
    }

    function testNotifyWithMulticast() {
        $args = array(1, 2, TRUE);
        $mock1 = new MockWact_Event_CallbackTester($this);
        $mock1->expectOnce('doInstance', $args);

        $mock2 = new MockWact_Event_CallbackTester($this);
        $mock2->expectOnce('doInstance', $args);
        
        $notifier = new Wact_Event_Notifier();
        $notifier->addListener(array($mock1, 'doInstance'));
        $notifier->addListener(array($mock2, 'doInstance'));
        $notifier->notifyWith($args);
        
        $mock1->tally();
        $mock2->tally();
    }

    function testNotifyWithException() {
        $args = array(1, 2, TRUE);

        $mock = new MockWact_Event_CallbackTester($this);
        $mock->expectNever('doInstance');

        try {        
            $notifier = new Wact_Event_Notifier();
            $notifier->addListener(array('Wact_Event_CallbackTester', 'raiseException'));
            $notifier->addListener(array($mock, 'doInstance'));
            $notifier->notifyWith($args);
            $this->fail('Expected exception not thrown');
        } catch (Exception $e) {
            $this->pass();
        }
        
        $mock->tally();
    }

    function testNotifyUntil() {
        $args = array(1, 2, TRUE);
        $mock1 = new MockWact_Event_CallbackTester($this);
        $mock1->expectOnce('doInstance', $args);

        $mock2 = new MockWact_Event_CallbackTester($this);
        $mock2->expectNever('doInstance', $args);
        
        $notifier = new Wact_Event_Notifier();
        $notifier->addListener(array($mock1, 'doInstance'));
        $notifier->addListener(array(new Wact_Event_CallbackTester(), 'doInstance'));
        $notifier->addListener(array($mock2, 'doInstance'));
        $result = $notifier->notifyUntil(1, 2, TRUE);
        
        $this->assertIdentical($result, $args);
        
        $mock1->tally();
        $mock2->tally();
    }

    function testNotifyUntilWith() {
        $args = array(1, 2, TRUE);
        $mock1 = new MockWact_Event_CallbackTester($this);
        $mock1->expectOnce('doInstance', $args);

        $mock2 = new MockWact_Event_CallbackTester($this);
        $mock2->expectNever('doInstance', $args);
        
        $notifier = new Wact_Event_Notifier();
        $notifier->addListener(array($mock1, 'doInstance'));
        $notifier->addListener(array(new Wact_Event_CallbackTester(), 'doInstance'));
        $notifier->addListener(array($mock2, 'doInstance'));
        $result = $notifier->notifyUntilWith($args);
        
        $this->assertIdentical($result, $args);
        
        $mock1->tally();
        $mock2->tally();
    }


}

?>