[limb-svn] r6555 - in 3.x/trunk/limb/macro: src src/tags src/tags/core src/tags/form src/tags/list src/tags/tree tests/cases tests/cases/tags tests/cases/tags/core tests/cases/tags/form tests/cases/tags/list tests/cases/tags/pager tests/cases/tags/tree

svn at limb-project.com svn at limb-project.com
Sat Dec 1 13:31:03 MSK 2007


Author: serega
Date: 2007-12-01 13:31:03 +0300 (Sat, 01 Dec 2007)
New Revision: 6555
URL: http://fisheye.limb-project.com/changelog/limb/?cs=6555

Added:
   3.x/trunk/limb/macro/src/tags/form/
   3.x/trunk/limb/macro/src/tags/form/form.tag.php
   3.x/trunk/limb/macro/src/tags/form/form_errors.tag.php
   3.x/trunk/limb/macro/src/tags/form/lmbMacroFormErrorList.class.php
   3.x/trunk/limb/macro/src/tags/form/lmbMacroFormFieldWidget.class.php
   3.x/trunk/limb/macro/src/tags/form/lmbMacroFormLabelWidget.class.php
   3.x/trunk/limb/macro/src/tags/form/lmbMacroFormWidget.class.php
   3.x/trunk/limb/macro/src/tags/form/lmbMacroHtmlTagWidget.class.php
   3.x/trunk/limb/macro/src/tags/form/lmbMacroRuntimeWidgetTag.class.php
   3.x/trunk/limb/macro/tests/cases/compiler/
   3.x/trunk/limb/macro/tests/cases/tags/core/
   3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroIncludeTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroTemplateTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroWrapTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/form/
   3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormErrorListTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormErrorsTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormWidgetTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/list/
   3.x/trunk/limb/macro/tests/cases/tags/list/lmbMacroListTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/pager/
   3.x/trunk/limb/macro/tests/cases/tags/pager/lmbMacroPagerHelperTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/pager/lmbMacroPagerTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/pager/lmbMacroPaginateTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/tree/
   3.x/trunk/limb/macro/tests/cases/tags/tree/lmbMacroTreeTagTest.class.php
Removed:
   3.x/trunk/limb/macro/tests/cases/tags/lmbMacroIncludeTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/lmbMacroListTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPagerHelperTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPagerTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPaginateTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTemplateTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTreeTagTest.class.php
   3.x/trunk/limb/macro/tests/cases/tags/lmbMacroWrapTagTest.class.php
Modified:
   3.x/trunk/limb/macro/src/lmbMacroCompiler.class.php
   3.x/trunk/limb/macro/src/lmbMacroFilter.class.php
   3.x/trunk/limb/macro/src/lmbMacroNode.class.php
   3.x/trunk/limb/macro/src/lmbMacroOutputExpressionNode.class.php
   3.x/trunk/limb/macro/src/lmbMacroTag.class.php
   3.x/trunk/limb/macro/src/lmbMacroTagParsingState.class.php
   3.x/trunk/limb/macro/src/lmbMacroTextNode.class.php
   3.x/trunk/limb/macro/src/tags/core/apply.tag.php
   3.x/trunk/limb/macro/src/tags/core/include.tag.php
   3.x/trunk/limb/macro/src/tags/core/slot.tag.php
   3.x/trunk/limb/macro/src/tags/core/template.tag.php
   3.x/trunk/limb/macro/src/tags/core/wrap.tag.php
   3.x/trunk/limb/macro/src/tags/list/list.tag.php
   3.x/trunk/limb/macro/src/tags/list/list_even.tag.php
   3.x/trunk/limb/macro/src/tags/list/list_fill.tag.php
   3.x/trunk/limb/macro/src/tags/list/list_glue.tag.php
   3.x/trunk/limb/macro/src/tags/list/list_odd.tag.php
   3.x/trunk/limb/macro/src/tags/tree/tree.tag.php
   3.x/trunk/limb/macro/src/tags/tree/tree_branch.tag.php
   3.x/trunk/limb/macro/tests/cases/lmbMacroTagAcceptanceTest.class.php
   3.x/trunk/limb/macro/tests/cases/lmbMacroTagTest.class.php
Log:
-- initial commit of new {{form}} tag functionality
  * {{form}} tag added
  * {{form:errors}} tag added
  * initial version of form runtime widget and other helper classes. Massive refactorings here are expected.
-- lmbMacroNode :: prepare() removed since we don't need it
-- removed lmbMacroNode :: _preGenerataAttributes() since it actually belongs to lmbMacroTag
-- removed lmbMacroNode :: generateConstructor() 
-- removed lmbMacroNode :: generateContents() since generate() actually do the business. All immediate children of lmbMacroNode should now overrides or extend generate() instead of generateContents()
-- removed property lmbMacroTag :: $empty_closed_tag since $has_closing_tag is enough.
-- lmbMacroTag :: getConstantAttributes() added.
-- lmbMacroTag :: generate() now have calls for protected _generateBeforeContent(), _generateContent() and _generateAfterContent() methods. lmbMacroTag child classes in most cases can override _generateContent() method to render some php-code arount child nodes contents. lmbMacroTag :: generate() also has _preGenerataAttributes() method call that pregenerates dynamic attributes. That why lmbMacroTag child classes should never override generate() method unless they can't have any dymamic attributes.
-- minor restructure of tests

Modified: 3.x/trunk/limb/macro/src/lmbMacroCompiler.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroCompiler.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/lmbMacroCompiler.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -63,8 +63,6 @@
     $root_node = new lmbMacroNode(new lmbMacroSourceLocation($source_file, ''));
     $this->parseTemplate($source_file, $root_node);
 
-    $root_node->prepare();
-
     $generated_code = $this->_generateTemplateCode($class, $render_func, $root_node);
     self :: writeFile($compiled_file, $generated_code);
   }

Modified: 3.x/trunk/limb/macro/src/lmbMacroFilter.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroFilter.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/lmbMacroFilter.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -28,7 +28,7 @@
   {
     $this->base->preGenerate($code);
   }
-
+  
   function setParams($params)
   {
     $this->params = $params;

Modified: 3.x/trunk/limb/macro/src/lmbMacroNode.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroNode.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/lmbMacroNode.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -218,37 +218,14 @@
     return $parent;
   }
 
-  function prepare()
-  {
-    foreach($this->children as $child)
-      $child->prepare();
-  }
-
   function preParse(){}
 
-  function generateConstructor($code_writer)
+  function generate($code_writer)
   {
     foreach($this->children as $child)
-      $child->generateConstructor($code_writer);
-  }
-
-  function generateContents($code_writer)
-  {
-    foreach($this->children as $child)
       $child->generate($code_writer);
   }
 
-  function generate($code_writer)
-  {
-    $this->_preGenerateAttributes($code_writer);
-
-    $this->generateContents($code_writer);
-  }
-
-  protected function _preGenerateAttributes($code_writer)
-  {
-  }
-
   /**
   * Checks that each immediate child of the current component has a unique ID
   * amongst its siblings.

Modified: 3.x/trunk/limb/macro/src/lmbMacroOutputExpressionNode.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroOutputExpressionNode.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/lmbMacroOutputExpressionNode.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -26,7 +26,7 @@
     parent :: __construct($location);
   }
 
-  function generateContents($code)
+  function generate($code)
   {
     $this->expression->preGenerate($code);
     $code->writePHP('echo ' . $this->expression->getValue() .  ";\n");

Modified: 3.x/trunk/limb/macro/src/lmbMacroTag.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroTag.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/lmbMacroTag.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -19,9 +19,8 @@
 class lmbMacroTag extends lmbMacroNode
 {
   protected $tag;
+  protected $tag_info;
   protected $has_closing_tag = true;
-  protected $empty_closed_tag = false;
-  protected $tag_info;
   protected $attributes = array();
 
   function __construct($location, $tag, $tag_info)
@@ -103,11 +102,27 @@
   {
     return array_key_exists(strtolower($name), $this->attributes);
   }
+  
+  function hasConstant($name)
+  {
+    return $this->has($name) && !$this->attributes[strtolower($name)]->isDynamic();
+  }
 
   function isDynamic($name)
   {
-    return $this->has($name) && $this->attributes[strtolower($name)]->isDynamic();
+    return !$this->hasConstant($name);
   }
+  
+  function getConstantAttributes()
+  {
+    $res = array();
+    foreach($this->attributes as $key => $attr)
+    {
+      if(!$attr->isDynamic())
+        $res[$attr->getName()] = $attr->getValue();
+    }
+    return $res;
+  }
 
   /**
   * Return the value of a boolean attribute as a boolean.
@@ -146,10 +161,29 @@
   function generate($code_writer)
   {
     $this->_preGenerataAttributes($code_writer);
+    
+    $this->_generateBeforeContent($code_writer);
+    
+    $this->_generateContent($code_writer);
+    
+    $this->_generateAfterContent($code_writer);
+  }
+  
+  // children can override this method if they need to generate some code around content in simple cases
+  // but it's recommended to override generateBeforeContent() and generateAfterContent() instead.
+  protected function _generateContent($code_writer)
+  {
+    parent :: generate($code_writer);
+  }
+ 
+  protected function _generateBeforeContent($code_writer)
+  {
+  }
 
-    $this->generateContents($code_writer);
+  protected function _generateAfterContent($code_writer)
+  {
   }
-
+  
   protected function _preGenerataAttributes($code_writer)
   {
     foreach($this->attributes as $attribute)

Modified: 3.x/trunk/limb/macro/src/lmbMacroTagParsingState.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroTagParsingState.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/lmbMacroTagParsingState.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -39,7 +39,7 @@
 
     if($tag_info->isEndTagForbidden())
     {
-      $tag_node = $this->buildTagNode($tag_info, $tag, $attrs, $self_closed_tag = true);
+      $tag_node = $this->buildTagNode($tag_info, $tag, $attrs);
       $tag_node->setHasClosingTag(false);
       $this->tree_builder->pushNode($tag_node); // for cases like {{include}} we do pushNode() and popNode() here.
       $this->tree_builder->popNode();
@@ -54,7 +54,9 @@
 
   function endElement($tag)
   {
-    $tag_info = $this->tag_dictionary->findTagInfo($tag);
+    if(!$tag_info = $this->tag_dictionary->findTagInfo($tag))
+      throw new lmbMacroException("Tag '$tag' not found in dictionary");
+    
     $location = $this->parser->getCurrentLocation();
 
     if($tag_info->isEndTagForbidden())
@@ -78,7 +80,7 @@
       throw new lmbMacroException("Tag '$tag' not found in dictionary");
     $tag_info->load();
 
-    $tag_node = $this->buildTagNode($tag_info, $tag, $attrs, $self_closed_tag = true);
+    $tag_node = $this->buildTagNode($tag_info, $tag, $attrs);
     $tag_node->setHasClosingTag(false);
     $this->tree_builder->pushNode($tag_node); // for cases like {{include}} we do pushNode() and popNode() here.
     $this->tree_builder->popNode();
@@ -92,10 +94,9 @@
   * @param boolean whether the tag has contents
   * @return lmbMacroNode
   */
-  function buildTagNode($tag_info, $tag, $attrs, $isEmpty)
+  function buildTagNode($tag_info, $tag, $attrs)
   {
     $tag_node = $this->_createTagNode($tag_info, $tag);
-    $tag_node->emptyClosedTag = $isEmpty;
     $this->_addAttributesToTagNode($tag_node, $attrs);
     return $tag_node;
   }

Modified: 3.x/trunk/limb/macro/src/lmbMacroTextNode.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroTextNode.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/lmbMacroTextNode.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -23,10 +23,10 @@
     $this->contents = $text;
   }
 
-  function generateContents($code_writer)
+  function generate($code_writer)
   {
     $code_writer->writeHtml($this->contents);
-    parent :: generateContents($code_writer);
+    parent :: generate($code_writer);
   }
 
   function getText()

