<?php

Mock::generate('Wact_View_Partial', 'MockWact_View_Partial');
Mock::generate('Wact_View_Repeated', 'MockWact_View_Repeated');

abstract class Wact_View_Partial_Test extends Wact_Test_Case {

    /**
    * @var Wact_View_Partial
    */
    public $view;

    function tearDown() {
        unset ( $this->view );
    }

    function testFindChild() {
        $viewId = 'TestChild';
        $child = new Wact_View_Partial();
        $this->view->appendChild($child, $viewId);
        $this->assertIsA($this->view->findChild($viewId), 'Wact_View_Partial');
    }

    function testFindChildNotFound() {
        $this->assertFalse($this->view->findChild('TestChild'));
    }

    function testGetChild() {
        $viewId = 'TestChild';
        $child = new Wact_View_Partial();
        $this->view->appendChild($child, $viewId);
        $this->assertIsA($this->view->getChild($viewId), 'Wact_View_Partial');
    }

    function testGetChildNotFound() {
        $viewId = 'TestChild';
        try {
            $child = $this->view->getChild($viewId);
            $this->fail('Expected exception not thrown');
        } catch (Wact_View_Exception $e) {
            $this->pass();
            $this->assertEqual($e->getViewId(), $viewId);
        }
    }

    function testAppendChild() {
        $child = new Wact_View_Partial();
        $this->view->appendChild($child, 'child');

        $this->assertReference($child->parent, $this->view);
    }

    function testPrependChild() {
        $firstChild = new Wact_View_Partial();
        $this->view->appendChild($firstChild, 'first');
        
        $prependedChild = new Wact_View_Partial();
        $this->view->prependChild($prependedChild, 'no-im-first');
        
        $this->assertEqual(array_keys($this->view->children), array('no-im-first', 'first'));
    }

    function testAddChildDuplicate() {
        $viewId = 'child';

        $child1 = new Wact_View_Partial();
        $child2 = new Wact_View_Partial();

        $this->view->appendChild($child1, $viewId);
        try {
            $this->view->appendChild($child2, $viewId);
            $this->fail('Expected exception not thrown');
        } catch (Wact_View_Exception $e) {
            $this->pass();
            $this->assertEqual($e->getViewId(), $viewId);
        }
    }

    function testArrayAccessGet() {
        $child1 = new Wact_View_Partial();
        $this->view->appendChild($child1, 'TestChild1');
        
        $child2 = new Wact_View_Partial();
        $this->view->appendChild($child2, 'TestChild2');

        // Don't use assertReference because of PHP seg fault / memory leak
        $this->assertTrue($this->view['TestChild1'] === $child1);
        $this->assertTrue($this->view['TestChild2'] === $child2);
    }

    function testArrayAccessGetNotFound() {
        $viewId = 'TestChild';
        try {
            $child = $this->view[$viewId];
            $this->fail('Expected exception not thrown');
        } catch (Wact_View_Exception $e) {
            $this->pass();
            $this->assertEqual($e->getViewId(), $viewId);
        }
    }

    function testArrayAccessSet() {
        $child1 = new Wact_View_Partial();
        $this->view['TestChild1'] = $child1;

        $child2 = new Wact_View_Partial();
        $this->view['TestChild2'] = $child2;

        $child3 = new Wact_View_Partial();
        $this->view[] = $child3;
        
        $viewId = $child3->getViewId();

        // Don't use assertReference because of PHP seg fault / memory leak
        $this->assertTrue($this->view['TestChild1'] === $child1);
        $this->assertTrue($this->view['TestChild2'] === $child2);
        $this->assertTrue($this->view[$viewId] === $child3);
    }

    function testArrayAccessExists() {
        $this->view['TestChild1'] = new Wact_View_Partial();
        $this->view['TestChild2'] = new Wact_View_Partial();

        $this->assertEqual(isset($this->view['TestChild1']), true);
        $this->assertEqual(isset($this->view['TestChild2']), true);
        $this->assertEqual(isset($this->view['TestChild3']), false);
    }

    function testArrayAccessUnSet() {
        $viewId = 'TestChild';

        $this->view[$viewId] = new Wact_View_Partial();

        try {
            unset($this->view[$viewId]);
            $this->fail('Expected exception not thrown');
        } catch (Wact_View_Exception $e) {
            $this->pass();
        }
    }

    function test__getPropertyDoesNotExist() {
        try {
            $prop = $this->view->non_existent_property_name;
            $this->fail('Expected exception not thrown');
        } catch (Wact_Property_Exception_PropertyNotFound $e) {
            $this->pass();
            $this->assertEqual($e->getProperty(), 'non_existent_property_name');
        }
    }

    function test__setPropertyDoesNotExist() {
        try {
            $this->view->non_existent_property_name = FALSE;
            $this->fail('Expected exception not thrown');
        } catch (Wact_Property_Exception_PropertyNotFound $e) {
            $this->pass();
            $this->assertEqual($e->getProperty(), 'non_existent_property_name');
        }

    }

    function testBindScope() {
        $root = new Wact_View_Partial();

        $child = new MockWact_View_Partial($this);
        $child->expectOnce('bindScope', array($root, $root));

        $this->view->appendChild($child);

        $this->view->bindScope($root, $root);

        $this->assertReference($this->view->root, $root);

        $child->tally();
    }
   
    function testSetChildModel() {
        $model = new StdClass();
        $viewId = 'child';
        
        $child = new MockWact_View_Scoped();
        $child->setReturnValue('findChild', $child);
        $child->expectOnce('setModel', array($model));
        
        $this->view[$viewId] = $child;
        
        $this->view->setChildModel($viewId, $model);
        
        $child->tally();
    }

    function testSetChildIterator() {
        $iterator = new StdClass();
        $viewId = 'child';
        
        $child = new MockWact_View_Repeated();
        $child->setReturnValue('findChild', $child);
        $child->expectOnce('setIterator', array($iterator));
        
        $this->view[$viewId] = $child;
        
        $this->view->setChildIterator($viewId, $iterator);
        
        $child->tally();
    }

    function testSetControllerChildren() {
        $controller = new StdClass();
        $viewId = 'child';
        
        $child = new MockWact_View_Partial();
        $child->setReturnValue('findChild', $child);
        $child->expectOnce('setController', array($controller));
        
        $this->view[$viewId] = $child;
        
        $this->view->setController($controller);
        
        $this->assertReference($this->view->controller, $controller);
        
        $child->tally();
    }

    function testSetController() {
        $controller = new StdClass();

        $this->view->setController($controller);
        
        $this->assertReference($this->view->controller, $controller);
    }

    function testRender() {
        $child = new MockWact_View_Partial($this);
        $child->expectOnce('render');

        $this->view->appendChild($child);

        $root = new Wact_View_Partial();
        $this->view->bindScope($root, $root);

        ob_start();
        $this->view->render();
        $output = ob_get_contents();
        ob_end_clean();

        $child->tally();
    }

    function testDataProperty() {
        $root = new Wact_View_Root();
        $root->appendChild($this->view);
        
        $root->bindScope($root, $root);
        
        $this->assertReference($this->view->myScope, $root);
    }

}


?>