<?php

Mock::generate('Wact_Template_Compiler_Node','MockTemplateNode');
Mock::generate('Wact_Html_Sax_Parser','MockHTMLParser');
Mock::generate('Wact_Template_Compiler_Parser_TreeBuilder', 'MockTreeBuilder');

class Wact_Template_Compiler_Parser_TreeBuilderTestCase extends Wact_Test_Case {

    var $component;

    function setUp() {
        $this->component = new MockTemplateNode($this);
        $this->treeBuilder = new Wact_Template_Compiler_Parser_TreeBuilder(NULL);
        $this->treeBuilder->setCursor($this->component);
        $this->treeBuilder->setDocumentLocator(new MockHTMLParser($this));
    }

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

    function testPushNode() {
        $newComponent = new MockTemplateNode($this);

        $this->component->expectOnce('addChild');
        $newComponent->expectOnce('preParse');

        $this->treeBuilder->pushNode($newComponent);

        $this->assertReference($newComponent, $this->treeBuilder->getCursor());
        $this->component->tally();
        $newComponent->tally();
    }

    function testAddNode() {
        $newComponent = new MockTemplateNode($this);

        $this->component->expectOnce('addChild');
        $newComponent->expectOnce('preParse');

        $this->treeBuilder->addNode($newComponent);

        $this->assertReference($this->component, $this->treeBuilder->getCursor());
        $this->component->tally();
    }

    function testAddTextNode() {
        $this->component->expectOnce('addChild');

        $this->treeBuilder->addTextNode('text');

        $this->assertReference($this->component, $this->treeBuilder->getCursor());
        $this->component->tally();
    }

    function testPopNode() {
        $parentComponent = new MockTemplateNode($this);
        $grandParentComponent = new MockTemplateNode($this);
        $parentComponent->parent = $grandParentComponent;
        $this->component->parent = $parentComponent;

        $this->component->setReturnValue('getChildren', array());
        $this->component->expect('setClosing', array(Wact_Template_Compiler_Node::CLOSING_TAG));

        $this->treeBuilder->popNode();
        $treeBuilderCursor = $this->treeBuilder->getCursor();

        $this->assertReference($parentComponent, $treeBuilderCursor);
        $this->assertReference($grandParentComponent,$treeBuilderCursor->parent);
    }

    function testPushAndpopTag() {
        $this->treeBuilder->pushTag('tag1');
        $this->treeBuilder->pushTag('tag2');

        $this->assertEqual($this->treeBuilder->popTag('tag2'), FALSE);

        $this->treeBuilder->popTag('tag2');
    }

    function testCheckViewIds() {
        $root = new Wact_Template_Compiler_Node('testtag', NULL, new Wact_Template_Compiler_Location('file', 123));
        $childOne = new MockTemplateNode($this);
        $childOne->setReturnValue('getChildren', array());
        $childTwo = new MockTemplateNode($this);
        $childTwo->setReturnValue('getChildren', array());
        $root->addChild($childOne);
        $root->addChild($childTwo);

        $childOne->expectOnce('getViewId');
        $childOne->setReturnValue('getViewId', 'id1');
        $childTwo->expectOnce('getViewId');
        $childTwo->setReturnValue('getViewId', 'id2');

        $this->treeBuilder->setCursor($root);
        $this->treeBuilder->checkViewIds();

        $childOne->tally();
        $childTwo->tally();
    }

    function testDuplicateViewIdsError() {
        $root = new Wact_Template_Compiler_Node('testtag', NULL, new Wact_Template_Compiler_Location('file', 123));

        $childOne = new MockTemplateNode($this);
        $childOne->setReturnValue('getChildren', array());
        $childOne->setReturnValue('getViewId', 'dup');
        $root->addChild($childOne);

        $childTwo = new MockTemplateNode($this);
        $childTwo->setReturnValue('getTag', 'testtag');
        $childTwo->setReturnValue('getSourceLocation', new Wact_Template_Compiler_Location('file', 123));
        $childTwo->setReturnValue('getChildren', array());
        $childTwo->setReturnValue('getViewId', 'dup');
        $root->addChild($childTwo);

        $this->treeBuilder->setCursor($root);

        try {
            $this->treeBuilder->checkViewIds();
            $this->fail('Expected exception not thrown');
        } catch (Wact_Template_Compiler_Exception $e) {
            $this->pass();
            $this->assertEqual($e->getTag(), 'testtag');
            $this->assertEqual($e->getViewId(), 'dup');
        }
    }

    function testDuplicateIdIsLegalInDifferentBranch() {
        $root = new Wact_Template_Compiler_Node('testtag', NULL, new Wact_Template_Compiler_Location('file', 123));

        $branch = new Wact_Template_Compiler_Node('testtag', NULL, new Wact_Template_Compiler_Location('file', 123));
        $childOne = new MockTemplateNode($this);
        $childOne->setReturnValue('getChildren', array());
        $branch->addChild($childOne);
        $root->addChild($branch);

        $childTwo = new MockTemplateNode($this);
        $childTwo->setReturnValue('getChildren', array());
        $root->addChild($childTwo);

        $childOne->setReturnValue('getViewId', 'dup');
        $childTwo->setReturnValue('getViewId', 'dup');

        $this->treeBuilder->setCursor($root);
        $this->treeBuilder->checkViewIds();
    }

    function testBuildComponent() {
        $tag = 'test';
        $info = new Wact_Template_Compiler_Generic_Info($tag);

        $node = $this->treeBuilder->buildComponent($info, $tag, array('foo'=>'bar'), Wact_Template_Compiler_Node::CLOSING_NONE);

        $this->assertIsA($node, $info->getName());
        $this->assertEqual($node->getTag(), $tag);
    }

    function testCreateTagComponent() {
        $tag = 'test';
        $info = new Wact_Template_Compiler_Generic_Info($tag);

        $node = $this->treeBuilder->buildComponent($info, $tag, array(), Wact_Template_Compiler_Node::CLOSING_NONE);

        $this->assertIsA($node, $info->getName());
        $this->assertEqual($node->getTag(), $tag);
    }

    /*
    function testAddContent() {
        $fi = new Wact_Template_Compiler_Formatter_Info('html', 'Wact_Template_Compiler_Formatter');
        $fi->file = 'wact/template/compiler/formatter/formatter.inc.php';

        $this->formatterDictionary->setReturnValue('getFormatterInfo', $fi);

        $treeBuilder = new MockTreeBuilder($this);
        $treeBuilder->expectOnce('addTextNode');
        $treeBuilder->expectOnce('addNode');

        $treeBuilder->addContent('{$1}test');

        $treeBuilder->tally();
    }
    */

}
?>