Modified: 3.x/trunk/limb/macro/src/tags/core/apply.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/core/apply.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/core/apply.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -17,7 +17,7 @@
  */
 class lmbMacroApplyTag extends lmbMacroTag
 {
-  function generateContents($code)
+  function generate($code)
   {
     $name = $this->get('template');
 

Modified: 3.x/trunk/limb/macro/src/tags/core/include.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/core/include.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/core/include.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -42,15 +42,15 @@
     return $this->isDynamic('file');
   }
 
-  function generateContents($code)
+  function generate($code)
   {
     if($this->_isDynamic())
-      $this->_generateDynamicContents($code);
+      $this->_generateDynamicaly($code);
     else
-      $this->_generateStaticContents($code);
+      $this->_generateStaticaly($code);
   }
 
-  function _generateDynamicContents($code)
+  function _generateDynamicaly($code)
   {
     $args = $this->_attributesIntoArray();
 
@@ -62,14 +62,14 @@
     $code->writePHP('$this->includeTemplate(' . $this->get('file') . ',' . $arg_str . ');');
   }
 
-  function _generateStaticContents($code)
+  function _generateStaticaly($code)
   {
     static $counter = 1;
 
     list($keys, $vals) = $this->_attributesIntoArgs();
 
     $method = $code->beginMethod('__staticInclude' . ($counter++), $keys);
-    parent :: generateContents($code);
+    parent :: generate($code);
     $code->endMethod();
 
     $code->writePHP('$this->' . $method . '(' . implode(', ', $vals) . ');');

Modified: 3.x/trunk/limb/macro/src/tags/core/slot.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/core/slot.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/core/slot.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -18,7 +18,7 @@
  */
 class lmbMacroSlotTag extends lmbMacroTag
 {
-  function generateContents($code)
+  function generate($code)
   {
     $slot = $this->getId();
     //calling slot handler in case of dynamic wrapping
@@ -31,7 +31,7 @@
     if($this->children)
     {
       $method = $code->beginMethod('__slotHandler' . uniqid());
-      parent :: generateContents($code);
+      parent :: generate($code);
       $code->endMethod();
       $code->writePHP('$this->' . $method . '()');
     }

Modified: 3.x/trunk/limb/macro/src/tags/core/template.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/core/template.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/core/template.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -17,14 +17,14 @@
  */
 class lmbMacroTemplateTag extends lmbMacroTag
 {
-  function generateContents($code)
+  function generate($code)
   {
     $name = $this->get('name');
 
     $args = $code->generateVar();
     $code->beginMethod('_template'. $name, array($args . '= array()'));
     $code->writePHP("if($args) extract($args);");
-    parent :: generateContents($code);
+    parent :: generate($code);
     $code->endMethod();
   }
 }

Modified: 3.x/trunk/limb/macro/src/tags/core/wrap.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/core/wrap.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/core/wrap.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -80,7 +80,7 @@
     return $this->findImmediateChildrenByClass('lmbMacroIntoTag');
   }
 
-  function generateContents($code)
+  function generate($code)
   {
     if($this->is_dynamic)
     {
@@ -93,14 +93,14 @@
         foreach($intos as $into)
         {
           $methods[$into->get('slot')] = $code->beginMethod('__slotHandler'. uniqid());
-          $into->generateContents($code);
+          $into->generate($code);
           $code->endMethod();
         }
       }
       else
       {
         $methods[$this->get('into')] = $code->beginMethod('__slotHandler'. uniqid());
-        parent :: generateContents($code);
+        parent :: generate($code);
         $code->endMethod();
       }
 
@@ -112,7 +112,7 @@
       $code->writePHP('$this->wrapTemplate(' . $this->getEscaped('with') . ', ' . $handlers_str . ');');
     }
     else
-      parent :: generateContents($code);
+      parent :: generate($code);
   }
 }
 

Added: 3.x/trunk/limb/macro/src/tags/form/form.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/form/form.tag.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/src/tags/form/form.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,46 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+lmb_require('limb/macro/src/tags/form/lmbMacroRuntimeWidgetTag.class.php');
+
+/**
+ * Macro analog for html <form> tag
+ * @tag form
+ * @package macro
+ * @version $Id$
+ */
+class lmbMacroFormTag extends lmbMacroRuntimeWidgetTag
+{
+  protected $widget_class_name = 'lmbMacroFormWidget';
+  protected $widget_include_file = 'limb/macro/src/tags/form/lmbMacroFormWidget.class.php';
+  
+  function __construct($location, $tag, $tag_info)
+  {
+    parent :: __construct($location, $tag, $tag_info, 'form');
+  }
+  
+  protected function _generateBeforeOpeningTag($code)
+  {
+    $form = $this->getWidgetVar();
+    
+    // передача указанного контейнера с данными в виджет формы
+    if($this->has('from'))
+    {
+      $from = $this->getEscaped('from');       
+      $code->writePHP("{$form}->setDatasource({$from});\n");
+    }
+    
+    $error_list_id = $form . '_error_list';
+    // передача установленного в шаблон списка ошибок формы
+    $code->writePHP("if(isset({$error_list_id})){$form}->setErrorList({$error_list_id});\n");
+    
+    parent :: _generateBeforeOpeningTag($code);
+  }
+}
+

Added: 3.x/trunk/limb/macro/src/tags/form/form_errors.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/form/form_errors.tag.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/src/tags/form/form_errors.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,31 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+/**
+ * @tag form:errors
+ * @parent_tag_class lmbMacroFormTag
+ * @restrict_self_nesting
+ * @package macro
+ * @version $Id$
+ */
+class lmbMacroFormErrorsTag extends lmbMacroTag
+{
+  function generate($code)
+  {
+    $form = $this->findParentByClass('lmbMacroFormTag')->getWidgetVar();
+    
+    $to = $this->get('to');
+    
+    $code->writePhp("{$to} = {$form}->getErrorList();\n");
+
+    parent :: generate($code);
+  }
+}
+
+

Added: 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormErrorList.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormErrorList.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormErrorList.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,61 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com 
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
+ */
+
+/**
+ * Form error list container
+ * @package macro
+ * @version $Id$
+ */
+class lmbMacroFormErrorList extends ArrayIterator
+{
+  protected $form;
+  
+  function addError($message, $fields = array(), $values = array())
+  {
+    $this->append(array('message' => $message, 'fields' => $fields, 'values' => $values));
+  }
+
+  function getFieldName($field_id)
+  {
+    if(!$this->form)
+      return $field_id;
+    
+    $form_field = $this->form->getChild($field_id);
+    if (is_object($form_field))
+      return $form_field->getDisplayName();
+    else
+      return $field_id;
+  }
+
+  function bindToForm($form)
+  {
+    $this->form = $form;
+    $form->setErrorList($this);
+  }
+
+  function current()
+  {
+    $error = parent :: current();
+
+    $text = $error['message'];
+    
+    foreach($error['fields'] as $key => $fieldName)
+    {
+      $replacement = $this->getFieldName($fieldName);
+      $text = str_replace('{' . $key . '}', $replacement, $text);
+    }
+
+    foreach($error['values'] as $key => $replacement)
+      $text = str_replace('{' . $key . '}', $replacement, $text);
+
+    $error['message'] = $text;
+    return $error;
+  }
+}
+

Added: 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormFieldWidget.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormFieldWidget.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormFieldWidget.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,38 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+ 
+lmb_require('limb/macro/src/tags/form/lmbMacroHtmlTagWidget.class.php');
+
+/**
+ * class lmbMacroFormFieldWidget.
+ * Base class for any form fields object at runtime 
+ *
+ * @package macro
+ * @version $Id$
+ */
+class lmbMacroFormFieldWidget extends lmbMacroHtmlTagWidget
+{
+  protected $has_errors = false;
+  
+  function getDisplayName()
+  {
+    return $this->id;
+  }
+  
+  function setErrorState($has_errors = true)
+  {
+    $this->has_errors = $has_errors;
+  }
+  
+  function hasErrors()
+  {
+    return $this->has_errors;
+  }
+}
+

Added: 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormLabelWidget.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormLabelWidget.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormLabelWidget.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,33 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+ 
+lmb_require('limb/macro/src/tags/form/lmbMacroHtmlTagWidget.class.php');
+
+/**
+ * class lmbMacroFormLabelFieldWidget.
+ * Runtime class for {{label}} tag that renders html <label> tag   
+ *
+ * @package macro
+ * @version $Id$
+ */
+class lmbMacroFormLabelWidget extends lmbMacroHtmlTagWidget
+{
+  protected $has_errors = false;
+  
+  function setErrorState($has_errors = true)
+  {
+    $this->has_errors = $has_errors;
+  }
+  
+  function hasErrors()
+  {
+    return $this->has_errors;
+  }   
+}
+

Added: 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormWidget.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormWidget.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/src/tags/form/lmbMacroFormWidget.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,137 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+ 
+lmb_require('limb/macro/src/tags/form/lmbMacroHtmlTagWidget.class.php');
+
+/**
+ * class lmbMacroFormWidget.
+ * Handles all logic with validation errors and knows about all child form elements widgets 
+ *
+ * @package macro
+ * @version $Id$
+ */
+class lmbMacroFormWidget extends lmbMacroHtmlTagWidget
+{
+  protected $error_list = array();
+
+  protected $children = array();
+
+  protected $datasource;
+
+  function __construct($id)
+  {
+    parent :: __construct($id);
+
+    $this->datasource = array();
+  }
+  
+  function getChild($id)
+  {
+    if(isset($this->children[$id]))
+      return $this->children[$id];
+  }
+  
+  function addChild($child)
+  {
+    $this->children[$child->getId()] = $child;
+  }
+
+  function setDatasource($datasource)
+  {
+    $this->datasource = $datasource;
+  }
+
+  function getDatasource()
+  {
+    return $this->datasource;
+  }
+
+  function getLabelFor($field_id)
+  {
+    foreach(array_keys($this->children) as $key)
+    {
+      $child = $this->children[$key];
+      if (($child instanceof lmbMacroFormLabelWidget) && ($child->getAttribute('for') == $field_id))
+        return $child;
+    }
+  }
+
+  function setErrorList($error_list)
+  {
+    $this->error_list = $error_list;
+
+    $this->_notifyFieldsAboutErrors();
+  }
+
+  protected function _notifyFieldsAboutErrors()
+  {
+    foreach($this->error_list as $error)
+    {
+      foreach($error['fields'] as $field_name)
+      {
+        if(!$field = $this->getChild($field_name))
+          continue;
+        
+        $field->setErrorState(true);
+        if($label = $this->getLabelFor($field->getId()))
+          $label->setErrorState(true);
+      }
+    }
+  }
+
+  function getErrorList()
+  {
+    return $this->error_list;
+  }
+
+  function getErrorsListForFields($for = '')
+  {
+    if (!count($this->error_list))
+      return array();
+
+    $result = array();
+    foreach($this->error_list as $error)
+    {
+      if(!$for)
+        $this->_appendErrorsForEachField($result, $error);
+      else
+        $this->_appendErrorForField($result, $error, $for);
+    }
+
+    return $result;
+  }
+
+  protected function _appendErrorsForEachField(&$result, $error)
+  {
+    $fields = $error['fields'];
+    foreach($fields as $alias => $field)
+    {
+      if(is_object($error))
+        $field_error = clone($error);
+      else
+        $field_error = $error;
+      $field_error['id'] = $field;
+      $result[] = $field_error;
+    }
+  }
+
+  protected function _appendErrorForField(&$result, $error, $field)
+  {
+    if(!in_array($field, $error['fields']))
+      return;
+
+    if(is_object($error))
+      $field_error = clone($error);
+    else
+      $field_error = $error;
+    $field_error['id'] = $field;
+    $result[] = $field_error;
+  }
+}
+

Added: 3.x/trunk/limb/macro/src/tags/form/lmbMacroHtmlTagWidget.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/form/lmbMacroHtmlTagWidget.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/src/tags/form/lmbMacroHtmlTagWidget.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,129 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com 
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
+ */
+
+/**
+ * Base class for runtime components that output XML(html) tags
+ * @package macro
+ * @version $Id$
+ */
+class lmbMacroHtmlTagWidget
+{
+  protected $attributes = array();
+
+  protected $id;
+  
+  function __construct($id)
+  {
+    $this->id = $id;
+  }
+  
+  function getId()
+  {
+    return $this->id;
+  }
+
+  function setAttributes($attributes)
+  {
+    if(is_array($attributes))    
+      $this->attributes = $attributes;
+  }
+
+  function setAttribute($attrib, $value)
+  {
+    $attrib = $this->_getCanonicalAttributeName($attrib);
+    $this->attributes[$attrib] = $value;
+  }
+
+  function getAttribute($attrib)
+  {
+    $attrib = $this->_getCanonicalAttributeName($attrib);
+    if (isset($this->attributes[$attrib]))
+      return $this->attributes[$attrib];
+  }
+
+  function getBoolAttribute($attrib, $default = FALSE)
+  {
+    if (!isset($this->attributes[strtolower($attrib)]))
+      return $default;
+
+    return self :: getBooleanValue($this->attributes[strtolower($attrib)]);
+  }
+
+  static function getBooleanValue($value)
+  {
+    if(is_bool($value))
+      return $value;
+
+    if(is_string($value))
+    {
+      switch(strtoupper($value))
+      {
+        case false:
+        case 'FALSE':
+        case 'N':
+        case 'NO':
+        case 'NONE':
+        case 'NA':
+        case '0':
+          return false;
+        default:
+          return true;
+      }
+    }
+  }
+
+  function removeAttribute($attrib)
+  {
+    $attrib = $this->_getCanonicalAttributeName($attrib);
+    unset($this->attributes[$attrib]);
+  }
+
+  function hasAttribute($attrib)
+  {
+    $attrib = $this->_getCanonicalAttributeName($attrib);
+    return array_key_exists($attrib, $this->attributes);
+  }
+
+  /**
+  * Writes the contents of the attributes to the screen, using
+  * htmlspecialchars to convert entities in values. Called by
+  * a compiled template
+  */
+  function renderAttributes()
+  {
+    foreach ($this->attributes as $name => $value)
+    {
+      echo ' ';
+      echo $name;
+      if (!is_null($value))
+      {
+        echo '="';
+        echo htmlspecialchars($value, ENT_QUOTES);
+        echo '"';
+      }
+    }
+  }
+
+  protected function _getCanonicalAttributeName($attrib)
+  {
+    // quick check if they happen to use the same case.
+    if (array_key_exists($attrib, $this->attributes))
+      return $attrib;
+
+    // slow check
+    foreach(array_keys($this->attributes) as $key)
+    {
+      if (strcasecmp($attrib, $key) == 0)
+        return $key;
+    }
+
+    return $attrib;
+  }
+}
+

Added: 3.x/trunk/limb/macro/src/tags/form/lmbMacroRuntimeWidgetTag.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/form/lmbMacroRuntimeWidgetTag.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/src/tags/form/lmbMacroRuntimeWidgetTag.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,137 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com 
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
+ */
+
+lmb_require('limb/macro/src/lmbMacroTag.class.php');
+
+/**
+ * @package macro
+ * @version $Id$
+ */
+class lmbMacroRuntimeWidgetTag extends lmbMacroTag
+{
+  protected $widget_include_file;
+  protected $widget_class_name;
+  protected $html_tag;
+  
+  function __construct($location, $tag, $tag_info, $html_tag)
+  {
+    parent :: __construct($location, $tag, $tag_info);
+
+    $this->html_tag = $html_tag;
+    
+    if(!$this->widget_class_name)
+      $this->raise('Please specify "$widget_class_name" property of the tag class "' . get_class($this) .'"');
+  }
+
+  protected function _generateBeforeContent($code_writer)
+  {
+    $this->_generateWidget($code_writer);
+    
+    $this->_generateBeforeOpeningTag($code_writer);
+    $this->_generateOpeningTag($code_writer);
+    $this->_generateAfterOpeningTag($code_writer);
+  }
+    
+  protected function _generateAfterContent($code_writer)
+  {
+    $this->_generateBeforeClosingTag($code_writer);
+    $this->_generateClosingTag($code_writer);
+    $this->_generateAfterClosingTag($code_writer);
+  }
+  
+  function getWidgetVar()
+  {
+    return '$this->' . $this->html_tag . '_' . $this->getWidgetId();
+  }
+  
+  function getWidgetId()
+  {
+    if ($this->hasConstant('widget_id'))
+      return $this->get('widget_id');
+    elseif($this->hasConstant('id'))
+      return $this->get('id');
+    elseif($this->hasConstant('name'))
+      return $this->get('name');
+    else
+    {
+      $widget_id = self :: generateNewWidgetId();
+      $this->set('widget_id', $widget_id);
+      return $widget_id;
+    }
+  }   
+
+  static function generateNewWidgetId()
+  {
+    static $counter = 1;
+    return 'id00' . $counter++;
+  }
+
+  function _generateWidget($code_writer)
+  {
+    if ($this->widget_include_file)
+      $code_writer->registerInclude($this->widget_include_file);
+
+    $id = $this->getWidgetId();
+    $widget = $this->getWidgetVar();
+    $code_writer->writeToInit("{$widget} = new {$this->widget_class_name}('{$id}');\n");
+    $code_writer->writeToInit("{$widget}->setAttributes(" . var_export($this->getConstantAttributes(), true) . ");\n");
+  }
+
+  protected function _generateOpeningTag($code)
+  {
+    $this->_generateDynamicAttributes($code);
+
+    $code->writeHTML("<{$this->html_tag}");
+
+    $code->writePHP($this->getWidgetVar() . '->renderAttributes();');
+
+    if (!$this->has_closing_tag)
+      $code->writeHTML(' /');
+
+    $code->writeHTML('>');
+  }
+  
+  protected function _generateDynamicAttributes($code)
+  {
+    $widget = $this->getWidgetVar();
+    foreach(array_keys($this->attributes) as $key)
+    {
+      if ($this->attributes[$key]->isDynamic())
+      {
+        $value = $this->attributes[$key]->getValue();
+        $code->writePHP("{$widget}->setAttribute('{$key}',");
+        $code->writePHP($this->attributes[$key]->getEscaped());
+        $code->writePHP(");\n");
+      }
+    } 
+  }
+
+  protected function _generateClosingTag($code)
+  {
+    if ($this->has_closing_tag)
+      $code->writeHTML("</{$this->html_tag}>");
+  }
+  
+  protected function _generateBeforeOpeningTag($code)
+  {
+  }
+
+  protected function _generateAfterOpeningTag($code)
+  {
+  }
+ 
+  protected function _generateBeforeClosingTag($code)
+  {
+  }
+
+  protected function _generateAfterClosingTag($code)
+  {
+  }
+}
+

Modified: 3.x/trunk/limb/macro/src/tags/list/list.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/list/list.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/list/list.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -34,7 +34,7 @@
     $this->count_source = true;
   }
 
