[limb-svn] r5797 - in 3.x/trunk/limb/macro: src tests/cases
svn at limb-project.com
svn at limb-project.com
Fri May 4 02:28:03 MSD 2007
Author: pachanga
Date: 2007-05-04 02:28:03 +0400 (Fri, 04 May 2007)
New Revision: 5797
URL: http://fisheye.limb-project.com/changelog/limb/?cs=5797
Added:
3.x/trunk/limb/macro/src/lmbMacroCodeWriter.class.php
3.x/trunk/limb/macro/src/lmbMacroException.class.php
3.x/trunk/limb/macro/src/lmbMacroNode.class.php
3.x/trunk/limb/macro/src/lmbMacroTag.class.php
3.x/trunk/limb/macro/src/lmbMacroTagInfo.class.php
3.x/trunk/limb/macro/tests/cases/lmbMacroTagTest.class.php
Log:
-- adding initial versions of lmbMacroCodeWriter, lmbMacroException, lmbMacroNode, lmbMacroTag, lmbMacroTagInfo
Added: 3.x/trunk/limb/macro/src/lmbMacroCodeWriter.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroCodeWriter.class.php (rev 0)
+++ 3.x/trunk/limb/macro/src/lmbMacroCodeWriter.class.php 2007-05-03 22:28:03 UTC (rev 5797)
@@ -0,0 +1,176 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright Copyright © 2004-2007 BIT
+ * @license LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version $Id: WactCodeWriter.class.php 5071 2007-02-16 09:09:35Z serega $
+ * @package macro
+ */
+
+class lmbMacroCodeWriter
+{
+ const MODE_PHP = 1;
+ const MODE_HTML = 2;
+
+ protected $current_mode = self :: MODE_HTML;
+
+ protected $code = '';
+
+ protected $function_prefix = '';
+ protected $function_suffix = 1;
+
+ protected $include_list = array();
+
+ protected $tempVarName = 1;
+
+ function reset()
+ {
+ $this->code = '';
+ $this->current_mode = self :: MODE_HTML;
+ $this->include_list = array();
+ }
+
+ protected function switchToPHP()
+ {
+ if($this->current_mode == self :: MODE_HTML)
+ {
+ $this->current_mode = self :: MODE_PHP;
+ $this->code .= '<?php ';
+ }
+ }
+
+ protected function switchToHTML($context = null)
+ {
+ if($this->current_mode == self :: MODE_PHP)
+ {
+ $this->current_mode = self :: MODE_HTML;
+ if($context === "\n")
+ $this->code .= " ?>\n";
+ else
+ $this->code .= ' ?>';
+ }
+ }
+
+ function writePHP($text)
+ {
+ $this->switchToPHP();
+ $this->code .= $text;
+ }
+
+ function writePHPLiteral($text, $escape_text = true)
+ {
+ $this->switchToPHP();
+
+ if($escape_text)
+ $this->code .= "'" . $this->escapeLiteral($text) . "'";
+ else
+ $this->code .= "'" . $text . "'";
+ }
+
+ function escapeLiteral($text)
+ {
+ $text = str_replace('\'', "\\'", $text);
+ if(substr($text, -1) == '\\')
+ $text .= '\\';
+ return $text;
+ }
+
+ function writeHTML($text)
+ {
+ $this->switchToHTML(substr($text,0,1));
+ $this->code .= $text;
+ }
+
+ function renderCode()
+ {
+ $this->switchToHTML();
+
+ $this->_prependIncludeListToCode();
+
+ return $this->code;
+ }
+
+ function getCode()
+ {
+ return $this->code;
+ }
+
+ function setCode($code)
+ {
+ $this->code = $code;
+ }
+
+ protected function _prependIncludeListToCode()
+ {
+ $include_code = '';
+ foreach($this->include_list as $include_file)
+ $include_code .= "require_once('$include_file');\n";
+
+ if(!empty($include_code))
+ $this->code = '<?php ' . $include_code . '?>' . $this->code;
+ }
+
+ function getMode()
+ {
+ return $this->current_mode;
+ }
+
+ function registerInclude($include_file)
+ {
+ if(!in_array($include_file, $this->include_list))
+ $this->include_list[] = $include_file;
+ }
+
+ function getIncludeList()
+ {
+ return $this->include_list;
+ }
+
+ /**
+ * Begins writing a PHP function to the compiled template, using the
+ * function_prefix and the function_suffix, the latter being post incremented
+ * by one.
+ */
+ function beginFunction($param_list)
+ {
+ $func_name = 'tpl' . $this->function_prefix . $this->function_suffix++;
+ $this->writePHP('function ' . $func_name . $param_list ." {\n");
+ return $func_name;
+ }
+
+ function endFunction()
+ {
+ $this->writePHP(" }\n");
+ }
+
+ function setFunctionPrefix($prefix)
+ {
+ $this->function_prefix = $prefix;
+ }
+
+ /**
+ * Utility method, which generates a unique variable name
+ */
+ function getTempVariable()
+ {
+ $var = $this->tempVarName++;
+ if($var > 675)
+ return chr(65 + ($var/26)/26) . chr(65 + ($var/26)%26) . chr(65 + $var%26);
+ elseif($var > 26)
+ return chr(65 + ($var/26)%26) . chr(65 + $var%26);
+ else
+ return chr(64 + $var);
+ }
+
+ /**
+ * Utility method, which generates a unique variable name, prefixed with a $
+ */
+ function getTempVarRef()
+ {
+ return '$' . $this->getTempVariable();
+ }
+}
+?>
Added: 3.x/trunk/limb/macro/src/lmbMacroException.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroException.class.php (rev 0)
+++ 3.x/trunk/limb/macro/src/lmbMacroException.class.php 2007-05-03 22:28:03 UTC (rev 5797)
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright Copyright © 2004-2007 BIT
+ * @license LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version $Id: error.inc.php 5334 2007-03-23 11:48:20Z pachanga $
+ * @package macro
+ */
+
+class lmbMacroException extends lmbException
+{
+ function __construct($message, $params = array())
+ {
+ parent :: __construct('MACRO exception: ' . $message, $params);
+ }
+}
+?>
\ No newline at end of file
Added: 3.x/trunk/limb/macro/src/lmbMacroNode.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroNode.class.php (rev 0)
+++ 3.x/trunk/limb/macro/src/lmbMacroNode.class.php 2007-05-03 22:28:03 UTC (rev 5797)
@@ -0,0 +1,245 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright Copyright © 2004-2007 BIT
+ * @license LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version $Id: WactCompilerTag.class.php 5203 2007-03-07 08:58:21Z serega $
+ * @package macro
+ */
+lmb_require('limb/macro/src/lmbMacroException.class.php');
+lmb_require('limb/macro/src/lmbMacroSourceLocation.class.php');
+
+class lmbMacroNode
+{
+ protected $id;
+ protected $children = array();
+ protected $parent;
+ /**
+ * @var lmbMacroSourceLocation
+ **/
+ protected $location;
+
+ function __construct($location = null)
+ {
+ if($location)
+ $this->location = $location;
+ else
+ $this->location = new lmbMacroSourceLocation();
+ }
+
+ function setParent($parent)
+ {
+ $this->parent = $parent;
+ }
+
+ function getLocationInTemplate()
+ {
+ return $this->location;
+ }
+
+ function getTemplateFile()
+ {
+ return $this->location->getFile();
+ }
+
+ function getTemplateLine()
+ {
+ return $this->location->getLine();
+ }
+
+ function getId()
+ {
+ if($this->id)
+ return $this->id;
+
+ $this->id = self :: generateNewId();
+ return $this->id;
+ }
+
+ function setId($id)
+ {
+ $this->id = $id;
+ }
+
+ static function generateNewId()
+ {
+ static $counter = 1;
+ return 'id00' . $counter++;
+ }
+
+ function raise($error, $vars = array())
+ {
+ $vars['file'] = $this->location->getFile();
+ $vars['line'] = $this->location->getLine();
+ throw new lmbMacroException($error, $vars);
+ }
+
+ function addChild($child)
+ {
+ $child->parent = $this;
+ $this->children[] = $child;
+ }
+
+ function removeChild($id)
+ {
+ foreach(array_keys($this->children) as $key)
+ {
+ $child = $this->children[$key];
+ if($child->getId() == $id)
+ {
+ unset($this->children[$key]);
+ return $child;
+ }
+ }
+ }
+
+ function getChildren()
+ {
+ return $this->children;
+ }
+
+ function removeChildren()
+ {
+ foreach (array_keys($this->children) as $key)
+ {
+ $this->children[$key]->removeChildren();
+ unset($this->children[$key]);
+ }
+ }
+
+ function getChild($id)
+ {
+ if($child = $this->findChild($id))
+ return $child;
+ else
+ $this->raise('Could not find component', array('id' => $id));
+ }
+
+ function findChild($id)
+ {
+ foreach(array_keys($this->children) as $key)
+ {
+ if($this->children[$key]->getId() == $id)
+ return $this->children[$key];
+ else
+ return $this->children[$key]->findChild($id);
+ }
+ }
+
+ function findChildByClass($class)
+ {
+ foreach(array_keys($this->children) as $key)
+ {
+ if(is_a($this->children[$key], $class))
+ return $this->children[$key];
+ else
+ {
+ if($result = $this->children[$key]->findChildByClass($class))
+ return $result;
+ }
+ }
+ }
+
+ function findChildrenByClass($class)
+ {
+ $ret = array();
+ foreach(array_keys($this->children) as $key)
+ {
+ if(is_a($this->children[$key], $class))
+ $ret[] = $this->children[$key];
+ else
+ {
+ $more_children = $this->children[$key]->findChildrenByClass($class);
+ if(count($more_children))
+ $ret = array_merge($ret, $more_children);
+ }
+ }
+ return $ret;
+ }
+
+ function findImmediateChildByClass($class)
+ {
+ foreach(array_keys($this->children) as $key)
+ {
+ if(is_a($this->children[$key], $class))
+ return $this->children[$key];
+ }
+ }
+
+ function findImmediateChildrenByClass($class)
+ {
+ $result = array();
+ foreach(array_keys($this->children) as $key)
+ {
+ if(is_a($this->children[$key], $class))
+ $result[] = $this->children[$key];
+ }
+ return $result;
+ }
+
+ function findParentByClass($class)
+ {
+ $parent = $this->parent;
+
+ while($parent && !is_a($parent, $class))
+ $parent = $parent->parent;
+
+ return $parent;
+ }
+
+ function prepare()
+ {
+ foreach(array_keys($this->children) as $key)
+ $this->children[$key]->prepare();
+ }
+
+ function preParse(){}
+
+ function generateConstructor($code_writer)
+ {
+ foreach(array_keys($this->children) as $key)
+ $this->children[$key]->generateConstructor($code_writer);
+ }
+
+ function generateContents($code_writer)
+ {
+ foreach(array_keys($this->children) as $key)
+ $this->children[$key]->generate($code_writer);
+ }
+
+ function generate($code_writer)
+ {
+ $this->generateContents($code_writer);
+ }
+
+ /**
+ * Checks that each immediate child of the current component has a unique ID
+ * amongst its siblings.
+ */
+ function checkChildrenIds()
+ {
+ $child_ids = array();
+ $checked_children = array();
+ foreach($this->getChildren() as $key => $child)
+ {
+ $id = $child->getId();
+ if (in_array($id, $child_ids))
+ {
+ $duplicate_child = $checked_children[$id];
+ $child->raise('Duplicate "id" attribute',
+ array('id' => $id,
+ 'duplicate_node_file' => $duplicate_child->getTemplateFile(),
+ 'duplicate_node_line' => $duplicate_child->getTemplateLine()));
+ }
+ else
+ {
+ $child_ids[] = $id;
+ $checked_children[$id] = $child;
+ }
+ }
+ }
+}
+?>
\ No newline at end of file
Added: 3.x/trunk/limb/macro/src/lmbMacroTag.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroTag.class.php (rev 0)
+++ 3.x/trunk/limb/macro/src/lmbMacroTag.class.php 2007-05-03 22:28:03 UTC (rev 5797)
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright Copyright © 2004-2007 BIT
+ * @license LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version $Id: WactCompilerTag.class.php 5203 2007-03-07 08:58:21Z serega $
+ * @package macro
+ */
+
+lmb_require('limb/macro/src/lmbMacroNode.class.php');
+
+class lmbMacroTag extends lmbMacroNode
+{
+ protected $tag;
+ protected $has_closing_tag = true;
+ protected $empty_closed_tag = false;
+ protected $tag_info;
+ protected $attributes = array();
+
+ function __construct($location, $tag, $tag_info)
+ {
+ $this->tag = $tag;
+ $this->tag_info = $tag_info;
+
+ parent :: __construct($location);
+ }
+
+ function getTag()
+ {
+ return $this->tag;
+ }
+
+ function getId()
+ {
+ if($this->id)
+ return $this->id;
+
+ if($id = $this->get('id'))
+ $this->id = $id;
+ else
+ $this->id = self :: generateNewId();
+
+ return $this->id;
+ }
+
+ function get($name)
+ {
+ if(array_key_exists(strtolower($name), $this->attributes))
+ return $this->attributes[strtolower($name)];
+ }
+
+ function set($name, $value)
+ {
+ $this->attributes[strtolower($name)] = $value;
+ }
+
+ function has($name)
+ {
+ return array_key_exists(strtolower($name), $this->attributes);
+ }
+
+ /**
+ * Return the value of a boolean attribute as a boolean.
+ * ATTRIBUTE=ANYTHING (true)
+ * ATTRIBUTE=(false|N|NA|NO|NONE|0) (false)
+ * ATTRIBUTE (true)
+ * (attribute unspecified) (default)
+ */
+ function getBool($attrib, $default = false)
+ {
+ if(!isset($this->attributes[strtolower($attrib)]))
+ return $default;
+
+ return self :: getBooleanValue($this->attributes[strtolower($attrib)]);
+ }
+
+ static function getBooleanValue($value)
+ {
+ switch(strtoupper($value))
+ {
+ case 'FALSE':
+ case 'N':
+ case 'NO':
+ case 'NONE':
+ case 'NA':
+ case '0':
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ function remove($attrib)
+ {
+ unset($this->attributes[strtolower($attrib)]);
+ }
+
+ function raise($error, $vars = array())
+ {
+ $vars['tag'] = $this->tag;
+ parent :: raise($error, $vars);
+ }
+
+ function raiseRequiredAttribute($attribute_name)
+ {
+ $this->raise('Missing required attribute', array('attribute' => $attribute_name));
+ }
+
+ function preParse()
+ {
+ foreach($this->tag_info->getRequiredAttributes() as $attr_name)
+ {
+ if(!$this->has($attr_name))
+ $this->raiseRequiredAttribute($attr_name);
+ }
+
+ if($this->tag_info->isRestrictSelfNesting() && $parent = $this->findParentByClass(get_class($this)))
+ $this->raise('Tag cannot be nested within the same tag',
+ array('same_tag_file' => $parent->getTemplateFile(),
+ 'same_tag_line' => $parent->getTemplateLine()));
+
+ if(($parent_class = $this->tag_info->getParentClass()) &&
+ !$parent = $this->findParentByClass($parent_class))
+ {
+ $this->raise('Tag must be enclosed by a proper parent tag',
+ array('required_parent_tag_class' => $parent_class));
+
+ }
+ }
+}
+?>
\ No newline at end of file
Added: 3.x/trunk/limb/macro/src/lmbMacroTagInfo.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroTagInfo.class.php (rev 0)
+++ 3.x/trunk/limb/macro/src/lmbMacroTagInfo.class.php 2007-05-03 22:28:03 UTC (rev 5797)
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright Copyright © 2004-2007 BIT
+ * @license LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version $Id: WacttagInfo.class.php 5021 2007-02-12 13:04:07Z pachanga $
+ * @package macro
+ */
+
+class lmbMacroTagInfo
+{
+ protected $tag = '';
+ protected $class = '';
+ protected $file;
+ protected $req_attributes = array();
+ protected $parent_class;
+ protected $restrict_self_nesting = false;
+ protected $forbid_parsing = false;
+ protected $forbid_endtag = false;
+
+ function __construct($tag, $class)
+ {
+ $this->tag = $tag;
+ $this->class = $class;
+ }
+
+ function setForbidEndtag($flag = true)
+ {
+ $this->forbid_endtag = $flag;
+ }
+
+ function isEndtagForbidden()
+ {
+ return $this->forbid_endtag;
+ }
+
+ function setRequiredAttributes($attributes)
+ {
+ $this->req_attributes = $attributes;
+ }
+
+ function getRequiredAttributes()
+ {
+ return $this->req_attributes;
+ }
+
+ function setParentClass($parent_tag_class)
+ {
+ $this->parent_class = $parent_tag_class;
+ }
+
+ function getParentClass()
+ {
+ return $this->parent_class;
+ }
+
+ function setRestrictSelfNesting($flag = true)
+ {
+ $this->restrict_self_nesting = $flag;
+ }
+
+ function isRestrictSelfNesting()
+ {
+ return $this->restrict_self_nesting;
+ }
+
+ function setForbidParsing($flag = true)
+ {
+ $this->forbid_parsing = $flag;
+ }
+
+ function isParsingForbidden()
+ {
+ return $this->forbid_parsing;
+ }
+
+ function load()
+ {
+ if(!class_exists($this->class) && isset($this->file))
+ require_once($this->file);
+ }
+}
+?>
\ No newline at end of file
Added: 3.x/trunk/limb/macro/tests/cases/lmbMacroTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/lmbMacroTagTest.class.php (rev 0)
+++ 3.x/trunk/limb/macro/tests/cases/lmbMacroTagTest.class.php 2007-05-03 22:28:03 UTC (rev 5797)
@@ -0,0 +1,355 @@
+<?php
+/**
+ * Limb Web Application Framework
+ *
+ * @link http://limb-project.com
+ *
+ * @copyright Copyright © 2004-2007 BIT
+ * @license LGPL http://www.gnu.org/copyleft/lesser.html
+ * @version $Id: lmbMacroTagTest.class.php 5021 2007-02-12 13:04:07Z pachanga $
+ * @package macro
+ */
+
+lmb_require('limb/macro/src/lmbMacroNode.class.php');
+lmb_require('limb/macro/src/lmbMacroTag.class.php');
+lmb_require('limb/macro/src/lmbMacroTagInfo.class.php');
+lmb_require('limb/macro/src/lmbMacroSourceLocation.class.php');
+lmb_require('limb/macro/src/lmbMacroCodeWriter.class.php');
+
+class MacroTagClass1CompilerTest extends lmbMacroTag{}
+class MacroTagClass2CompilerTest extends lmbMacroTag{}
+
+Mock::generate('lmbMacroNode', 'MockMacroNode');
+Mock::generate('lmbMacroCodeWriter', 'MockMacroCodeWriter');
+
+class lmbMacroTagTest extends UnitTestCase
+{
+ protected $node;
+ protected $tag_info;
+ protected $source_location;
+
+ function setUp()
+ {
+ $this->tag_info = new lmbMacroTagInfo('MacroTag', 'whatever');
+ $this->source_location = new lmbMacroSourceLocation('my_file', 10);
+ $this->node = $this->_createNode();
+ }
+
+ protected function _createNode()
+ {
+ return new lmbMacroTag($this->source_location, 'my_tag', $this->tag_info);
+ }
+
+ function testGetIdAttribute()
+ {
+ $this->node->setId('Test');
+ $this->assertEqual($this->node->getId(), 'Test');
+ }
+
+ function testGetIdGenerated()
+ {
+ $id = $this->node->getId();
+ $this->assertEqual($this->node->getId(), $id);
+ }
+
+ function testFindChild()
+ {
+ $mock = new MockMacroNode();
+ $mock->setReturnValue('getId', 'Test');
+ $this->node->addChild($mock);
+ $this->assertIsA($this->node->findChild('Test'), 'MockMacroNode');
+ }
+
+ function testFindChildNotFound()
+ {
+ $this->assertFalse($this->node->findChild('Test'));
+ }
+
+ function testFindChildByClass()
+ {
+ $mock = new MockMacroNode();
+ $this->node->addChild($mock);
+ $this->assertIsA($this->node->findChildByClass('MockMacroNode'), 'MockMacroNode');
+ }
+
+ function testFindChildByClassNotFound()
+ {
+ $this->assertFalse($this->node->findChildByClass('Booo'));
+ }
+
+ function testFindParentByChilld()
+ {
+ $parent = new lmbMacroNode;
+ $parent->addChild($this->node);
+ $this->assertIsA($this->node->findParentByClass('lmbMacroNode'), 'lmbMacroNode');
+ }
+
+ function testFindParentByClassNotFound()
+ {
+ $this->assertFalse($this->node->findParentByClass('Test'));
+ }
+
+ function testRemoveChild()
+ {
+ $mock = new MockMacroNode();
+ $mock->setReturnValue('getId', 'Test');
+ $this->node->addChild($mock);
+ $this->assertIsA($this->node->removeChild('Test'), 'MockMacroNode');
+ }
+
+ function testGetChildren()
+ {
+ $mock = new MockMacroNode();
+ $this->node->addChild($mock);
+ $children = $this->node->getChildren();
+ $this->assertReference($mock, $children[0]);
+ }
+
+ function testPrepare()
+ {
+ $child = new MockMacroNode();
+ $this->node->addChild($child);
+ $child->expectCallCount('prepare', 1);
+ $this->node->prepare();
+ }
+
+ function testGenerateConstructor()
+ {
+ $code_writer = new MockMacroCodeWriter();
+ $child = new MockMacroNode();
+ $child->expectCallCount('generateConstructor', 1);
+ $this->node->addChild($child);
+ $this->node->generateConstructor($code_writer);
+ }
+
+ function testGenerateContents()
+ {
+ $code_writer = new MockMacroCodeWriter();
+ $child = new MockMacroNode();
+ $child->expectCallCount('generate', 1);
+ $this->node->addChild($child);
+ $this->node->generateContents($code_writer);
+ }
+
+ function testGenerate()
+ {
+ $code_writer = new MockMacroCodeWriter();
+ $child = new MockMacroNode();
+ $child->expectCallCount('generate', 1);
+ $this->node->addChild($child);
+ $this->node->generate($code_writer);
+ }
+
+ function testCheckIdsOk()
+ {
+ $root = new lmbMacroNode;
+ $child1 = new lmbMacroNode;
+ $child1->setId('id1');
+
+ $child2 = new lmbMacroNode;
+ $child2->setId('id2');
+
+ $root->addChild($child1);
+ $root->addChild($child2);
+
+ $root->checkChildrenIds();
+ }
+
+ function testDuplicateIdsError()
+ {
+ $root = new lmbMacroNode;
+ $child1 = new lmbMacroNode(new lmbMacroSourceLocation('my_file', 10));
+ $child1->setId('my_tag');
+ $root->addChild($child1);
+
+ $child2 = new lmbMacroNode(new lmbMacroSourceLocation('my_file2', 15));
+ $child2->setId('my_tag');
+ $root->addChild($child2);
+
+ try
+ {
+ $root->checkChildrenIds();
+ $this->assertTrue(false);
+ }
+ catch(lmbMacroException $e)
+ {
+ $this->assertWantedPattern('/Duplicate "id" attribute/', $e->getMessage());
+ $params = $e->getParams();
+ $this->assertEqual($params['file'], 'my_file2');
+ $this->assertEqual($params['line'], 15);
+ $this->assertEqual($params['duplicate_node_file'], 'my_file');
+ $this->assertEqual($params['duplicate_node_line'], 10);
+ }
+ }
+
+ function testDuplicateIdIsLegalInDifferentBranches()
+ {
+ $root = new lmbMacroNode;
+
+ $Branch = new lmbMacroNode;
+ $root->addChild($Branch);
+
+ $child1 = new lmbMacroNode;
+ $child1->setId('my_tag');
+ $Branch->addChild($child1);
+
+ $child2 = new MockMacroNode();
+ $child2->setId('my_tag');
+ $root->addChild($child2);
+
+ $root->checkChildrenIds();
+ }
+
+ function testGetIdByDefault()
+ {
+ $this->assertNotNull($this->node->getId());
+ }
+
+ function testGetId()
+ {
+ $this->node->setId('TestId');
+ $this->assertEqual($this->node->getId(), 'TestId');
+ }
+
+ function testGetAttributeUnset()
+ {
+ $this->assertNull($this->node->get('foo'));
+ }
+
+ function testGetAttribute()
+ {
+ $this->node->set('foo', 'bar');
+ $this->assertEqual($this->node->get('foo'), 'bar');
+ $this->assertEqual($this->node->get('FOO'), 'bar');
+ }
+
+ function testHasAttribute()
+ {
+ $this->node->set('foo', 'bar');
+ $this->node->set('tricky', NULL);
+ $this->assertTrue($this->node->has('foo'));
+ $this->assertTrue($this->node->has('tricky'));
+ $this->assertFalse($this->node->has('missing'));
+ $this->assertTrue($this->node->has('FOO'));
+ $this->assertTrue($this->node->has('TRICKY'));
+ $this->assertFalse($this->node->has('MISSING'));
+ }
+
+ function testRemoveAttribute()
+ {
+ $this->node->set('foo', 'bar');
+ $this->node->set('untouched', 'value');
+ $this->assertTrue($this->node->has('foo'));
+ $this->node->remove('FOO');
+ $this->assertFalse($this->node->has('foo'));
+ }
+
+ function testBooleanAttribute()
+ {
+ //true cases
+ $this->node->set('B', 'True');
+ $this->assertTrue($this->node->getBool('B'));
+
+ $this->node->set('C', 'Something');
+ $this->assertTrue($this->node->getBool('C'));
+
+ //false cases
+ $this->node->set('A', NULL);
+ $this->assertFalse($this->node->getBool('A'));
+
+ $this->node->set('D', 'False');
+ $this->assertFalse($this->node->getBool('D'));
+
+ $this->assertFalse($this->node->getBool('E'));
+
+ $this->node->set('F', 'n');
+ $this->assertFalse($this->node->getBool('F'));
+
+ $this->node->set('G', 'No');
+ $this->assertFalse($this->node->getBool('G'));
+
+ $this->node->set('H', 'none');
+ $this->assertFalse($this->node->getBool('H'));
+
+ $this->node->set('I', '0');
+ $this->assertFalse($this->node->getBool('I'));
+ }
+
+ function testPreparseAndCheckForRequiredAttributes()
+ {
+ $this->tag_info->setRequiredAttributes(array('bar'));
+ $this->node->set('bar', null);
+ $this->node->preParse();
+ }
+
+ function testPreparseAndCheckForMissedRequiredAttributes()
+ {
+ $this->tag_info->setRequiredAttributes(array('bar'));
+
+ try
+ {
+ $this->node->preParse();
+ $this->assertTrue(false);
+ }
+ catch(lmbMacroException $e)
+ {
+ $this->assertWantedPattern('/Missing required attribute/', $e->getMessage());
+ $this->assertEqual($e->getParam('attribute'), 'bar');
+ }
+ }
+
+ function testRestrictSelfNesting()
+ {
+ $tag_info = new lmbMacroTagInfo('CompilerTag', 'whatever');
+ $tag_info->setRestrictSelfNesting(true);
+
+ $node = new lmbMacroTag(new lmbMacroSourceLocation('my_file', 13), 'whatever', $tag_info);
+
+ $parent = new lmbMacroTag(new lmbMacroSourceLocation('my_file', 10), 'whatEver', $tag_info);
+ $node->setParent($parent);
+
+ try
+ {
+ $node->preParse();
+ $this->assertTrue(false);
+ }
+ catch(lmbMacroException $e)
+ {
+ $this->assertWantedPattern('/Tag cannot be nested within the same tag/', $e->getMessage());
+ $this->assertEqual($e->getParam('same_tag_file'), 'my_file');
+ $this->assertEqual($e->getParam('same_tag_line'), 10);
+ }
+ }
+
+ function testCheckParentTagClassOk()
+ {
+ $this->tag_info->setParentClass('MacroTagClass1CompilerTest');
+
+ $parent = new MacroTagClass1CompilerTest(null, null, null);
+ $this->node->setParent($parent);
+
+ $this->node->preParse();
+ }
+
+ function testCheckParentTagClassException()
+ {
+ $this->tag_info->setParentClass('MacroTagClass1CompilerTest');
+
+ $parent = new MacroTagClass2CompilerTest(null, null, null);
+ $this->node->setParent($parent);
+
+ try
+ {
+ $this->node->preParse();
+ $this->assertTrue(false);
+ }
+ catch(lmbMacroException $e)
+ {
+ $this->assertWantedPattern('/Tag must be enclosed by a proper parent tag/', $e->getMessage());
+ $this->assertEqual($e->getParam('required_parent_tag_class'), 'MacroTagClass1CompilerTest');
+ $this->assertEqual($e->getParam('file'), $this->source_location->getFile());
+ $this->assertEqual($e->getParam('line'), $this->source_location->getLine());
+ }
+ }
+}
+?>
\ No newline at end of file
More information about the limb-svn
mailing list