<?php

Mock::generate('Wact_Template_Compiler_Node', 'MockTemplateNode');
//Mock::generate('Wact_Php_Writer', 'MockCodeWriter');

class Wact_Template_Compiler_NodeTestCase extends Wact_Test_Case {

    protected $node;

    function setUp() {
        $this->node = new Wact_Template_Compiler_Node('tagtag', NULL, 
            new Wact_Template_Compiler_Location('filename', 123));
    }

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

    function testGetClientId() {
        $this->node->setAttributeValue('id', 'TestId');
        $this->assertEqual($this->node->getClientId(), 'TestId');
    }

    function testGetClientIdUnset() {
        $this->assertNull($this->node->getClientId());
    }

    function testGetViewIdFromId() {
        $this->node->setAttributeValue('id', 'TestId');
        $this->assertEqual($this->node->getViewId(), strtolower('TestId'));
    }
    
    function testGetViewIdFromWactId() {
        $this->node->setAttributeValue('wact:id', 'TestId');
        $this->assertEqual($this->node->getViewId(), strtolower('TestId'));
    }
    
    function testGetViewIdGenerated() {
        $id = $this->node->getViewId();
        $this->assertEqual($this->node->getViewId(), $id);
    }

    function testFindChild() {
        $child = new MockTemplateNode($this);
        $child->setReturnValue('getViewId', 'test');

        $this->node->addChild($child);

        $this->assertIsA($this->node->findChild('test'), 'MockTemplateNode');
    }

    function testFindChildCaseInsensitivity() {
        $child = new Wact_Template_Compiler_Node('childtag', null, new Wact_Template_Compiler_Location('file', 1));
        $child->setAttributeValue('wact:id', 'Test');

        $this->node->addChild($child);

        $this->assertIsA($this->node->findChild('test'), 'Wact_Template_Compiler_Node');
    }

    function testFindChildNotFound() {
        $this->assertFalse($this->node->findChild('Test'));
    }

    function testFindChildByClass() {
        $child = new MockTemplateNode($this);

        $this->node->addChild($child);

        $this->assertIsA($this->node->findChildByClass('MockTemplateNode'), 'MockTemplateNode');
    }

    function testFindChildByClassNotFound() {
        $this->assertFalse($this->node->findChildByClass('MockTemplateNode'));
    }

    function testFindParentByChilld() {
        $parent = new Wact_Template_Compiler_Node('childtag', NULL, new Wact_Template_Compiler_Location('file', 1));
        $parent->addChild($this->node);
        $this->assertIsA($this->node->findParentByClass('Wact_Template_Compiler_Node'), 'Wact_Template_Compiler_Node');
    }

    function testFindParentByClassNotFound() {
        $this->assertFalse($this->node->findParentByClass('Test'));
    }

    function testRemoveChild() {
        $child = new MockTemplateNode($this);
        $child->setReturnValue('getViewId', 'Test');
        
        $this->node->addChild($child);

        $this->assertIsA($this->node->removeChild('Test'), 'MockTemplateNode');
    }
    
    function testGetChildren() {
        $child = new MockTemplateNode($this);

        $this->node->addChild($child);

        $children = $this->node->getChildren();
        $this->assertReference($child, $children[0]);
    }   

    function testPrepare() {
        $child = new MockTemplateNode($this);
        $child->expectCallCount('prepare', 1);

        $this->node->addChild($child);
        $this->node->prepare();

        $child->tally();
    }

    function testPreParse() {
        $this->assertEqual($this->node->preParse(NULL), Wact_Template_Compiler_Node::REQUIRE_PARSING);
    }

/*
    function testGenerateConstructor() {
        $code = new MockCodeWriter($this);

        $child = new MockTemplateNode($this);
        $child->expectCallCount('generateConstructor', 1);

        $this->node->addChild($child);
        $this->node->generateConstructor($code);

        $child->tally();
    }
*/

/*
    function testGenerateContents() {
        $code = new MockCodeWriter($this);

        $child = new MockTemplateNode($this);
        $child->expectCallCount('generate', 1);

        $this->node->addChild($child);
        $this->node->generateContents($code);

        $child->tally();
    }
*/

/*
    function testGenerate(){
        $code = new MockCodeWriter($this);

        $child = new MockTemplateNode($this);
        $child->expectCallCount('generate', 1);

        $this->node->addChild($child);
        $this->node->generate($code);

        $child->tally();
    }
*/

    function testGetAttribute() {
        $this->node->setAttributeValue('foo', 'bar');

        $this->assertEqual($this->node->getAttributeValue('foo'), 'bar');
        $this->assertEqual($this->node->getAttributeValue('FOO'), 'bar');
    }

    function testGetAttributeUnset() {
        $this->assertNull($this->node->getAttributeValue('foo'));
    }

    function testHasAttribute() {
        $this->node->setAttributeValue('foo', 'bar');
        $this->node->setAttributeValue('tricky', NULL);

        $this->assertTrue( $this->node->hasAttribute('foo'));                    
        $this->assertTrue( $this->node->hasAttribute('tricky'));                    
        $this->assertFalse( $this->node->hasAttribute('missing'));                    
        $this->assertTrue( $this->node->hasAttribute('FOO'));                    
        $this->assertTrue( $this->node->hasAttribute('TRICKY'));                    
        $this->assertFalse( $this->node->hasAttribute('MISSING'));                    
    }

    function testDuplicateAttribute() {
        // Once set, attributes at compile time are immutable.
        $this->node->setAttributeValue('SAME', 'value 1');

        try {
            $this->node->setAttributeValue('same', 'value 2');
            $this->fail('Expected exception not thrown');
        } catch (Wact_Template_Compiler_Exception $e) {
            $this->pass();
        }
    }

    function testRemoveAttribute() {
        $this->node->setAttributeValue('foo', 'bar');
        $this->node->setAttributeValue('untouched', 'value');
        $this->assertTrue( $this->node->hasAttribute('foo'));                    
        $this->node->removeAttribute('FOO');
        $this->assertFalse( $this->node->hasAttribute('foo'));                    
    }

    function testBooleanAttribute() {
        //true cases
        $this->node->setAttributeValue('A', NULL);
        $this->node->setAttributeValue('B', 'True');
        $this->node->setAttributeValue('C', 'Something');
        //false cases
        $this->node->setAttributeValue('D', 'False');
        $this->node->setAttributeValue('F', 'n');
        $this->node->setAttributeValue('G', 'No');
        $this->node->setAttributeValue('H', 'none');
        $this->node->setAttributeValue('I', '0');
        //assertions
        $this->assertTrue( $this->node->getBoolAttributeValue('A'));                    
        $this->assertTrue( $this->node->getBoolAttributeValue('B'));                    
        $this->assertTrue( $this->node->getBoolAttributeValue('C'));                    
        $this->assertFalse( $this->node->getBoolAttributeValue('D'));                    
        $this->assertFalse( $this->node->getBoolAttributeValue('E'));                    
        $this->assertFalse( $this->node->getBoolAttributeValue('F'));                    
        $this->assertFalse( $this->node->getBoolAttributeValue('G'));                    
        $this->assertFalse( $this->node->getBoolAttributeValue('H'));                    
        $this->assertFalse( $this->node->getBoolAttributeValue('I'));                    
    }

    function testAddChildAttribute() {
        $attrib = new Wact_Template_Compiler_Attribute('Foo', 'bar');
        $this->node->addChildAttribute($attrib);
        $this->assertEqual($this->node->getAttributeValue('FOO'), 'bar');
    }
}

?>