-  function generateContents($code)
+  protected function _generateContent($code)
   {
     if(!$as = $this->get('as'))
       $as = '$item';
@@ -65,7 +65,7 @@
         if(!$found_item_tag)
         {
           $code->writePHP('if(' . $this->counter_var . ' == 0) {');
-          $child->generateContents($code);
+          $child->generate($code);
           $code->writePHP('}');
         }
         //otherwise we collect them to display later
@@ -75,7 +75,7 @@
       elseif(is_a($child, 'lmbMacroListItemTag'))
       {
         $found_item_tag = true;
-        $child->generateContents($code);
+        $child->generate($code);
       }
     }
 
@@ -86,7 +86,7 @@
     foreach($postponed_nodes as $node)
     {
       $code->writePHP('if(' . $this->counter_var . ' > 0) {');
-      $node->generateContents($code);
+      $node->generate($code);
       $code->writePHP('}');
     }
 
@@ -139,7 +139,7 @@
     if($list_empty = $this->findImmediateChildByClass('lmbMacroListEmptyTag'))
     {
       $code->writePHP('if(' . $this->counter_var . ' == 0) {');
-      $list_empty->generateContents($code);
+      $list_empty->generate($code);
       $code->writePHP('}');
     }
   }

Modified: 3.x/trunk/limb/macro/src/tags/list/list_even.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/list/list_even.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/list/list_even.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -18,13 +18,13 @@
  */
 class lmbMacroListRowEvenTag extends lmbMacroTag
 {
-  function generateContents($code)
+  protected function _generateContent($code)
   {
     $list = $this->findParentByClass('lmbMacroListTag');
     $counter_var = $list->getCounterVar();
 
     $code->writePHP('if(('. $counter_var . '+1) % 2 == 0) {');
-    parent :: generateContents($code);
+    parent :: _generateContent($code);
     $code->writePHP('}');
   }
 }

Modified: 3.x/trunk/limb/macro/src/tags/list/list_fill.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/list/list_fill.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/list/list_fill.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -20,7 +20,7 @@
  */
 class lmbMacroListFillTag extends lmbMacroTag
 {
-  function generateContents($code)
+  protected function _generateContent($code)
   {
     $ratio_var = $code->generateVar();
     if($ratio = $this->get('upto'))
@@ -44,7 +44,7 @@
     if($items_left = $this->get('items_left'))
       $code->writePhp($items_left . " = {$items_left_var};");
 
-    parent :: generateContents($code);
+    parent :: _generateContent($code);
 
     $code->writePhp('}'. "\n");
   }

Modified: 3.x/trunk/limb/macro/src/tags/list/list_glue.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/list/list_glue.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/list/list_glue.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -27,7 +27,7 @@
     $list->countSource();
   }
 
-  function generateContents($code)
+  protected function _generateContent($code)
   {
     $step_var = $this->getStepVar($code);
     $helper_var = $this->getHelperVar($code);
@@ -64,7 +64,7 @@
       }
     }
 
-    parent :: generateContents($code);
+    parent :: _generateContent($code);
 
     $code->writePhp("}\n");
   }

Modified: 3.x/trunk/limb/macro/src/tags/list/list_odd.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/list/list_odd.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/list/list_odd.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -18,13 +18,13 @@
  */
 class lmbMacroListRowOddTag extends lmbMacroTag
 {
-  function generateContents($code)
+  protected function _generateContent($code)
   {
     $list = $this->findParentByClass('lmbMacroListTag');
     $counter_var = $list->getCounterVar();
 
     $code->writePHP('if(('. $counter_var . ' + 1) % 2 != 0) {');
-    parent :: generateContents($code);
+    parent :: _generateContent($code);
     $code->writePHP('}');
   }
 }

Modified: 3.x/trunk/limb/macro/src/tags/tree/tree.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/tree/tree.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/tree/tree.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -16,7 +16,7 @@
  */
 class lmbMacroTreeTag extends lmbMacroTag
 {
-  function generateContents($code)
+  protected function _generateContent($code)
   {
     if(!$level = $this->get('level'))
       $level = '$level';
@@ -44,11 +44,11 @@
     //rendering tags before branch
     $code->writePHP('if(!' . $counter . ') {');
     foreach($before_branch as $tag)
-      $tag->generateContents($code);
+      $tag->generate($code);
     $code->writePHP('}');
 
     $branch->setRecursionMethod($method);
-    $branch->generateContents($code);
+    $branch->generate($code);
 
     $code->writePHP($counter . '++;');
     $code->writePHP('}');//foreach
@@ -56,7 +56,7 @@
     //rendering tags after branch
     $code->writePHP('if(' . $counter . ') {');
     foreach($after_branch as $tag)
-      $tag->generateContents($code);
+      $tag->generate($code);
     $code->writePHP('}');
 
     $code->endMethod();

Modified: 3.x/trunk/limb/macro/src/tags/tree/tree_branch.tag.php
===================================================================
--- 3.x/trunk/limb/macro/src/tags/tree/tree_branch.tag.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/src/tags/tree/tree_branch.tag.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -23,7 +23,7 @@
     $this->method = $name;
   }
 
-  function generateContents($code)
+  protected function _generateContent($code)
   {
     if(!$level = $this->parent->get('level'))
       $level = '$level';
@@ -41,18 +41,18 @@
     $code->writePHP('if(isset(' . $as . '["' . $kids_prop . '"])) {');
 
     foreach($before_item as $tag)
-      $tag->generateContents($code);
+      $tag->generate($code);
 
-    $item->generateContents($code);
+    $item->generate($code);
 
     $code->writePHP('$this->' . $this->method . '(' . $as . '["' . $kids_prop . '"], ' . $level . ' + 1);');
 
     foreach($after_item as $tag)
-      $tag->generateContents($code);
+      $tag->generate($code);
 
     $code->writePHP('} else {');
 
-    parent :: generateContents($code);
+    parent :: _generateContent($code);
 
     $code->writePHP('}');
   }

Modified: 3.x/trunk/limb/macro/tests/cases/lmbMacroTagAcceptanceTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/lmbMacroTagAcceptanceTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/lmbMacroTagAcceptanceTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -16,7 +16,7 @@
 
 class MacroTagFooTest extends lmbMacroTag
 {
-  function generateContents($code)
+  function generate($code)
   {
     $code->writeHtml('foo!');
   }
@@ -24,7 +24,7 @@
 
 class MacroTagBarTest extends lmbMacroTag
 {
-  function generateContents($code)
+  function generate($code)
   {
     $code->writeHtml('bar');
   }
@@ -32,7 +32,8 @@
 
 class MacroTagZooTest extends lmbMacroTag
 {
-  function generateContents($code)
+  // note that we overrided _generateContent since generate() methods pregenerates dynamic attributes
+  function _generateContent($code)
   {
     $code->writePHP('echo ' . $this->getEscaped('attr') . ';');
   }

Modified: 3.x/trunk/limb/macro/tests/cases/lmbMacroTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/lmbMacroTagTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/lmbMacroTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -139,32 +139,6 @@
     $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();
@@ -253,7 +227,7 @@
     $this->node->setId('TestId');
     $this->assertEqual($this->node->getId(), 'TestId');
   }
-
+  
   function testGetAttributeUnset()
   {
     $this->assertNull($this->node->get('foo'));
@@ -277,6 +251,15 @@
     $this->assertTrue($this->node->has('TRICKY'));
     $this->assertFalse($this->node->has('MISSING'));
   }
+  
+  function testHasConstantAttribute()
+  {
+    $this->node->set('foo', 'bar');
+    $this->node->set('tricky', '$this->bar');
+    
+    $this->assertTrue($this->node->hasConstant('foo'));
+    $this->assertFalse($this->node->hasConstant('tricky'));
+  }
 
   function testRemoveAttribute()
   {

Copied: 3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroIncludeTagTest.class.php (from rev 6553, 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroIncludeTagTest.class.php)
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroIncludeTagTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroIncludeTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,117 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+class lmbMacroTagIncludeTest extends lmbBaseMacroTest
+{
+  function testSimpleStaticInclude()
+  {
+    $bar = '<body>{{include file="foo.html"/}}</body>';
+    $foo = '<p>Hello, Bob</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Hello, Bob</p></body>');
+  }
+
+  function testNestedStaticInclude()
+  {
+    $bar = '<body>{{include file="foo.html"/}}</body>';
+    $foo = '<p>Hello, {{include file="name.html"/}}</p>';
+    $name = "Bob";
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+    $name_tpl = $this->_createTemplate($name, 'name.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Hello, Bob</p></body>');
+  }
+
+  function testStaticIncludePassVariables()
+  {
+    $bar = '<body><?php $var2=2;?>{{include file="foo.html" var1="1" var2="$var2"/}}</body>';
+    $foo = '<p>Numbers: <?php echo $var1;?> <?php echo $var2;?></p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Numbers: 1 2</p></body>');
+  }
+
+  function testStaticIncludeMixLocalAndTemplateVariables()
+  {
+    $bar = '<body><?php $var2=2;?>{{include file="foo.html" var1="1" var2="$var2"/}}</body>';
+    $foo = '<p>Numbers: <?php echo $var1;?> <?php echo $var2;?> <?php echo $this->var3;?></p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+
+    $macro->set('var3', 3);
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Numbers: 1 2 3</p></body>');
+  }
+
+  function testDynamicInclude()
+  {
+    $bar = '<body>{{include file="$this->file"/}}</body>';
+    $foo = '<p>Hello!</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('file', 'foo.html');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Hello!</p></body>');
+  }
+
+  function testDynamicIncludePassLocalVars()
+  {
+    $bar = '<body><?php $name = "Fred";?>{{include file="$this->file" name="$name"/}}</body>';
+    $foo = '<p>Hello, <?php echo $name;?>!</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('file', 'foo.html');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Hello, Fred!</p></body>');
+  }
+
+  function testDynamicIncludeMixLocalAndTemplateVars()
+  {
+    $bar = '<body><?php $name = "Fred";?>{{include file="$this->file" name="$name"/}}</body>';
+    $foo = '<p>Hello, <?php echo $name . " " . $this->lastname;?>!</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('file', 'foo.html');
+    $macro->set('lastname', 'Atkins');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Hello, Fred Atkins!</p></body>');
+  }
+}
+

Copied: 3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroTemplateTagTest.class.php (from rev 6553, 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTemplateTagTest.class.php)
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroTemplateTagTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroTemplateTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,35 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+class lmbMacroTemplateTagTest extends lmbBaseMacroTest
+{
+  function testApplyTemplate()
+  {
+    $content = '{{template name="tpl1"}}' .  
+               '{$bar}' .                   
+               '{{/template}}' .              
+               '{{template name="tpl2"}}' .  
+               '{$foo}{$hey}' .                   
+               '{{/template}}' .
+               '{{apply template="tpl2" hey="$#hey" foo="$#foo"/}}' .
+               '{{apply template="tpl1" bar="$#bar"/}}' 
+               ;
+
+    $tpl = $this->_createTemplate($content, 'tree.html');
+
+    $macro = $this->_createMacro($tpl);
+    $macro->set('hey', 'HEY');
+    $macro->set('bar', 'BAR');
+    $macro->set('foo', 'FOO');
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'FOOHEYBAR');
+  }
+}
+

Copied: 3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroWrapTagTest.class.php (from rev 6553, 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroWrapTagTest.class.php)
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroWrapTagTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/tests/cases/tags/core/lmbMacroWrapTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,197 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+class lmbMacroWrapTagTest extends lmbBaseMacroTest
+{
+  function testSimpleStaticWrap()
+  {
+    $bar = '{{wrap with="foo.html" into="slot1"}}Bob{{/wrap}}';
+    $foo = '<p>Hello, {{slot id="slot1"/}}</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<p>Hello, Bob</p>');
+  }
+
+  function testStaticWrapWithVariables()
+  {
+    $bar = '{{wrap with="foo.html" into="slot1"}}<?php echo $this->bob?>{{/wrap}}';
+    $foo = '<p>Hello, {{slot id="slot1"/}}</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('bob', 'Bob');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<p>Hello, Bob</p>');
+  }
+
+  function testNestedStaticWrap()
+  {
+    $bar = '{{wrap with="foo.html" into="slot1"}}<?php echo $this->bob?>{{/wrap}}';
+    $foo = '{{wrap with="zoo.html" into="slot2"}}<p>Hello, {{slot id="slot1"/}}</p>{{/wrap}}';
+    $zoo = '<body>{{slot id="slot2"/}}</body>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+    $zoo_tpl = $this->_createTemplate($zoo, 'zoo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('bob', 'Bob');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Hello, Bob</p></body>');
+  }
+
+  function testMultiStaticWrap()
+  {
+    $bar = '{{wrap with="foo.html"}}{{into slot="slot1"}}Bob{{/into}}{{into slot="slot2"}}Thorton{{/into}}{{/wrap}}';
+    $foo = '<p>Hello, {{slot id="slot2"/}} {{slot id="slot1"/}}</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<p>Hello, Thorton Bob</p>');
+  }
+
+  function testSimpleDynamicWrap()
+  {
+    $bar = '{{wrap with="$this->layout" into="slot1"}}Bob{{/wrap}}';
+    $foo = '<p>Hello, {{slot id="slot1"/}}</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('layout', 'foo.html');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<p>Hello, Bob</p>');
+  }
+
+  function testMultiDynamicWrap()
+  {
+    $bar = '{{wrap with="$this->layout"}}{{into slot="slot1"}}Bob{{/into}}{{into slot="slot2"}}Thorton{{/into}}{{/wrap}}';
+    $foo = '<p>Hello, {{slot id="slot2"/}} {{slot id="slot1"/}}</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('layout', 'foo.html');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<p>Hello, Thorton Bob</p>');
+  }
+
+  function testMixStaticAndDynamicWrap()
+  {
+    $bar = '{{wrap with="$this->layout" into="slot1"}}<?php echo $this->bob?>{{/wrap}}';
+    $foo = '{{wrap with="zoo.html" into="slot2"}}<p>Hello, {{slot id="slot1"/}}</p>{{/wrap}}';
+    $zoo = '<body>{{slot id="slot2"/}}</body>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+    $zoo_tpl = $this->_createTemplate($zoo, 'zoo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('layout', 'foo.html');
+    $macro->set('bob', 'Bob');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Hello, Bob</p></body>');
+  }
+
+  function testNestedDynamicWrap()
+  {
+    $bar = '{{wrap with="$this->layout1" into="slot1"}}<?php echo $this->bob?>{{/wrap}}';
+    $foo = '{{wrap with="$this->layout2" into="slot2"}}<p>Hello, {{slot id="slot1"/}}</p>{{/wrap}}';
+    $zoo = '<body>{{slot id="slot2"/}}</body>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+    $zoo_tpl = $this->_createTemplate($zoo, 'zoo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('layout1', 'foo.html');
+    $macro->set('layout2', 'zoo.html');
+    $macro->set('bob', 'Bob');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<body><p>Hello, Bob</p></body>');
+  }
+
+  function testStaticallyWrappedChildAccessesParentData()
+  {
+    $bar = '{{wrap with="foo.html" into="slot1"}}<?php echo $this->bob?>{{/wrap}}';
+    $foo = '<?php $this->bob = "Bob";?><p>Hello, {{slot id="slot1"/}}</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<p>Hello, Bob</p>');
+  }
+
+  function testDynamicallyWrappedChildAccessesParentData()
+  {
+    $bar = '{{wrap with="$this->layout" into="slot1"}}<?php echo $this->bob?>{{/wrap}}';
+    $foo = '<?php $this->bob = "Bob";?><p>Hello, {{slot id="slot1"/}}</p>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('layout', 'foo.html');
+
+    $out = $macro->render();
+    $this->assertEqual($out, '<p>Hello, Bob</p>');
+  }
+
+  function testStaticallyWrappedChildLocalVarsAreIsolated()
+  {
+    $bar = '{{wrap with="foo.html" into="slot1"}}<?php $foo = "Todd";?>{{/wrap}}';
+    $foo = '<?php $foo = "Bob";?>{{slot id="slot1"/}}<?php echo $foo;?>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'Bob');
+  }
+
+  function testDynamicallyWrappedChildLocalVarsAreIsolated()
+  {
+    $bar = '{{wrap with="$this->layout" into="slot1"}}<?php $foo = "Todd";?>{{/wrap}}';
+    $foo = '<?php $foo = "Bob";?>{{slot id="slot1"/}}<?php echo $foo;?>';
+
+    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
+    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
+
+    $macro = $this->_createMacro($bar_tpl);
+    $macro->set('layout', 'foo.html');
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'Bob');
+  }
+}
+

Added: 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormErrorListTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormErrorListTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormErrorListTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,87 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+require_once('limb/macro/src/tags/form/lmbMacroFormErrorList.class.php');
+require_once('limb/macro/src/tags/form/lmbMacroFormWidget.class.php');
+require_once('limb/macro/src/tags/form/lmbMacroFormFieldWidget.class.php');
+
+Mock :: generate('lmbMacroFormWidget', 'MockMacroFormWidget');
+Mock :: generate('lmbMacroFormFieldWidget', 'MockMacroFormFieldWidget');
+
+class lmbMacroFormErrorListTest extends lmbBaseMacroTest
+{
+  function testAddSimpleError()
+  {
+    $error_list = new lmbMacroFormErrorList();
+    $error_list->addError($message ='Error in some field');
+    
+    $this->assertErrorsInList($error_list, array(array('message' => $message,
+                                                       'fields' => array(),
+                                                        'values' => array())));
+  }
+  
+  function testAddErrorWithFieldPlaceholder()
+  {
+    $error_list = new lmbMacroFormErrorList();
+    $error_list->addError('Error in {Field}', array('Field' => 'title'));
+    
+    $this->assertErrorsInList($error_list, array(array('message' => 'Error in title',
+                                                        'fields' => array('Field' => 'title'),
+                                                        'values' => array())));
+  }
+
+  function testBindToForm()
+  {
+    $form = new MockMacroFormWidget();
+    $field1 = new MockMacroFormFieldWidget();
+    $field2 = new MockMacroFormFieldWidget();
+    
+    $error_list = new lmbMacroFormErrorList();
+    $error_list->addError('Error in {Field}', array('Field' => 'title'));
+    $error_list->addError('Other error in {Field}', array('Field' => 'name'));
+    
+    $form->setReturnValue('getChild', $field1, array('title'));
+    $form->setReturnValue('getChild', $field2, array('name'));
+
+    $field1->setReturnValue('getDisplayName', 'TitleField');
+    $field2->setReturnValue('getDisplayName', 'NameField');
+    
+    $error_list->bindToForm($form);
+    
+    $this->assertErrorsInList($error_list, array(array('message' => 'Error in TitleField',
+                                                        'fields' => array('Field' => 'title'),
+                                                        'values' => array()),
+                                                 array('message' => 'Other error in NameField',
+                                                        'fields' => array('Field' => 'name'),
+                                                        'values' => array())));
+  }
+  
+  function testAddErrorWithFieldAndValuePlaceholders()
+  {
+    $error_list = new lmbMacroFormErrorList();
+    $error_list->addError('{Field} should be between {value_min} and {value_max}', 
+                          array('Field' => 'title'),
+                          array('value_min' => 10, 'value_max' => 100));
+    
+    $this->assertErrorsInList($error_list, array(array('message' => 'title should be between 10 and 100',
+                                                       'fields' => array('Field' => 'title'),
+                                                       'values' => array('value_min' => 10, 'value_max' => 100))));
+  }
+  
+  
+  function assertErrorsInList($error_list, $etalon)
+  {
+    $errors = array();
+    foreach($error_list as $error)
+      $errors[] = $error;
+
+    $this->assertEqual($errors, $etalon);
+  }
+}
+

Added: 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormErrorsTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormErrorsTagTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormErrorsTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,32 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+ 
+require_once('limb/macro/src/tags/form/lmbMacroFormErrorList.class.php'); 
+
+class lmbMacroFormErrorsTagTest extends lmbBaseMacroTest
+{
+  function testSimpleCase()
+  {
+    $template = '{{form name="my_form"}}'.
+                '{{form:errors to="$form_errors"/}}'.
+                '{{list using="$form_errors" as="$item"}}{{list:item}}{$item.message}{{/list:item}}{{/list}}'.
+                '{{/form}}';
+
+    $page = $this->_createMacroTemplate($template, 'tpl.html');
+    
+    $error_list = new lmbMacroFormErrorList();
+    $error_list->addError('Error in title field');
+    $error_list->addError('Error in name field');
+    
+    $page->set('form_my_form_error_list', $error_list);
+ 
+    $out = $page->render();
+    $this->assertEqual($out, '<form name="my_form">Error in title fieldError in name field</form>');
+  }   
+}

Added: 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormTagTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,54 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+require_once('limb/macro/src/tags/form/lmbMacroFormErrorList.class.php'); 
+ 
+
+class lmbMacroFormTagTest extends lmbBaseMacroTest
+{
+  function testSimpleForm()
+  {
+    $template = '{{form name="my_form"}}Hi{{/form}}';
+
+    $page = $this->_createMacroTemplate($template, 'tpl.html');
+ 
+    $out = $page->render();
+    $this->assertEqual($out, '<form name="my_form">Hi</form>');
+  }   
+  
+  function testFormGeneratesWidgetVar()
+  {
+    $template = '{{form name="my_form"}}<?php if(isset($this->form_my_form)) echo 1111; ?>{{/form}}';
+
+    $page = $this->_createMacroTemplate($template, 'tpl.html');
+ 
+    $out = $page->render();
+    $this->assertEqual($out, '<form name="my_form">1111</form>');
+  }
+  
+  function testFormTakesErrorListFromTemplateVariable()
+  {
+    $template = '{{form name="my_form"}}'.
+                '<?php $error_list = $this->form_my_form->getErrorList(); '.
+                'if($error_list[0]["message"] == $this->error_message) echo 1111;'.
+                '?>'.
+                '{{/form}}';
+
+    $page = $this->_createMacroTemplate($template, 'tpl.html');
+    
+    $error_list = new lmbMacroFormErrorList();
+    $error_list->addError($message = 'Any error message');
+    
+    $page->set('error_message', $message);
+    $page->set('form_my_form_error_list', $error_list);
+ 
+    $out = $page->render();
+    $this->assertEqual($out, '<form name="my_form">1111</form>');
+  }  
+}

Added: 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormWidgetTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormWidgetTagTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/tests/cases/tags/form/lmbMacroFormWidgetTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,115 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+require_once('limb/macro/src/tags/form/lmbMacroFormWidget.class.php');
+require_once('limb/macro/src/tags/form/lmbMacroFormErrorList.class.php');
+require_once('limb/macro/src/tags/form/lmbMacroFormFieldWidget.class.php');
+require_once('limb/macro/src/tags/form/lmbMacroFormLabelWidget.class.php');
+
+class lmbMacroFormWidgetTest extends lmbBaseMacroTest
+{
+  function testAddAndGetChild()
+  {
+    $form = new lmbMacroFormWidget('my_id');
+    $field1 = new lmbMacroFormFieldWidget('Input1');
+    $field2 = new lmbMacroFormFieldWidget('Input3');
+    $form->addChild($field1);
+    $form->addChild($field2);
+    
+    $this->assertEqual($form->getChild('Input3'), $field2);
+    $this->assertNull($form->getChild('NoSuchInput'));
+  }
+  
+  function testGetLabelFor()
+  {
+    $form = new lmbMacroFormWidget('my_id');
+    $field1 = new lmbMacroFormFieldWidget('Input1');
+    $label1 = new lmbMacroFormLabelWidget('Label1');
+    $label1->setAttribute('for', 'Input1');
+    
+    $field2 = new lmbMacroFormFieldWidget('Input3');
+    $label2 = new lmbMacroFormLabelWidget('Label3');
+    $label2->setAttribute('for', 'Input3');
+
+    $form->addChild($field1);
+    $form->addChild($field2);
+    $form->addChild($label1);
+    $form->addChild($label2);
+    
+    $this->assertEqual($form->getLabelFor('Input3'), $label2);
+    $this->assertEqual($form->getLabelFor('Input1'), $label1);
+    $this->assertNull($form->getLabelFor('NoSuchInput'));
+  }
+  
+  function testSetErrorsNotifyFieldsAboutErrors()
+  {
+    $error_list = new lmbMacroFormErrorList();
+    $error_fields = array('x'=>'Input1', 'z'=>'Input3');
+    $error_list->addError('message', $error_fields);
+
+    $form = new lmbMacroFormWidget('my_id');
+    $field1 = new lmbMacroFormFieldWidget('Input1');
+    $field2 = new lmbMacroFormFieldWidget('Input3');
+    $form->addChild($field1);
+    $form->addChild($field2);
+    
+    $form->setErrorList($error_list);
+    
+    $this->assertTrue($field1->hasErrors());
+    $this->assertTrue($field2->hasErrors());
+  }
+
+  function testSetErrorsNotifyFieldsAndLabelsAboutErrors()
+  {
+    $error_list = new lmbMacroFormErrorList();
+    $error_list->addError('message', array('x'=>'Input1'));
+
+    $form = new lmbMacroFormWidget('my_id');
+    $field1 = new lmbMacroFormFieldWidget('Input1');
+    $label1 = new lmbMacroFormLabelWidget('Label1');
+    $label1->setAttribute('for', 'Input1');
+
+    $field2 = new lmbMacroFormFieldWidget('Input3');
+    $label2 = new lmbMacroFormLabelWidget('Label3');
+    $label2->setAttribute('for', 'Input3');
+    
+    $form->addChild($field1);
+    $form->addChild($field2);
+    $form->addChild($label1);
+    $form->addChild($label2);
+    
+    $form->setErrorList($error_list);
+    
+    $this->assertTrue($field1->hasErrors());
+    $this->assertFalse($field2->hasErrors());
+    $this->assertTrue($label1->hasErrors());
+    $this->assertFalse($label2->hasErrors());
+  }
+
+  function testGetFieldErrorsForField()
+  {
+    $error_list = new lmbMacroFormErrorList();
+    $error_list->addError('message1', array('x'=>'Input1'));
+    $error_list->addError('message2', array('x'=>'Input1', 'z'=>'Input2'));
+
+    $form = new lmbMacroFormWidget('my_id');
+    $form->setErrorList($error_list);
+
+    $errors = $form->getErrorsListForFields();
+    $this->assertEqual(sizeof($errors), 3);
+    
+    $errors = $form->getErrorsListForFields('Input1');
+
+    $this->assertEqual($errors[0]['message'], 'message1');
+    $this->assertEqual($errors[1]['message'], 'message2');
+
+    $errors = $form->getErrorsListForFields('Input2');
+    $this->assertEqual($errors[0]['message'], 'message2');
+  }
+}

Copied: 3.x/trunk/limb/macro/tests/cases/tags/list/lmbMacroListTagTest.class.php (from rev 6553, 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroListTagTest.class.php)
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/list/lmbMacroListTagTest.class.php	                        (rev 0)
+++ 3.x/trunk/limb/macro/tests/cases/tags/list/lmbMacroListTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -0,0 +1,204 @@
+<?php
+/*
+ * Limb PHP Framework
+ *
+ * @link http://limb-project.com
+ * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
+ * @license    LGPL http://www.gnu.org/copyleft/lesser.html
+ */
+
+class lmbMacroListTagTest extends lmbBaseMacroTest
+{
+  function testSimpleList()
+  {
+    $list = '{{list using="$#list" as="$item"}}{{list:item}}<?=$item?> {{/list:item}}{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('Bob', 'Todd'));
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'Bob Todd ');
+  }
+
+  function testListUsingDefaultItem()
+  {
+    $list = '{{list using="$#list"}}{{list:item}}<?=$item?> {{/list:item}}{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('Bob', 'Todd'));
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'Bob Todd ');
+  }
+
+  function testEmptyList()
+  {
+    $list = '{{list using="$#list" as="$item"}}{{list:item}}<?=$item?>{{/list:item}}' .
+            '{{list:empty}}Nothing{{/list:empty}}{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array());
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'Nothing');
+  }
+
+  function testShowCounter()
+  {
+    $list = '{{list using="$#list" counter="$ctr"}}{{list:item}}<?=$ctr?>)<?=$item?> {{/list:item}}{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('Bob', 'Todd'));
+
+    $out = $macro->render();
+    $this->assertEqual($out, '1)Bob 2)Todd ');
+  }
+
+  function testTextNodesInsideListTag()
+  {
+    $list = '{{list using="$#list" as="$item"}}List: {{list:item}}<?=$item?> {{/list:item}} !{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('Bob', 'Todd'));
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'List: Bob Todd  !');
+  }
+
+  function testTextNodesInsideListTagWithEmptyListTag()
+  {
+    $list = '{{list using="$#list" as="$item"}}List: {{list:item}}<?=$item?> {{/list:item}} !' .
+            '{{list:empty}}Nothing{{/list:empty}}{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array());
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'Nothing');
+  }
+
+  function testParity()
+  {
+    $list = '{{list using="$#list" as="$item" parity="$parity"}}{{list:item}}{$parity}-{$item} {{/list:item}} !{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('Bob', 'Todd', 'Jeff'));
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'odd-Bob even-Todd odd-Jeff  !');
+  }
+
+  function testEvenAndOddTags()
+  {
+    $list = '{{list using="$#list" as="$item" parity="$parity"}}{{list:item}}'.
+              '{{list:odd}}Odd{{/list:odd}}{{list:even}}Even{{/list:even}}-{$item} {{/list:item}} !{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('Bob', 'Todd', 'Jeff'));
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'Odd-Bob Even-Todd Odd-Jeff  !');
+  }
+
+  function testListWithGlue()
+  {
+    $list = '{{list using="$#list" as="$item"}}List:'.
+            '{{list:item}}<?=$item?>{{list:glue}}||{{/list:glue}}'.
+            '{{/list:item}}!' .
+            '{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('Bob', 'Todd', 'Marry'));
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'List:Bob||Todd||Marry!');
+  }
+
+  function testListWithGlueWithStep()
+  {
+    $list = '{{list using="$#list" as="$item"}}List:'.
+            '{{list:item}}<?=$item?>{{list:glue step="2"}}||{{/list:glue}}'.
+            '{{/list:item}}!' .
+            '{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('Bob', 'Todd', 'Marry'));
+
+    $out = $macro->render();
+    $this->assertEqual($out, 'List:BobTodd||Marry!');
+  }
+
+  function testTwoDependentGlues()
+  {
+    $list = '{{list using="$#list" as="$item"}}List#'.
+            '{{list:item}}<?=$item?>' .
+            '{{list:glue step="2"}}|{{/list:glue}}'.
+            '{{list:glue}}:{{/list:glue}}'.
+            '{{/list:item}}!'.
+            '{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('John', 'Pavel', 'Peter', 'Harry', 'Roman', 'Sergey'));
+
+    $this->assertEqual($macro->render(), 'List#John:Pavel|Peter:Harry|Roman:Sergey!');
+  }
+
+  function testListFillTagWithRatio()
+  {
+    $list = '{{list using="$#list" as="$item"}}List#'.
+                '{{list:item}}{$item}'.
+                '{{list:glue step="3"}}++{{/list:glue}}'.
+                '{{list:glue}}:{{/list:glue}}'.
+                '{{/list:item}}'.
+                '{{list:fill upto="3" items_left="$items_left"}}{$items_left}{{/list:fill}}'.
+                '{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('John', 'Pavel', 'Peter', 'Harry'));
+
+    $this->assertEqual($macro->render(), 'List#John:Pavel:Peter++Harry2');
+  }
+
+  function testListFillTagWithTotalElementsLessThanRatio()
+  {
+    $list = '{{list using="$#list" as="$item"}}List#'.
+                '{{list:item}}{$item}'.
+                '{{list:glue step="3"}}++{{/list:glue}}'.
+                '{{list:glue}}:{{/list:glue}}'.
+                '{{/list:item}}'.
+                '{{list:fill upto="3" items_left="$items_left"}}{$items_left}{{/list:fill}}'.
+                '{{/list}}';
+
+    $list_tpl = $this->_createTemplate($list, 'list.html');
+
+    $macro = $this->_createMacro($list_tpl);
+    $macro->set('list', array('John', 'Pavel'));
+
+    $this->assertEqual($macro->render(), 'List#John:Pavel');
+  }
+}
+

Deleted: 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroIncludeTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroIncludeTagTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroIncludeTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -1,117 +0,0 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
-
-class lmbMacroTagIncludeTest extends lmbBaseMacroTest
-{
-  function testSimpleStaticInclude()
-  {
-    $bar = '<body>{{include file="foo.html"/}}</body>';
-    $foo = '<p>Hello, Bob</p>';
-
-    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
-    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
-
-    $macro = $this->_createMacro($bar_tpl);
-
-    $out = $macro->render();
-    $this->assertEqual($out, '<body><p>Hello, Bob</p></body>');
-  }
-
-  function testNestedStaticInclude()
-  {
-    $bar = '<body>{{include file="foo.html"/}}</body>';
-    $foo = '<p>Hello, {{include file="name.html"/}}</p>';
-    $name = "Bob";
-
-    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
-    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
-    $name_tpl = $this->_createTemplate($name, 'name.html');
-
-    $macro = $this->_createMacro($bar_tpl);
-
-    $out = $macro->render();
-    $this->assertEqual($out, '<body><p>Hello, Bob</p></body>');
-  }
-
-  function testStaticIncludePassVariables()
-  {
-    $bar = '<body><?php $var2=2;?>{{include file="foo.html" var1="1" var2="$var2"/}}</body>';
-    $foo = '<p>Numbers: <?php echo $var1;?> <?php echo $var2;?></p>';
-
-    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
-    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
-
-    $macro = $this->_createMacro($bar_tpl);
-
-    $out = $macro->render();
-    $this->assertEqual($out, '<body><p>Numbers: 1 2</p></body>');
-  }
-
-  function testStaticIncludeMixLocalAndTemplateVariables()
-  {
-    $bar = '<body><?php $var2=2;?>{{include file="foo.html" var1="1" var2="$var2"/}}</body>';
-    $foo = '<p>Numbers: <?php echo $var1;?> <?php echo $var2;?> <?php echo $this->var3;?></p>';
-
-    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
-    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
-
-    $macro = $this->_createMacro($bar_tpl);
-
-    $macro->set('var3', 3);
-    $out = $macro->render();
-    $this->assertEqual($out, '<body><p>Numbers: 1 2 3</p></body>');
-  }
-
-  function testDynamicInclude()
-  {
-    $bar = '<body>{{include file="$this->file"/}}</body>';
-    $foo = '<p>Hello!</p>';
-
-    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
-    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
-
-    $macro = $this->_createMacro($bar_tpl);
-    $macro->set('file', 'foo.html');
-
-    $out = $macro->render();
-    $this->assertEqual($out, '<body><p>Hello!</p></body>');
-  }
-
-  function testDynamicIncludePassLocalVars()
-  {
-    $bar = '<body><?php $name = "Fred";?>{{include file="$this->file" name="$name"/}}</body>';
-    $foo = '<p>Hello, <?php echo $name;?>!</p>';
-
-    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
-    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
-
-    $macro = $this->_createMacro($bar_tpl);
-    $macro->set('file', 'foo.html');
-
-    $out = $macro->render();
-    $this->assertEqual($out, '<body><p>Hello, Fred!</p></body>');
-  }
-
-  function testDynamicIncludeMixLocalAndTemplateVars()
-  {
-    $bar = '<body><?php $name = "Fred";?>{{include file="$this->file" name="$name"/}}</body>';
-    $foo = '<p>Hello, <?php echo $name . " " . $this->lastname;?>!</p>';
-
-    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
-    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
-
-    $macro = $this->_createMacro($bar_tpl);
-    $macro->set('file', 'foo.html');
-    $macro->set('lastname', 'Atkins');
-
-    $out = $macro->render();
-    $this->assertEqual($out, '<body><p>Hello, Fred Atkins!</p></body>');
-  }
-}
-

Deleted: 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroListTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroListTagTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroListTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -1,204 +0,0 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
-
-class lmbMacroListTagTest extends lmbBaseMacroTest
-{
-  function testSimpleList()
-  {
-    $list = '{{list using="$#list" as="$item"}}{{list:item}}<?=$item?> {{/list:item}}{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('Bob', 'Todd'));
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'Bob Todd ');
-  }
-
-  function testListUsingDefaultItem()
-  {
-    $list = '{{list using="$#list"}}{{list:item}}<?=$item?> {{/list:item}}{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('Bob', 'Todd'));
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'Bob Todd ');
-  }
-
-  function testEmptyList()
-  {
-    $list = '{{list using="$#list" as="$item"}}{{list:item}}<?=$item?>{{/list:item}}' .
-            '{{list:empty}}Nothing{{/list:empty}}{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array());
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'Nothing');
-  }
-
-  function testShowCounter()
-  {
-    $list = '{{list using="$#list" counter="$ctr"}}{{list:item}}<?=$ctr?>)<?=$item?> {{/list:item}}{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('Bob', 'Todd'));
-
-    $out = $macro->render();
-    $this->assertEqual($out, '1)Bob 2)Todd ');
-  }
-
-  function testTextNodesInsideListTag()
-  {
-    $list = '{{list using="$#list" as="$item"}}List: {{list:item}}<?=$item?> {{/list:item}} !{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('Bob', 'Todd'));
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'List: Bob Todd  !');
-  }
-
-  function testTextNodesInsideListTagWithEmptyListTag()
-  {
-    $list = '{{list using="$#list" as="$item"}}List: {{list:item}}<?=$item?> {{/list:item}} !' .
-            '{{list:empty}}Nothing{{/list:empty}}{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array());
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'Nothing');
-  }
-
-  function testParity()
-  {
-    $list = '{{list using="$#list" as="$item" parity="$parity"}}{{list:item}}{$parity}-{$item} {{/list:item}} !{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('Bob', 'Todd', 'Jeff'));
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'odd-Bob even-Todd odd-Jeff  !');
-  }
-
-  function testEvenAndOddTags()
-  {
-    $list = '{{list using="$#list" as="$item" parity="$parity"}}{{list:item}}'.
-              '{{list:odd}}Odd{{/list:odd}}{{list:even}}Even{{/list:even}}-{$item} {{/list:item}} !{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('Bob', 'Todd', 'Jeff'));
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'Odd-Bob Even-Todd Odd-Jeff  !');
-  }
-
-  function testListWithGlue()
-  {
-    $list = '{{list using="$#list" as="$item"}}List:'.
-            '{{list:item}}<?=$item?>{{list:glue}}||{{/list:glue}}'.
-            '{{/list:item}}!' .
-            '{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('Bob', 'Todd', 'Marry'));
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'List:Bob||Todd||Marry!');
-  }
-
-  function testListWithGlueWithStep()
-  {
-    $list = '{{list using="$#list" as="$item"}}List:'.
-            '{{list:item}}<?=$item?>{{list:glue step="2"}}||{{/list:glue}}'.
-            '{{/list:item}}!' .
-            '{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('Bob', 'Todd', 'Marry'));
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'List:BobTodd||Marry!');
-  }
-
-  function testTwoDependentGlues()
-  {
-    $list = '{{list using="$#list" as="$item"}}List#'.
-            '{{list:item}}<?=$item?>' .
-            '{{list:glue step="2"}}|{{/list:glue}}'.
-            '{{list:glue}}:{{/list:glue}}'.
-            '{{/list:item}}!'.
-            '{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('John', 'Pavel', 'Peter', 'Harry', 'Roman', 'Sergey'));
-
-    $this->assertEqual($macro->render(), 'List#John:Pavel|Peter:Harry|Roman:Sergey!');
-  }
-
-  function testListFillTagWithRatio()
-  {
-    $list = '{{list using="$#list" as="$item"}}List#'.
-                '{{list:item}}{$item}'.
-                '{{list:glue step="3"}}++{{/list:glue}}'.
-                '{{list:glue}}:{{/list:glue}}'.
-                '{{/list:item}}'.
-                '{{list:fill upto="3" items_left="$items_left"}}{$items_left}{{/list:fill}}'.
-                '{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('John', 'Pavel', 'Peter', 'Harry'));
-
-    $this->assertEqual($macro->render(), 'List#John:Pavel:Peter++Harry2');
-  }
-
-  function testListFillTagWithTotalElementsLessThanRatio()
-  {
-    $list = '{{list using="$#list" as="$item"}}List#'.
-                '{{list:item}}{$item}'.
-                '{{list:glue step="3"}}++{{/list:glue}}'.
-                '{{list:glue}}:{{/list:glue}}'.
-                '{{/list:item}}'.
-                '{{list:fill upto="3" items_left="$items_left"}}{$items_left}{{/list:fill}}'.
-                '{{/list}}';
-
-    $list_tpl = $this->_createTemplate($list, 'list.html');
-
-    $macro = $this->_createMacro($list_tpl);
-    $macro->set('list', array('John', 'Pavel'));
-
-    $this->assertEqual($macro->render(), 'List#John:Pavel');
-  }
-}
-

Deleted: 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPagerHelperTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPagerHelperTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPagerHelperTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -1,262 +0,0 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com 
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
- */
-
-require_once('limb/macro/src/tags/pager/lmbMacroPagerHelper.class.php');
-
-class lmbMacroPagerHelperTest extends UnitTestCase
-{
-  protected $pager_id;
-  protected $pager;
-  protected $old_get;
-  protected $old_server;
-
-  function setUp()
-  {
-    $this->old_get = $_GET;
-    $this->old_server = $_SERVER;
-
-    $_SERVER['REQUEST_URI'] = 'http://test.com';
-    $_GET = array();
-
-    $this->pager_id = 'test_pager';
-    $this->pager = new lmbMacroPagerHelper($this->pager_id);
-  }
-
-  function tearDown()
-  {
-    $_GET = $this->old_get;
-    $_SERVER = $this->old_server;
-  }
-
-  function testPrepare()
-  {
-    $this->pager->setCurrentPage(2);
-    $this->pager->setItemsPerPage(10);
-    $this->pager->setPagesPerSection(5);
-    $this->pager->setTotalItems(100);
-
-    $this->pager->prepare();
-
-    $this->assertEqual($this->pager->getCurrentPage(), 2);
-    $this->assertFalse($this->pager->isDisplayedPage());
-    $this->assertEqual($this->pager->getPage(), 1);
-    $this->assertEqual($this->pager->getTotalPages(), 10);
-    $this->assertEqual($this->pager->getPagesPerSection(), 5);
-    $this->assertTrue($this->pager->hasMoreThanOnePage());
-    $this->assertEqual($this->pager->getSectionBeginPage(), 1);
-    $this->assertEqual($this->pager->getSectionEndPage(), 5);
-    $this->assertTrue($this->pager->hasNext());
-    $this->assertTrue($this->pager->hasPrev());
-    $this->assertEqual($this->pager->getCurrentPageBeginItem(), 11);
-    $this->assertEqual($this->pager->getCurrentPageEndItem(), 20);
-  }
-  
-  function testGettingCurrentPageWithGetIfCurrentPageWasNotSet()
-  {
-    $this->pager->setItemsPerPage(10);
-    $this->pager->setPagesPerSection(5);
-    $this->pager->setTotalItems(100);
-
-    $_GET[$this->pager_id] = 2;
-
-    $this->pager->prepare();
-    
-    $this->assertEqual($this->pager->getCurrentPage(), 2);
-    $this->assertFalse($this->pager->isDisplayedPage());
-    $this->assertEqual($this->pager->getPage(), 1);
-    $this->assertEqual($this->pager->getTotalPages(), 10);
-    $this->assertEqual($this->pager->getPagesPerSection(), 5);
-    $this->assertTrue($this->pager->hasMoreThanOnePage());
-    $this->assertEqual($this->pager->getSectionBeginPage(), 1);
-    $this->assertEqual($this->pager->getSectionEndPage(), 5);
-    $this->assertTrue($this->pager->hasNext());
-    $this->assertTrue($this->pager->hasPrev());
-    $this->assertEqual($this->pager->getCurrentPageBeginItem(), 11);
-    $this->assertEqual($this->pager->getCurrentPageEndItem(), 20);
-  }
-
-  function testTotalItemsZero()
-  {
-    $this->pager->setCurrentPage(2);
-    $this->pager->setItemsPerPage(10);
-    $this->pager->setPagesPerSection(5);
-    $this->pager->setTotalItems(0);
-
-    $this->pager->prepare();
-
-    $this->assertEqual($this->pager->getCurrentPage(), 1);
-    $this->assertEqual($this->pager->getPage(), 1);
-    $this->assertTrue($this->pager->isDisplayedPage());
-    $this->assertEqual($this->pager->getTotalPages(), 1);
-    $this->assertFalse($this->pager->hasMoreThanOnePage());
-    $this->assertEqual($this->pager->getSectionBeginPage(), 1);
-    $this->assertEqual($this->pager->getSectionEndPage(), 1);
-    $this->assertFalse($this->pager->hasNext());
-    $this->assertFalse($this->pager->hasPrev());
-    $this->assertEqual($this->pager->getCurrentPageBeginItem(), 0);
-    $this->assertEqual($this->pager->getCurrentPageEndItem(), 0);
-  }
-
-  function testNextPage()
-  {
-    $this->pager->setCurrentPage(2);
-    $this->pager->setTotalItems(40);
-    $this->pager->setItemsPerPage(10);
-    $this->pager->setPagesPerSection(5);
-
-    $this->pager->prepare();
-
-    $this->assertEqual($this->pager->getPage(), 1);
-
-    $this->assertTrue($this->pager->nextPage());
-    $this->assertTrue($this->pager->isValid());
-
-    $this->assertEqual($this->pager->getPage(), 2);
-  }
-
-  function testNextPageOutOfBounds()
-  {
-    $this->pager->setCurrentPage(2);
-    $this->pager->setTotalItems(40);
-    $this->pager->setItemsPerPage(10);
-
-    $this->pager->prepare();
-
-    $this->assertTrue($this->pager->nextPage());
-    $this->assertTrue($this->pager->isValid());
-
-    $this->assertTrue($this->pager->nextPage());
-    $this->assertTrue($this->pager->isValid());
-
-    $this->assertTrue($this->pager->nextPage());
-    $this->assertTrue($this->pager->isValid());
-
-    $this->assertFalse($this->pager->nextPage());
-    $this->assertFalse($this->pager->isValid());
-  }
-
-  function testSectionNumbers()
-  {
-    $this->pager->setCurrentPage(2);
-    $this->pager->setTotalItems(40);
-    $this->pager->setItemsPerPage(3);
-    $this->pager->setPagesPerSection(10);
-
-    $this->pager->prepare();
-
-    $this->pager->nextPage();
-
-    $this->assertEqual($this->pager->getSection(), 1);
-    $this->assertEqual($this->pager->getSectionBeginPage(), 1);
-    $this->assertEqual($this->pager->getSectionEndPage(), 10);
-  }
-
-  function testSectionNumbersRightBound()
-  {
-    $this->pager->setCurrentPage(2);
-    $this->pager->setTotalItems(40);
-    $this->pager->setItemsPerPage(10);// 4 pages total
-    $this->pager->setPagesPerSection(10);
-
-    $this->pager->prepare();
-
-    $this->pager->nextPage();
-
-    $this->assertEqual($this->pager->getSection(), 1);
-    $this->assertEqual($this->pager->getSectionBeginPage(), 1);
-    $this->assertEqual($this->pager->getSectionEndPage(), 4);
-  }
-
-  function testNextSection()
-  {
-    $this->pager->setCurrentPage(2);
-    $this->pager->setTotalItems(40);
-    $this->pager->setItemsPerPage(5);
-    $this->pager->setPagesPerSection(2);
-
-    $this->pager->prepare();
-
-    $this->assertTrue($this->pager->nextSection());
-    $this->assertTrue($this->pager->nextSection());
-    $this->assertTrue($this->pager->nextSection());
-    $this->assertFalse($this->pager->nextSection());
-  }
-
-  function testGetFirstPageUri()
-  {
-    $_GET['p1'] = ' wow ';
-    $_GET['p2'] = array('3' => 'yo');
-
-    $this->pager->prepare();
-
-    $uri = $this->pager->getPageUri(1);
-
-    $this->assertEqual($uri, 'http://test.com?p1=+wow+&p2[3]=yo');
-  }
-
-  function testGetFirstPageUriNoQuery()
-  {
-    $this->pager->prepare();
-
-    $uri = $this->pager->getPageUri(1);
-
-    $this->assertEqual($uri, 'http://test.com');
-  }
-
-  function testGetPageUri()
-  {
-    $_GET['p1'] = 'wow';
-    $_GET['p2'] = array('3' => ' yo ');
-
-    $this->pager->prepare();
-
-    $uri = $this->pager->getPageUri(2);
-
-    $this->assertEqual($uri, 'http://test.com?p1=wow&p2[3]=+yo+&test_pager=2');
-  }
-
-  function testGetPrevSectionUri()
-  {
-    $this->pager->setCurrentPage(3);
-    $this->pager->setTotalItems(60);
-    $this->pager->setItemsPerPage(10);
-    $this->pager->setPagesPerSection(2);
-
-    $this->pager->prepare();
-
-    $this->pager->nextPage();
-
-    $uri = $this->pager->getSectionUri();
-
-    $this->assertEqual($uri, 'http://test.com?test_pager=2');
-    $this->assertEqual($this->pager->getSectionBeginPage(), 1);
-    $this->assertEqual($this->pager->getSectionEndPage(), 2);
-  }
-
-  function testGetNextSectionUri()
-  {
-    $this->pager->setCurrentPage(3);
-    $this->pager->setTotalItems(60);
-    $this->pager->setItemsPerPage(10);
-    $this->pager->setPagesPerSection(2);
-
-    $this->pager->prepare();
-
-    for($i = 0; $i < 5; $i++)
-      $this->pager->nextPage();
-
-    $uri = $this->pager->getSectionUri(2);
-
-    $this->assertEqual($uri, 'http://test.com?test_pager=5');
-    $this->assertEqual($this->pager->getSectionBeginPage(), 5);
-    $this->assertEqual($this->pager->getSectionEndPage(), 6);
-  }
-}
-
-

Deleted: 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPagerTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPagerTagTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPagerTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -1,338 +0,0 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
-
-class lmbMacroPagerTagTest extends lmbBaseMacroTest
-{
-  protected $old_get;
-  protected $old_server;
-
-  function setUp()
-  {
-    parent :: setUp();
-
-    $this->old_get = $_GET;
-    $this->old_server = $_SERVER;
-
-    $_SERVER['REQUEST_URI'] = 'test.com';
-    $_GET = array();
-  }
-
-  function tearDown()
-  {
-    $_GET = $this->old_get;
-    $_SERVER = $this->old_server;
-
-    parent :: tearDown();
-  }
-
-  function testPager()
-  {
-    $template = '{{pager id="test_pager" items="10" total_items="$#items_count"}}'.
-                '{{pager:first}}F-{$href}|{{/pager:first}}' .
-                '{{pager:prev}}P-{$href}|{{/pager:prev}}' .
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$href}|{$number}|{{/pager:current}}' .
-                '{{pager:number}}N-{$href}|{$number}|{{/pager:number}}' .
-                '{{pager:separator}}**{{/pager:separator}}' .
-                '{{/pager:list}}'.
-                '{{pager:next}}X-{$href}|{{/pager:next}}' .
-                '{{pager:last}}L-{$href}|{{/pager:last}}' .
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');
-    $page->set('items_count', 40);
-
-    $_GET['test_pager'] = 2;
-
-    $expected = 'F-test.com|' .
-                'P-test.com|'.
-                'N-test.com|1|**'.
-                'C-test.com?test_pager=2|2|**'.
-                'N-test.com?test_pager=3|3|**N-test.com?test_pager=4|4|'.
-                'X-test.com?test_pager=3|'.
-                'L-test.com?test_pager=4|';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testPagerProperties()
-  {
-    $template = '{{pager id="test_pager" items="5" total_items="$#items_count"}}'.
-                '{$total_items}|{$total_pages}|{$items_per_page}|' .
-                'from:{$begin_item_number}|to:{$end_item_number}' .
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 40);
-
-    $_GET['test_pager'] = 2;
-
-    $expected = '40|8|5|from:6|to:10';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testSinglePageOnlyNotRenderAnything()
-  {
-    $template = '{{pager id="test_pager" items="10" total_items="$#items_count"}}'.
-                '{{pager:first}}F-{$href}|{{/pager:first}}' .
-                '{{pager:prev}}P-{$href}|{{/pager:prev}}' .
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$href}|{$number}|{{/pager:current}}' .
-                '{{pager:number}}N-{$href}|{$number}|{{/pager:number}}' .
-                '{{/pager:list}}'.
-                '{{pager:next}}X-{$href}|{{/pager:next}}' .
-                '{{pager:last}}L-{$href}|{{/pager:last}}' .
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 5);
-
-    $expected = '';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testFistPage()
-  {
-    $template = '{{pager id="test_pager" items="10" total_items="$#items_count"}}'.
-                '{{pager:first}}F-{$href}|{{/pager:first}}' .
-                '{{pager:prev}}P-{$href}|{{/pager:prev}}' .
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$href}|{$number}|{{/pager:current}}' .
-                '{{pager:number}}N-{$href}|{$number}|{{/pager:number}}' .
-                '{{/pager:list}}'.
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 40);
-
-    $expected = 'C-test.com|1|'.
-                'N-test.com?test_pager=2|2|N-test.com?test_pager=3|3|N-test.com?test_pager=4|4|';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testLastPage()
-  {
-    $template = '{{pager id="test_pager" items="10" total_items="$#items_count"}}'.
-                '{{pager:first}}F-{$href}|{{/pager:first}}' .
-                '{{pager:prev}}P-{$href}|{{/pager:prev}}' .
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$href}|{$number}|{{/pager:current}}' .
-                '{{pager:number}}N-{$href}|{$number}|{{/pager:number}}' .
-                '{{/pager:list}}'.
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 30);
-
-    $_GET['test_pager'] = 3;
-
-    $expected = 'F-test.com|' .
-                'P-test.com?test_pager=2|'.
-                'N-test.com|1|'.
-                'N-test.com?test_pager=2|2|'.
-                'C-test.com?test_pager=3|3|';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testElipsesBothSides()
-  {
-    $template = '{{pager id="test_pager" items="5" total_items="$#items_count" pages_in_middle="3" pages_in_sides="3"}}'.
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$number}|{{/pager:current}}' .
-                '{{pager:number}}N-{$number}|{{/pager:number}}' .
-                '{{pager:elipses}}...{{/pager:elipses}}' .
-                '{{/pager:list}}'.
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 65);
-
-    $_GET['test_pager'] = 7;
-
-    $expected = 'N-1|N-2|N-3|...N-6|C-7|N-8|...N-11|N-12|N-13|';
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testElipsesBothSidesAndSeparator()
-  {
-    $template = '{{pager id="test_pager" items="5" pages_in_middle="3" total_items="$#items_count" pages_in_sides="3"}}'.
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$number}{{/pager:current}}' .
-                '{{pager:number}}N-{$number}{{/pager:number}}' .
-                '{{pager:elipses}}...{{/pager:elipses}}' .
-                '{{pager:separator}}|{{/pager:separator}}' .
-                '{{/pager:list}}'.
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 65);
-
-    $_GET['test_pager'] = 7;
-
-    $expected = 'N-1|N-2|N-3...N-6|C-7|N-8...N-11|N-12|N-13';
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testElipsesBothSidesNoPagesInSides()
-  {
-    $template = '{{pager id="test_pager" items="5" pages_in_middle="3" total_items="$#items_count" pages_in_sides="0"}}'.
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$number}|{{/pager:current}}' .
-                '{{pager:number}}N-{$number}|{{/pager:number}}' .
-                '{{pager:elipses}}...{{/pager:elipses}}' .
-                '{{/pager:list}}'.
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 65);
-
-    $_GET['test_pager'] = 7;
-
-    $expected = '...N-6|C-7|N-8|...';
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testElipsesLeftOnly()
-  {
-    $template = '{{pager id="test_pager" items="5" pages_in_middle="3" total_items="$#items_count" pages_in_sides="3"}}'.
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$number}|{{/pager:current}}' .
-                '{{pager:number}}N-{$number}|{{/pager:number}}' .
-                '{{pager:elipses}}...{{/pager:elipses}}' .
-                '{{/pager:list}}'.
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 55);
-
-    $_GET['test_pager'] = 7;
-
-    $expected = 'N-1|N-2|N-3|...N-6|C-7|N-8|N-9|N-10|N-11|';
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testNoElipsesForSingleItemGap()
-  {
-    $template = '{{pager id="test_pager" items="5" pages_in_middle="3" total_items="$#items_count" pages_in_sides="3"}}'.
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$number}|{{/pager:current}}' .
-                '{{pager:number}}N-{$number}|{{/pager:number}}' .
-                '{{pager:elipses}}...{{/pager:elipses}}' .
-                '{{/pager:list}}'.
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 35);
-
-    $_GET['test_pager'] = 6;
-
-    $expected = 'N-1|N-2|N-3|N-4|N-5|C-6|N-7|';
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testSections()
-  {
-    $template = '{{pager id="test_pager" items="10" pages_per_section="2" total_items="$#items_count"}}'.
-                '{{pager:list}}'.
-                '{{pager:current}}C-{$href}|{$number}|{{/pager:current}}' .
-                '{{pager:number}}N-{$href}|{$number}|{{/pager:number}}' .
-                '{{pager:section}}S-{$href}|{$section_begin_page}|{$section_end_page}|{{/pager:section}}' .
-                '{{/pager:list}}'.
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 60);
-
-    $_GET['test_pager'] = 3;
-
-    $expected = 'S-test.com?test_pager=2|1|2|' .
-                'C-test.com?test_pager=3|3|'.
-                'N-test.com?test_pager=4|4|'.
-                'S-test.com?test_pager=5|5|6|';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testDisabledTagsShown()
-  {
-    $template = '{{pager id="test_pager" items="10" total_items="$#items_count"}}'.
-                '{{pager:first:disabled}}F-|{{/pager:first:disabled}}' .
-                '{{pager:prev:disabled}}P-|{{/pager:prev:disabled}}' .
-                '{{pager:next:disabled}}|-X{{/pager:next:disabled}}' .
-                '{{pager:last:disabled}}|-L{{/pager:last:disabled}}' .
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 1);
-
-    $expected = 'F-|P-||-X|-L';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testDisabledTagsHidden()
-  {
-    $template = '{{pager id="test_pager" items="1" total_items="$#items_count"}}'.
-                '{{pager:first:disabled}}F-|{{/pager:first:disabled}}' .
-                '{{pager:prev:disabled}}P-|{{/pager:prev:disabled}}' .
-                '{{pager:next:disabled}}|-X{{/pager:next:disabled}}' .
-                '{{pager:last:disabled}}|-L{{/pager:last:disabled}}' .
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 3);
-
-    $_GET['test_pager'] = 2;
-
-    $expected = '';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testShowFirstAndPrevTagsDisabledOnly()
-  {
-    $template = '{{pager id="test_pager" items="10" total_items="$#items_count"}}'.
-                '{{pager:first:disabled}}F-|{{/pager:first:disabled}}' .
-                '{{pager:prev:disabled}}P-|{{/pager:prev:disabled}}' .
-                '{{pager:next:disabled}}|-X{{/pager:next:disabled}}' .
-                '{{pager:last:disabled}}|-L{{/pager:last:disabled}}' .
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 20);
-
-    $expected = 'F-|P-|';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-
-  function testShowNextAndLastTagsDisabledOnly()
-  {
-    $template = '{{pager id="test_pager" items="10" total_items="$#items_count"}}'.
-                '{{pager:first:disabled}}F-|{{/pager:first:disabled}}' .
-                '{{pager:prev:disabled}}P-|{{/pager:prev:disabled}}' .
-                '{{pager:next:disabled}}|-X{{/pager:next:disabled}}' .
-                '{{pager:last:disabled}}|-L{{/pager:last:disabled}}' .
-                '{{/pager}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');                 
-    $page->set('items_count', 20);
-
-    $_GET['test_pager'] = 2;
-
-    $expected = '|-X|-L';
-
-    $this->assertEqual($page->render(), $expected);
-  }
-}
-

Deleted: 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPaginateTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPaginateTagTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroPaginateTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -1,107 +0,0 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
- 
-lmb_require('limb/core/src/lmbArrayIterator.class.php');
-
-class lmbMacroPaginateTagTest extends lmbBaseMacroTest
-{
-  protected $old_get;
-  protected $old_server;
-
-  function setUp()
-  {
-    parent :: setUp();
-
-    $this->old_get = $_GET;
-    $this->old_server = $_SERVER;
-
-    $_SERVER['REQUEST_URI'] = 'test.com';
-    $_GET = array();
-  }
-
-  function tearDown()
-  {
-    $_GET = $this->old_get;
-    $_SERVER = $this->old_server;
-
-    parent :: tearDown();
-  }
-
-  function testPaginateWithoutPager()
-  {
-    $template = '{{paginate iterator="$#test_iterator" offset="2" limit="2"/}}'.
-                 '{{list using="$#test_iterator" as="$item"}}{{list:item}}{$item}{{/list:item}}{{/list}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');
-    $page->set('test_iterator', new lmbArrayIterator(array('Ivan', 'Pavel', 'Mike', 'Bob', 'Todd')));
-
-    $expected = 'MikeBob';
-    $this->assertEqual($page->render(), $expected);
-  }
-  
-  function testErrorIfOffsetGivenWithoutLimit()
-  {
-    $template = '{{paginate iterator="$#test_iterator" offset="2"/}}'.
-                 '{{list using="$#test_iterator" as="$item"}}{{list:item}}{$item}{{/list:item}}{{/list}}';
-
-    try
-    {
-      $page = $this->_createMacroTemplate($template, 'tpl.html');
-      $page->render();
-      $this->assertTrue(false);
-    }
-    catch(lmbMacroException $e)
-    {
-      $this->assertTrue(true);
-    }
-  }  
-
-  function testPaginateWithoutPagerAndOffsetIsZeroIfNotSpecified()
-  {
-    $template = '{{paginate iterator="$#test_iterator" limit="2"/}}'.
-                 '{{list using="$#test_iterator" as="$item"}}{{list:item}}{$item}{{/list:item}}{{/list}}';
-
-    $page = $this->_createMacroTemplate($template, 'tpl.html');
-    $page->set('test_iterator', new lmbArrayIterator(array('Ivan', 'Pavel', 'Mike', 'Bob', 'Todd')));
-
-    $expected = 'IvanPavel';
-    $this->assertEqual($page->render(), $expected);
-  }
-  
-  function testPaginateWithPager()
-  {
-    $template = '{{paginate iterator="$#test_iterator" pager="test_pager"/}}'.
-                 '{{list using="$#test_iterator" as="$item"}}{{list:item}}{$item}{{/list:item}}{{/list}}'.
-                 '{{pager id="test_pager" items="2"/}}';
-
-    $_GET['test_pager'] = 2; // offset = 2 since the second page
-                  
-    $page = $this->_createMacroTemplate($template, 'tpl.html');
-    $page->set('test_iterator', new lmbArrayIterator(array('Ivan', 'Pavel', 'Mike', 'Bob', 'Todd')));
-
-    $expected = 'MikeBob';
-    $this->assertEqual($page->render(), $expected);
-  }
-  
-  function testPaginateWithPagerOverwritesPagerItemsPerPageByLimitAttribute()
-  {
-    $template = '{{paginate iterator="$#test_iterator" pager="test_pager" limit="3"/}}'.
-                 '{{list using="$#test_iterator" as="$item"}}{{list:item}}{$item}{{/list:item}}{{/list}}'.
-                 '{{pager id="test_pager" items="2"/}}';
-
-    $_GET['test_pager'] = 2; // offset = 2 since the second page
-                  
-    $page = $this->_createMacroTemplate($template, 'tpl.html');
-    $page->set('test_iterator', new lmbArrayIterator(array('Ivan', 'Pavel', 'Mike', 'Bob', 'Todd', 'Serega')));
-
-    $expected = 'BobToddSerega';
-    $this->assertEqual($page->render(), $expected);
-  }  
-}
-

Deleted: 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTemplateTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTemplateTagTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTemplateTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -1,35 +0,0 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
-
-class lmbMacroTemplateTagTest extends lmbBaseMacroTest
-{
-  function testApplyTemplate()
-  {
-    $content = '{{template name="tpl1"}}' .  
-               '{$bar}' .                   
-               '{{/template}}' .              
-               '{{template name="tpl2"}}' .  
-               '{$foo}{$hey}' .                   
-               '{{/template}}' .
-               '{{apply template="tpl2" hey="$#hey" foo="$#foo"/}}' .
-               '{{apply template="tpl1" bar="$#bar"/}}' 
-               ;
-
-    $tpl = $this->_createTemplate($content, 'tree.html');
-
-    $macro = $this->_createMacro($tpl);
-    $macro->set('hey', 'HEY');
-    $macro->set('bar', 'BAR');
-    $macro->set('foo', 'FOO');
-
-    $out = $macro->render();
-    $this->assertEqual($out, 'FOOHEYBAR');
-  }
-}
-

Deleted: 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTreeTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTreeTagTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroTreeTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -1,34 +0,0 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
-
-class lmbMacroTreeTagTest extends lmbBaseMacroTest
-{
-  function testRenderTree()
-  {
-    $content = '{{tree using="$#tree" as="$item" kids_prop="kids"}}' . 
-                  '<ul>' . 
-                  '{{tree:branch}}' . 
-                    '<li>{{tree:item}}{$item.title}{{/tree:item}}</li>' . 
-                  '{{/tree:branch}}' .
-                  '</ul>' . 
-                '{{/tree}}';
-
-    $tpl = $this->_createTemplate($content, 'tree.html');
-
-    $macro = $this->_createMacro($tpl);
-    $macro->set('tree', array(array('title' => 'foo'), 
-                              array('title' => 'bar', 'kids' => array(array('title' => 'bar1'),
-                                                                      array('title' => 'bar2'))), 
-                              array('title' => 'hey')));
-
-    $out = $macro->render();
-    $this->assertEqual($out, '<ul><li>foo</li><li>bar<ul><li>bar1</li><li>bar2</li></ul></li><li>hey</li></ul>');
-  }
-}
-

Deleted: 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroWrapTagTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroWrapTagTest.class.php	2007-11-30 11:34:07 UTC (rev 6554)
+++ 3.x/trunk/limb/macro/tests/cases/tags/lmbMacroWrapTagTest.class.php	2007-12-01 10:31:03 UTC (rev 6555)
@@ -1,197 +0,0 @@
-<?php
-/*
- * Limb PHP Framework
- *
- * @link http://limb-project.com
- * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
- * @license    LGPL http://www.gnu.org/copyleft/lesser.html
- */
-
-class lmbMacroWrapTagTest extends lmbBaseMacroTest
-{
-  function testSimpleStaticWrap()
-  {
-    $bar = '{{wrap with="foo.html" into="slot1"}}Bob{{/wrap}}';
-    $foo = '<p>Hello, {{slot id="slot1"/}}</p>';
-
-    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
-    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
-
-    $macro = $this->_createMacro($bar_tpl);
-
-    $out = $macro->render();
-    $this->assertEqual($out, '<p>Hello, Bob</p>');
-  }
-
-  function testStaticWrapWithVariables()
-  {
-    $bar = '{{wrap with="foo.html" into="slot1"}}<?php echo $this->bob?>{{/wrap}}';
-    $foo = '<p>Hello, {{slot id="slot1"/}}</p>';
-
-    $bar_tpl = $this->_createTemplate($bar, 'bar.html');
-    $foo_tpl = $this->_createTemplate($foo, 'foo.html');
-
-    $macro = $this->_createMacro($bar_tpl);
-    $macro->set('bob', 'Bob');
-
-    $out = $macro->render();
-    $thi