You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2010/06/18 01:57:56 UTC

svn commit: r955793 [3/4] - in /myfaces/tomahawk/trunk/core12/src/test: java/org/apache/myfaces/component/ java/org/apache/myfaces/component/html/ java/org/apache/myfaces/component/html/ext/ java/org/apache/myfaces/convert/ java/org/apache/myfaces/cust...

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/HtmlTreeRendererTest.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/HtmlTreeRendererTest.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/HtmlTreeRendererTest.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/HtmlTreeRendererTest.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.custom.tree2;
+
+import java.util.Stack;
+
+import javax.faces.component.html.HtmlForm;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * - .. Root (0)
+ * |
+ * - .. A (0:0)
+ * |    |
+ * |    + .. AA (0:0:0)
+ * |    |
+ * |    + .. AB (0:0:1)
+ * |    |
+ * |    + .. AC (0:0:2)
+ * |         | .. aca (0:0:2:0)
+ * |         | .. acb (0:0:2:1)
+ * |
+ * + .. B (0:1)
+ * |    |
+ * |    + .. BA (0:1:0)
+ * |    |
+ * |    + .. BB (0:1:1)
+ * |
+ * | .. C (0:2)
+ * |
+ * | .. d (0:3)
+ */
+
+public class HtmlTreeRendererTest extends AbstractTreeTestCase
+{
+    private NodeSimulator nodeSim;
+
+    /**
+     * Constructor
+     * @param name String
+     */
+    public HtmlTreeRendererTest(String name)
+    {
+        super(name);
+    }
+
+    /**
+     * See abstract class
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        nodeSim = new NodeSimulator();
+
+        // the tree needs a default facet - use a node simulator instead of the usual components
+        // so we can detect when a node is rendered
+        tree.getFacets().put(DEFAULT_NODE_TYPE, nodeSim);
+
+        // set up the renderer for the component.  with mock stuff we don't have faces config doing this for us
+        renderKit.addRenderer(HtmlTree.COMPONENT_FAMILY, HtmlTree.COMPONENT_TYPE, new HtmlTreeRenderer());
+    }
+
+    /**
+     * Tests the option of hiding the root node (with server side toggling option)
+     * @throws Exception
+     */
+    public void testHideRootNodeServer() throws Exception
+    {
+        tree.setParent(new HtmlForm());
+        tree.setClientSideToggle(false);
+        tree.setShowRootNode(false);
+
+        HtmlTreeRenderer treeRenderer = new HtmlTreeRenderer();
+        treeRenderer.encodeChildren(facesContext, tree);
+
+        // we expect the nodes to come off the stack in the reverse order in which they were added
+        Stack nodeStack = nodeSim.getNodeStack();
+        int numRendered = nodeStack.size();
+        assertEquals("Unexpected number of nodes rendered", 4, numRendered);
+
+        TreeNode node = (TreeNode)nodeStack.pop();
+        assertEquals("d", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("C", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("B", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("A", node.getIdentifier());
+    }
+
+    /**
+     * Tests the option of hiding the root node (with client side toggling option)
+     * @throws Exception
+     */
+    public void testHideRootNodeClient() throws Exception
+    {
+        tree.setClientSideToggle(true);
+        tree.setShowRootNode(false);
+
+        HtmlTreeRenderer treeRenderer = new HtmlTreeRenderer();
+        treeRenderer.encodeChildren(facesContext, tree);
+
+        // we expect the nodes to come off the stack in the reverse order in which they were added
+        Stack nodeStack = nodeSim.getNodeStack();
+        int numRendered = nodeStack.size();
+        assertEquals("Unexpected number of nodes rendered", 11, numRendered);
+
+        TreeNode node = (TreeNode)nodeStack.pop();
+        assertEquals("d", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("C", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("BB", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("BA", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("B", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("acb", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("aca", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("AC", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("AB", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("AA", node.getIdentifier());
+
+        node = (TreeNode)nodeStack.pop();
+        assertEquals("A", node.getIdentifier());
+    }
+
+    public static Test suite()
+    {
+        return new TestSuite(HtmlTreeRendererTest.class);
+    }
+}

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/HtmlTreeTest.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/HtmlTreeTest.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/HtmlTreeTest.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/HtmlTreeTest.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.custom.tree2;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * TestCase for HtmlTree
+ *
+ * @author Sean Schofield
+ */
+public class HtmlTreeTest extends AbstractTreeTestCase
+{
+    //private HtmlTree tree;
+
+    /**
+     * Constructor
+     * @param name Test name
+     */
+    public HtmlTreeTest(String name)
+    {
+        super(name);
+    }
+
+//    public void setUp()
+//    {
+//        super.setUp();
+//        tree = new HtmlTree();
+//    }
+//
+//    public void tearDown()
+//    {
+//        super.tearDown();
+//    }
+
+    // Return the tests included in this test case.
+    public static Test suite()
+    {
+        return new TestSuite(HtmlTreeTest.class);
+    }
+
+    /**
+     * Test default values of the tree
+     */
+    public void testDefaults()
+    {
+        assertTrue("clientSideToggle default should be true", tree.isClientSideToggle());
+        assertTrue("showNav default should be true", tree.isShowNav());
+        assertTrue("showLines default should be true", tree.isShowLines());
+        assertTrue("showRootNode default should be true", tree.isShowRootNode());
+        assertTrue("preserveToggle default should be true", tree.isPreserveToggle());
+    }
+
+    /**
+     *
+     */
+    public void testSaveAndRestore()
+    {
+
+    }
+}

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/TreeWalkerBaseTest.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/TreeWalkerBaseTest.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/TreeWalkerBaseTest.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/TreeWalkerBaseTest.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.custom.tree2;
+
+import junit.framework.TestCase;
+
+
+/**
+ * - .. Root (0)
+ * |
+ * - .. A (0:0)
+ * |    |
+ * |    + .. AA (0:0:0)
+ * |    |
+ * |    + .. AB (0:0:1)
+ * |    |
+ * |    + .. AC (0:0:2)
+ * |         | .. aca (0:0:2:0)
+ * |         | .. acb (0:0:2:1)
+ * |
+ * + .. B (0:1)
+ * |    |
+ * |    + .. BA (0:1:0)
+ * |    |
+ * |    + .. BB (0:1:1)
+ * |
+ * | .. C (0:2)
+ * |
+ * | .. d (0:3)
+ */
+
+public class TreeWalkerBaseTest extends TestCase
+{
+    private static final String DEFAULT_NODE_TYPE = "default";
+
+    UITreeData treeData = new UITreeData();
+    TreeWalker treeWalker;
+
+    protected void setUp() throws Exception
+    {
+        // set up the test tree with the standard data
+        TreeNodeBase Root_node = new TreeNodeBase(DEFAULT_NODE_TYPE, "Root", "Root", false);
+
+        TreeNodeBase A_node = new TreeNodeBase(DEFAULT_NODE_TYPE, "A", "A", false);
+        A_node.getChildren().add(new TreeNodeBase(DEFAULT_NODE_TYPE, "AA", "AA", false));
+        A_node.getChildren().add(new TreeNodeBase(DEFAULT_NODE_TYPE, "AB", "AB", false));
+        TreeNodeBase AC_node = new TreeNodeBase(DEFAULT_NODE_TYPE, "AC", "AC", false);
+        AC_node.getChildren().add(new TreeNodeBase(DEFAULT_NODE_TYPE, "aca", "aca", true));
+        AC_node.getChildren().add(new TreeNodeBase(DEFAULT_NODE_TYPE, "acb", "acb", true));
+        A_node.getChildren().add(AC_node);
+        Root_node.getChildren().add(A_node);
+
+        TreeNodeBase B_node = new TreeNodeBase(DEFAULT_NODE_TYPE, "B", "B", false);
+        B_node.getChildren().add(new TreeNodeBase(DEFAULT_NODE_TYPE, "BA", "BA", false));
+        B_node.getChildren().add(new TreeNodeBase(DEFAULT_NODE_TYPE, "BB", "BB", false));
+        Root_node.getChildren().add(B_node);
+
+        TreeNodeBase C_node = new TreeNodeBase(DEFAULT_NODE_TYPE, "C", "C", false);
+        Root_node.getChildren().add(C_node);
+
+        TreeNodeBase d_node = new TreeNodeBase(DEFAULT_NODE_TYPE, "d", "d", true);
+        Root_node.getChildren().add(d_node);
+
+        treeData.setValue(Root_node);
+
+        // setup the tree state
+        TreeState treeState = treeData.getDataModel().getTreeState();
+        treeState.toggleExpanded("0");
+        treeState.toggleExpanded("0:0");
+
+        // setup the tree walker
+        treeWalker = treeData.getDataModel().getTreeWalker();
+        treeWalker.setTree(treeData);
+    }
+
+    public void testGetRootNodeId() throws Exception
+    {
+        String nodeId = treeWalker.getRootNodeId();
+        assertEquals("Unexpected rootId", "0", nodeId);
+    }
+
+    /**
+     * Walk through all of the nodes and make sure the return value is correct as well as the current node of
+     * the tree.  Continue until the walker runs out of nodes.  Since the checkState property is true only the
+     * expanded nodes will be walked.
+     *
+     * @throws Exception
+     */
+    public void testNextCheckState() throws Exception
+    {
+        treeWalker.setCheckState(true);
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0", treeData.getNodeId());
+        assertEquals("unexpected node", "Root", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0", treeData.getNodeId());
+        assertEquals("unexpected node", "A", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0:0", treeData.getNodeId());
+        assertEquals("unexpected node", "AA", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0:1", treeData.getNodeId());
+        assertEquals("unexpected node", "AB", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0:2", treeData.getNodeId());
+        assertEquals("unexpected node", "AC", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:1", treeData.getNodeId());
+        assertEquals("unexpected node", "B", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:2", treeData.getNodeId());
+        assertEquals("unexpected node", "C", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:3", treeData.getNodeId());
+        assertEquals("unexpected node", "d", treeData.getNode().getIdentifier());
+
+        // not expecting anymore nodes
+        assertFalse("unxpected return value", treeWalker.next());
+    }
+
+
+    /**
+     * Walk through all of the nodes and make sure the return value is correct as well as the current node of
+     * the tree.  Continue until the walker runs out of nodes.  Sets the checkState property to false so all of
+     * the nodes will be walked.
+     *
+     * @throws Exception
+     */
+    public void testNextNoCheckState() throws Exception
+    {
+        // walk through all of the nodes and make sure the return value is correct until we run out of
+        // nodes
+        treeWalker.setCheckState(false);
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0", treeData.getNodeId());
+        assertEquals("unexpected node", "Root", treeData.getNode().getIdentifier());
+
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0", treeData.getNodeId());
+        assertEquals("unexpected node", "A", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0:0", treeData.getNodeId());
+        assertEquals("unexpected node", "AA", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0:1", treeData.getNodeId());
+        assertEquals("unexpected node", "AB", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0:2", treeData.getNodeId());
+        assertEquals("unexpected node", "AC", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0:2:0", treeData.getNodeId());
+        assertEquals("unexpected node", "aca", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:0:2:1", treeData.getNodeId());
+        assertEquals("unexpected node", "acb", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:1", treeData.getNodeId());
+        assertEquals("unexpected node", "B", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:1:0", treeData.getNodeId());
+        assertEquals("unexpected node", "BA", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:1:1", treeData.getNodeId());
+        assertEquals("unexpected node", "BB", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:2", treeData.getNodeId());
+        assertEquals("unexpected node", "C", treeData.getNode().getIdentifier());
+
+        assertTrue("unxpected return value", treeWalker.next());
+        assertEquals("unexpected nodeId", "0:3", treeData.getNodeId());
+        assertEquals("unexpected node", "d", treeData.getNode().getIdentifier());
+
+        // not expecting anymore nodes
+        assertFalse("unxpected return value", treeWalker.next());
+    }
+
+    /**
+     * Walk through the tree.  Then call reset.  Make sure the tree is walked through again
+     * from the beginning.  This can be tested by running some of the other tests twice with
+     * a call to reset in between.
+     */
+    public void testReset()
+    {
+        try
+        {
+            testNextCheckState();
+            treeWalker.reset();
+            testNextCheckState();
+        }
+        catch (Exception e)
+        {
+            fail("Unable to successfuly check the next method twice with a reset");
+        }
+    }
+}

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/UITreeDataTest.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/UITreeDataTest.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/UITreeDataTest.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/tree2/UITreeDataTest.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.custom.tree2;
+
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import javax.faces.event.ActionEvent;
+import javax.faces.component.html.HtmlCommandLink;
+
+/**
+ * Test case for {@link UITreeData}.
+ */
+public class UITreeDataTest extends AbstractTreeTestCase
+{
+    /**
+     * Constructor
+     * @param name String
+     */
+    public UITreeDataTest(String name)
+    {
+        super(name);
+    }
+
+    /**
+     * See abstract class
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+    }
+
+    /**
+     * Tests the selection of a specific node using both server side and client side
+     * toggle options.
+     *
+     * @throws Exception
+     */
+    public void testNodeSelected() throws Exception
+    {
+        tree.setClientSideToggle(false);
+        // tree.getAttributes().put(JSFAttr.CLIENT_SIDE_TOGGLE, Boolean.FALSE);
+
+        ActionEvent event = new ActionEvent(new HtmlCommandLink());
+
+        // set the node to be selected
+        tree.setNodeId("0:1:0");
+        tree.setNodeSelected(event);
+
+        assertTrue("Node 0:1:0 should be selected", tree.isNodeSelected());
+
+        tree.setClientSideToggle(true);
+        // tree.getAttributes().put(JSFAttr.CLIENT_SIDE_TOGGLE, Boolean.TRUE);
+
+        // set the node to be selected
+        tree.setNodeId("0:1:0");
+        tree.setNodeSelected(event);
+
+        assertTrue("Node 0:1:0 should be selected", tree.isNodeSelected());
+    }
+
+    /**
+     * Tests programatic selection of a node.  (See MYFACES-717)
+     * @throws Exception
+     */
+    public void testProgramaticSelection() throws Exception
+    {
+        TreeModel treeModel = tree.getDataModel();
+        TreeState treeState = treeModel.getTreeState();
+        treeState.setSelected("0:3");
+
+        treeModel.setTreeState(treeState);
+
+        tree.setValue(treeModel);
+        tree.setNodeId("0:3");
+        assertTrue("Node 0:3 should be selected", tree.isNodeSelected());
+    }
+
+    /**
+     * Tests the ability to expand all nodes at once.  (See TOMAHAWK-436)
+     * @throws Exception
+     */
+    public void testExpandAll() throws Exception
+    {
+        tree.expandAll();
+
+        tree.setNodeId("0");
+        assertTrue("Node O should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:0");
+        assertTrue("Node O:0 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:0:0");
+        assertTrue("Node O:0:0 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:0:1");
+        assertTrue("Node O:0:1 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:0:2");
+        assertTrue("Node O:0:2 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:0:2:0");
+        assertTrue("Node O:0:2:0 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:0:2:1");
+        assertTrue("Node O:0:2:1 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:1");
+        assertTrue("Node O:1 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:1:0");
+        assertTrue("Node O:1:0 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:1:1");
+        assertTrue("Node O:1:1 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:2");
+        assertTrue("Node O:2 should be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:3");
+        assertTrue("Node O:3 should be expanded", tree.isNodeExpanded());
+    }
+
+    /**
+     * Tests the ability to collapse all nodes at once.  (See TOMAHAWK-27)
+     * @throws Exception
+     */
+    public void testCollapseAll() throws Exception
+    {
+        // expand a few nodes to start off with
+        tree.expandPath(new String[] {"0", "0:0", "0:0:1"});
+        tree.expandPath(new String[] {"0", "0:1", "0:1:0"});
+
+        tree.collapseAll();
+
+        tree.setNodeId("0");
+        assertFalse("Node O should not be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:0");
+        assertFalse("Node O:0 should not be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:0:1");
+        assertFalse("Node O:0:1 should not be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:1");
+        assertFalse("Node O:1 should not be expanded", tree.isNodeExpanded());
+
+        tree.setNodeId("0:1:0");
+        assertFalse("Node O:1:0 should not be expanded", tree.isNodeExpanded());
+    }
+
+    /**
+     * Its possible that a facet will be empty on the decode if it contained only EL text.
+     * So its wrong to throw an exception when this is the case.  (See TOMAHAWK-510)
+     *
+     * @throws Exception
+     */
+    public void testEmptyFacet() throws Exception
+    {
+        tree.processDecodes(facesContext);
+
+    }
+
+    public static Test suite()
+    {
+        return new TestSuite(UITreeDataTest.class);
+    }
+}

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/AbstractValidatorTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/AbstractValidatorTestCase.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/AbstractValidatorTestCase.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/AbstractValidatorTestCase.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,50 @@
+package org.apache.myfaces.custom.validators;
+
+import javax.faces.component.UIComponent;
+import javax.faces.validator.Validator;
+
+import org.apache.shale.test.jmock.AbstractJmockJsfTestCase;
+import org.jmock.Mock;
+
+public abstract class AbstractValidatorTestCase extends AbstractJmockJsfTestCase
+{
+
+  public AbstractValidatorTestCase(String arg0) {
+    super(arg0);
+  }
+  
+  Mock mockComponent;
+  UIComponent component;
+  
+  protected void setUp() throws Exception
+  {
+    super.setUp();
+    mockComponent = mock(UIComponent.class);
+    component = (UIComponent) mockComponent.proxy();
+    
+  }
+
+  protected void tearDown() throws Exception
+  {
+    super.tearDown();
+  }
+
+
+  /**
+   * if contex or component = null then should throw NullPointerException
+   */
+  protected void doTestNullContext(
+    UIComponent component,
+    Validator validator) throws NullPointerException
+  {
+    try
+    {
+      validator.validate(null, component, "dummy");
+      fail("Expected NullpointerException - if context or component is null");
+    }
+    catch (NullPointerException npe)
+    {
+      // this is expected
+    }
+  }
+}
\ No newline at end of file

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/EmailValidatorTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/EmailValidatorTestCase.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/EmailValidatorTestCase.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/EmailValidatorTestCase.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,63 @@
+package org.apache.myfaces.custom.validators;
+
+import javax.faces.validator.ValidatorException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.myfaces.custom.emailvalidator.EmailValidator;
+
+public class EmailValidatorTestCase extends AbstractValidatorTestCase
+{
+
+  public EmailValidatorTestCase(String arg0) {
+    super(arg0);
+  }
+  
+  EmailValidator emailValidator;
+  
+  protected void setUp() throws Exception
+  {
+    super.setUp();
+    emailValidator = new EmailValidator();    
+  }
+
+  protected void tearDown() throws Exception
+  {
+    super.tearDown();
+  }
+
+  public static Test suite()
+  {
+    return new TestSuite(EmailValidatorTestCase.class);
+  }
+
+  /**
+   * Test when context is set to null
+   */
+  public void testNullContext()
+  {
+
+    doTestNullContext(component, emailValidator);
+  }
+  
+  public void testWrongEmailAddress()
+  {
+    try
+    {
+      emailValidator.validate(facesContext, component, "matzew@apache");
+      fail("Expected ValidatorException");
+    }
+    catch (ValidatorException ve)
+    {
+      // if exception then fine.
+    }
+
+  }
+
+  public void testGoodEmailAddress()
+  {
+      emailValidator.validate(facesContext, component, "foo@apache.org");
+  }
+  
+}
\ No newline at end of file

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/EqualValidatorTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/EqualValidatorTestCase.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/EqualValidatorTestCase.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/EqualValidatorTestCase.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,91 @@
+package org.apache.myfaces.custom.validators;
+
+import javax.faces.component.UIInput;
+import javax.faces.validator.ValidatorException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.myfaces.custom.equalvalidator.EqualValidator;
+
+public class EqualValidatorTestCase extends AbstractValidatorTestCase
+{
+
+  public EqualValidatorTestCase(String arg0) {
+    super(arg0);
+  }
+  
+  EqualValidator equalValidator;
+  
+  protected void setUp() throws Exception
+  {
+    super.setUp();
+    equalValidator = new EqualValidator();
+    
+  }
+
+  protected void tearDown() throws Exception
+  {
+    super.tearDown();
+  }
+
+  public static Test suite()
+  {
+    return new TestSuite(EqualValidatorTestCase.class);
+  }
+  
+  /**
+   * Test when context is set to null
+   */
+  public void testNullContext()
+  {
+
+    doTestNullContext(component, equalValidator);
+  }
+  
+  public void testRightValue()
+  {
+    equalValidator.setFor("comp1");
+    
+    UIInput comp1 = new UIInput();
+    comp1.setValue("HANS");
+    comp1.setId("comp1");
+    facesContext.getViewRoot().getChildren().add(comp1);
+    
+    
+    UIInput comp2 = new UIInput ();
+    comp2.setId("comp2");
+    facesContext.getViewRoot().getChildren().add(comp2);
+
+    equalValidator.validate(facesContext, comp2, "HANS");
+
+  }
+
+  public void testWrongValue()
+  {
+    try
+    {
+      equalValidator.setFor("comp1");
+      
+      UIInput comp1 = new UIInput();
+      comp1.setValue("HANS");
+      comp1.setId("comp1");
+      facesContext.getViewRoot().getChildren().add(comp1);
+      
+      
+      UIInput comp2 = new UIInput ();
+      comp2.setId("comp2");
+      facesContext.getViewRoot().getChildren().add(comp2);
+
+      equalValidator.validate(facesContext, comp2, "BUUBA");
+      
+      fail("Expected ValidatorException");
+    }
+    catch (ValidatorException ve)
+    {
+      // if exception then fine.
+    }
+
+  }
+
+}

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/RegExprValidatorTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/RegExprValidatorTestCase.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/RegExprValidatorTestCase.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/custom/validators/RegExprValidatorTestCase.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.custom.validators;
+
+import javax.faces.component.UIInput;
+import javax.faces.validator.ValidatorException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.myfaces.custom.regexprvalidator.RegExprValidator;
+
+public class RegExprValidatorTestCase extends AbstractValidatorTestCase
+{
+
+  public RegExprValidatorTestCase(String arg0) {
+    super(arg0);
+  }
+  
+  RegExprValidator validator;
+  
+  protected void setUp() throws Exception
+  {
+    super.setUp();
+    validator = new RegExprValidator();
+    
+  }
+
+  protected void tearDown() throws Exception
+  {
+    super.tearDown();
+  }
+
+  public static Test suite()
+  {
+    return new TestSuite(RegExprValidatorTestCase.class);
+  }
+  
+  /**
+   * Test when context is set to null
+   */
+  public void testNullContext()
+  {
+
+    doTestNullContext(component, validator);
+  }
+  
+  public void testRightValue()
+  {
+    validator.setPattern("\\d{5}");
+    
+    UIInput comp1 = new UIInput();
+    comp1.setValue("12345");
+    comp1.setId("comp1");
+    facesContext.getViewRoot().getChildren().add(comp1);
+    
+    validator.validate(facesContext, comp1, comp1.getValue());
+
+  }
+
+  public void testWrongValue()
+  {
+    try
+    {
+      validator.setPattern("\\d{12}");
+      
+      UIInput comp1 = new UIInput();
+      comp1.setValue("12345");
+      comp1.setId("comp1");
+      facesContext.getViewRoot().getChildren().add(comp1);
+      
+      validator.validate(facesContext, comp1, comp1.getValue());
+      
+      fail("Expected ValidatorException");
+    }
+    catch (ValidatorException ve)
+    {
+      // if exception then fine.
+    }
+
+  }
+
+  
+}

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/dateformat/TestSimpleDateFormatter.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/dateformat/TestSimpleDateFormatter.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/dateformat/TestSimpleDateFormatter.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/dateformat/TestSimpleDateFormatter.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,462 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.dateformat;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import org.joda.time.DateTime;
+
+public class TestSimpleDateFormatter extends TestCase
+{
+    // test just the very basics of date formatting
+    public void testFormatSimple()
+    {
+        SimpleDateFormatter sdf = new SimpleDateFormatter("yyyy-MM-dd'T'hh:mm:ss", null);
+        Date d = new Date();
+        d.setYear(1987 - 1900);
+        d.setMonth(2);
+        d.setDate(12);
+        d.setHours(13);
+        d.setMinutes(23);
+        d.setSeconds(59);
+        
+        String s = sdf.format(d);
+        assertEquals("1987-03-12T01:23:59", s);
+    }
+
+    // test just the very basics of date parsing
+    public void testParseSimple()
+    {
+        SimpleDateFormatter sdf = new SimpleDateFormatter("yyyy-MM-dd'T'HH:mm:ss", null);
+        Date d = sdf.parse("1987-03-12T04:23:59");
+
+        assertNotNull(d);
+        assertEquals(1987, d.getYear() + 1900);
+        assertEquals(2, d.getMonth());
+        assertEquals(12, d.getDate());
+        assertEquals(4, d.getHours());
+        assertEquals(23, d.getMinutes());
+        assertEquals(59, d.getSeconds());
+    }
+
+    /**
+     * Check the parsing of dates with months that use names.
+     */
+    public void testParseNamedMonth()
+    {
+        Locale locale = Locale.ENGLISH;
+        org.apache.myfaces.dateformat.DateFormatSymbols symbols = 
+            new org.apache.myfaces.dateformat.DateFormatSymbols(locale);
+        int firstDayOfWeek = 0;
+        SimpleDateFormatter sdf = new SimpleDateFormatter(
+                "dd-MMM-yyyy", symbols, firstDayOfWeek);
+        
+        Date d = sdf.parse("12-Mar-2008");
+        assertNotNull(d);
+        assertEquals(2008, d.getYear() + 1900);
+        assertEquals(2, d.getMonth());
+        assertEquals(12, d.getDate());
+        assertEquals(0, d.getHours());
+        assertEquals(0, d.getMinutes());
+        assertEquals(0, d.getSeconds());
+    }
+
+    // test every possible formatter in date formatting
+    public void testFormatAll()
+    {
+        Date d = new Date();
+        d.setYear(1987 - 1900);
+        d.setMonth(2);
+        d.setDate(12);
+        d.setHours(4);
+        d.setMinutes(23);
+        d.setSeconds(59);
+        
+        String[] data =
+        {
+            "yyyy", "1987",
+            "yyy", "87",
+            "yy", "87",
+            "y", "87",
+            "MMMM", "March",
+            "MMM", "Mar",
+            "MM", "03",
+            "M", "3",
+            "dd", "12",
+            "EEEE", "Thursday",
+            "EE", "Thu",
+            "HH", "04",
+            "H", "4",
+            "hh", "04",
+            "h", "4",
+            "mm", "23",
+            "m", "23",
+            "ss", "59",
+            "s", "59",
+            "a", "AM"
+        };
+
+        Locale locale = Locale.ENGLISH;
+        for(int i=0; i<data.length; i+=2)
+        {
+            String pattern = data[i];
+            String expected = data[i+1];
+
+            SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
+            String s = sdf.format(d);
+            assertEquals("custom:" + pattern, expected, s);
+            
+            SimpleDateFormat sf = new SimpleDateFormat(pattern, locale);
+            String s2 = sf.format(d);
+            assertEquals("std:" + pattern, expected, s2);
+        }
+    }
+    
+    // test every possible formatter in date parsing
+    public void testParseAll()
+    {
+        Date d = new Date();
+        d.setYear(1987 - 1900);
+        d.setMonth(2);
+        d.setDate(12);
+        d.setHours(4);
+        d.setMinutes(23);
+        d.setSeconds(59);
+        
+        String[] data =
+        {
+            "yyyy", "1987",
+            "yyy", "87",
+            "yy", "87",
+            "y", "87",
+            "MMMM", "March",
+            "MMM", "Mar",
+            "MM", "03",
+            "M", "3",
+            "dd", "12",
+
+            // These are difficult to test in this way; disable them
+            //"EEEE", "Monday",
+            //"EE", "Mon",
+
+            "HH", "04",
+            "H", "4",
+
+            "hh", "04",
+            "h", "4",
+            "mm", "23",
+            "m", "23",
+            "ss", "59",
+            "s", "59",
+            "a", "AM"
+        };
+
+        Locale locale = Locale.ENGLISH;
+        for(int i=0; i<data.length; i+=2)
+        {
+            String pattern = data[i];
+            String expected = data[i+1];
+
+            // parse it with our code, then format it with the std code and
+            // see if we get the same value back.
+            SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
+        
+            Date d2 = sdf.parse(expected);
+            SimpleDateFormat sf = new SimpleDateFormat(pattern, locale);
+            String s2 = sf.format(d2);
+            assertEquals(pattern, expected, s2);
+        }
+    }
+
+    // try to parse various combinations, and see what we get
+    public void testParseAssorted() throws Exception {
+        Object[] data =
+        {
+            // test standard, with literals
+            "yyyy-MM-dd", "1987-01-08", new Date(1987-1900, 0, 8),
+            
+            // test standard, with multichar literal sequences: any non-alpha
+            // char must exactly match the input.
+            "yyyy--MM-:()dd", "1987--01-:()08", new Date(1987-1900, 0, 8),
+            
+            // test standard, with quoted chars.
+            "yyyy'T'MM'T'dd", "1987T01T08", new Date(1987-1900, 0, 8),
+            
+            // test standard, with non-pattern chars.
+            // An alpha non-pattern char --> error
+            "yyyyRMMRdd", "1987-01-08", null,
+            
+            // test quoted text
+            "yyyy'year'MM'month'dd", "2003year04month06", new Date(2003-1900, 03, 06),
+            
+            // test mismatched quoted text
+            "yyyy'year'MM'month'dd", "2003yexr04month06", null,
+            
+            // test short year format with no century wraparound
+            "yy-MM-dd", "99-04-06", new Date(1999-1900, 03, 06),
+            
+            // test short year format with century wraparound
+            "yy-MM-dd", "03-04-06", new Date(2003-1900, 03, 06),
+            
+            // test short year format with no century wraparound
+            "yy-MM-dd", "33-04-06", new Date(1933-1900, 03, 06),
+        };
+
+        Locale locale = Locale.ENGLISH;
+        for(int i=0; i<data.length; i+=3)
+        {
+            String pattern = (String) data[i];
+            String input = (String) data[i+1];
+            Date expected = (Date) data[i+2];
+
+            // parse it with our code, and see if we get the expected result
+            SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
+            Date d = sdf.parse(input);
+            assertEquals("custom:" + pattern, expected, d);
+            
+            // try with the standard parser too
+            try
+            {
+                SimpleDateFormat sf = new SimpleDateFormat(pattern, locale);
+                Date d2 = sf.parse(input);
+                assertEquals("std:" + pattern, expected, d2);
+            }
+            catch(java.text.ParseException e)
+            {
+                // thrown when the input does not match the pattern
+                assertEquals("std:" + pattern, null, expected);
+            }
+            catch(IllegalArgumentException e)
+            {
+                // thrown when the pattern is not value
+                assertEquals("std:" + pattern, null, expected);
+            }
+        }
+    }
+    
+    //Try to parse non valid data
+    public void testParseInvalidValue()  throws Exception {
+        Object[] data =
+        {
+                "yyyy", "x1987",
+                "yyy", "98someinvalid7",                
+                "yy", "87x/dksk/-",
+                "y", "x87x-/\\233",
+                "MMMM", "Marchx",
+                "MMMM", "xMarch",
+                "MMMM", "Marcxh",
+                "MMM", "xMar",
+                "MMM", "xMxarx",
+                "MMM", "Marx",
+                "MM", "x03",
+                "MM", "0x3",
+                "MM", "03x",
+                "M", "x3",
+                "M", "3x",
+                "dd", "x12",
+                "HH", "0x4",
+                "H", "4x",
+                "hh", "04x",
+                "h", "4x",
+                "mm", "x23",
+                "m", "23x",
+                "ss", "x59",
+                "s", "59x",
+                "a", "AMx",                
+                "yyyy-MM-dd", "1987-0x1-08",
+                "yyyy-MM-dd", "1987-01-08x",
+                "yyyy-MM-dd", "x1987-0x1-08",
+                "yyyy--MM-:()dd", "x1987--01-:()08",
+                "yyyy--MM-:()dd", "1987--01-:()0x8",
+                "yyyy--MM-:()dd", "1987--01-:()08x",
+                "yyyy'T'MM'T'dd", "1987T01'T'08",
+                "yyyy'T'MM'T'dd", "T1987T01T08",
+                "yyyy'T'MM'T'dd", "19T87T01T08",
+                "yyyy'T'MM'T'dd", "1987T01T08T",
+                "yyyyRMMRdd", "1987-01-08",
+                "yyyyRMMRdd", "1987/01/08",
+                "yyyyRMMRdd", "1987'R'01-08",
+                "yyyy'year'MM'month'dd", "2003year0x4month06",
+                "yyyy'year'MM'month'dd", "2003'year'04month06",
+                "yyyy'year'MM'month'dd", "2003'year'04monxth06",
+                "yyyy'year'MM'month'dd", "2003YEAR04month06",
+                "yyyy'year'MM'month'dd", "2003yexr04month06",
+                "yy-MM-dd", "x99-04-06", 
+                "yy-MM-dd", "9x9-04-06",
+                "yy-MM-dd", "99-04-0x6",
+                "yy-MM-dd", "99-x04-06",
+                "yy-MM-dd", "99-x04-06",
+                "yy-MM-dd", "99-04-06y",
+        };
+        Locale locale = Locale.ENGLISH;
+        for(int i=0; i<data.length; i+=2)
+        {
+            String pattern = (String) data[i];
+            String input = (String) data[i+1];
+
+            SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
+            Date d = sdf.parse(input);
+            assertNull("Parsing should fail when using this pattern "+
+                    pattern+" and this input "+input,d);
+        }
+    }
+
+    // try to format with various combinations, and see what we get
+    public void testFormatAssorted() throws Exception
+    {
+        Date d = new Date();
+        d.setYear(1987 - 1900);
+        d.setMonth(2);
+        d.setDate(12);
+        d.setHours(4);
+        d.setMinutes(23);
+        d.setSeconds(59);
+        
+        String[] data =
+        {
+            // test standard, with literals
+            "yyyy-MM-dd", "1987-03-12",
+            
+            // test standard, with multichar literal sequences: any non-alpha
+            "yyyy--MM-:()dd", "1987--03-:()12",
+            
+            // test standard, with non-pattern chars.--> error
+            "yyyyTMMTdd", null,
+            
+            // test standard, with non-pattern chars.
+            "yyyy'T'MM'T'dd", "1987T03T12",
+            
+            // test quoted text
+            "yyyy'year'MM'month'dd", "1987year03month12",
+        };
+
+        Locale locale = Locale.ENGLISH;
+        for(int i=0; i<data.length; i+=2)
+        {
+            String pattern = data[i];
+            String expected = data[i+1];
+
+            // format it with our code, and check against expected.
+            SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
+            String s = sdf.format(d);
+            assertEquals("custom:" + pattern, expected, s);
+
+            // try with the standard parser too
+            try
+            {
+                SimpleDateFormat sf = new SimpleDateFormat(pattern, locale);
+                String s2 = sf.format(d);
+                assertEquals("std:" + pattern, expected, s2);
+            }
+            catch(IllegalArgumentException e)
+            {
+                // thrown when the pattern is not value
+                assertEquals("std:" + pattern, null, expected);
+            }
+        }
+    }
+
+    // test just the very basics of date parsing
+    public void testWeekParseSimple()
+    {
+        SimpleDateFormatter sdf = new SimpleDateFormatter("xxxx-ww", null);
+        Date d = sdf.parse("2009-06");
+
+        assertNotNull(d);
+        assertEquals(2009, d.getYear() + 1900);
+        assertEquals(2, d.getMonth() + 1);
+        assertEquals(2, d.getDate());
+        assertEquals(0, d.getHours());
+        assertEquals(0, d.getMinutes());
+        assertEquals(0, d.getSeconds());
+    }
+    
+    public void testWeekFormatAgainstJoda() throws Exception
+    {
+        // for every year from 2000-2010, test:
+        //   1-8 jan jan
+        //   29,30 may,
+        //   1-8 june
+        //   23-31 dec
+         for(int year = 2000; year < 2020; ++year)
+         {
+             checkWeekFormatAgainstJoda(year, 0, 1);
+             checkWeekFormatAgainstJoda(year, 0, 2);
+             checkWeekFormatAgainstJoda(year, 0, 3);
+             checkWeekFormatAgainstJoda(year, 0, 4);
+             checkWeekFormatAgainstJoda(year, 0, 5);
+             checkWeekFormatAgainstJoda(year, 0, 6);
+             checkWeekFormatAgainstJoda(year, 0, 7);
+             checkWeekFormatAgainstJoda(year, 0, 8);
+
+             checkWeekFormatAgainstJoda(year, 4, 29);
+             checkWeekFormatAgainstJoda(year, 4, 30);
+             checkWeekFormatAgainstJoda(year, 5, 1);
+             checkWeekFormatAgainstJoda(year, 5, 2);
+             checkWeekFormatAgainstJoda(year, 5, 3);
+             checkWeekFormatAgainstJoda(year, 5, 4);
+             checkWeekFormatAgainstJoda(year, 5, 5);
+             checkWeekFormatAgainstJoda(year, 5, 6);
+             checkWeekFormatAgainstJoda(year, 5, 7);
+             checkWeekFormatAgainstJoda(year, 5, 8);
+
+             checkWeekFormatAgainstJoda(year, 11, 23);
+             checkWeekFormatAgainstJoda(year, 11, 24);
+             checkWeekFormatAgainstJoda(year, 11, 25);
+             checkWeekFormatAgainstJoda(year, 11, 26);
+             checkWeekFormatAgainstJoda(year, 11, 27);
+             checkWeekFormatAgainstJoda(year, 11, 28);
+             checkWeekFormatAgainstJoda(year, 11, 29);
+             checkWeekFormatAgainstJoda(year, 11, 30);
+             checkWeekFormatAgainstJoda(year, 11, 31);
+         }
+    }
+
+    private void checkWeekFormatAgainstJoda(int year, int month, int day)
+    {
+        Date date = new Date(year-1900, month, day);
+        DateTime jdt = new DateTime(date.getTime());
+        int jodaWeekOfWeekyear = jdt.getWeekOfWeekyear();
+        int jodaWeekyear = jdt.getWeekyear();
+
+        WeekDate iwd = SimpleDateFormatter.getIsoWeekDate(date);
+
+        // the java.util.Date convention is that 1 = monday
+        int firstDayOfWeek = 1;
+        WeekDate jwd = SimpleDateFormatter.getWeekDate(date, firstDayOfWeek);
+
+        /*
+        String ds = new SimpleDateFormat("yyyy-MM-dd").format(date);
+        System.out.println(
+            ds + ":"
+            + "(" + jodaWeekyear + "-" + jodaWeekOfWeekyear + ")"
+            + ",(" + iwd.year + "-" + iwd.week + ")"
+            + ",(" + jwd.year + "-" + jwd.week + ")"
+            );
+            */
+        assertEquals(jodaWeekyear, iwd.getYear());
+        assertEquals(jodaWeekOfWeekyear, iwd.getWeek());
+        assertEquals(jodaWeekyear, jwd.getYear());
+        assertEquals(jodaWeekOfWeekyear, jwd.getWeek());
+    }
+}

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/renderkit/html/util/AddResourceTest.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/renderkit/html/util/AddResourceTest.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/renderkit/html/util/AddResourceTest.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/renderkit/html/util/AddResourceTest.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,364 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.renderkit.html.util;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.myfaces.test.AbstractTomahawkViewControllerTestCase;
+import org.apache.myfaces.webapp.filter.servlet.AbstractAttributeMap;
+import org.apache.myfaces.webapp.filter.servlet.RequestHeaderMap;
+import org.apache.myfaces.webapp.filter.servlet.RequestHeaderValuesMap;
+import org.apache.shale.test.mock.MockExternalContext;
+import org.apache.shale.test.mock.MockPrintWriter;
+import org.apache.shale.test.mock.MockResponseWriter;
+
+/**
+ * Unit test for the AddResource class which can output script, style and inline
+ * javascript into the header or body of an HTML response page.
+ */
+public class AddResourceTest extends AbstractTomahawkViewControllerTestCase
+{
+    public AddResourceTest(String name)
+    {
+        super(name);
+    }
+
+    public void testGetInstance()
+    {
+
+       Map cacheMap = new LinkedHashMap();
+
+        AddResource instance1 = AddResourceFactory.getInstance(null,cacheMap, "/test1", null);
+        assertNotNull(instance1);
+
+        /* no longer true
+        AddResource instance2 = AddResourceFactory.getInstance(null, "/test2", null);
+        assertNotSame(instance1, instance2);
+        */
+
+        AddResourceFactory.getInstance(null,cacheMap, "/test1", null);
+    }
+    
+    /*
+    public void setUp()
+    {
+        // Make sure a FacesContext configured from some previous test case
+        // doesn't interfere with the test case we are about to run...
+        FacesContextHelper.setCurrentInstance(null);
+    }
+
+    public void tearDown()
+    {
+        // Make sure a FacesContext we may have configured in the test case
+        // just completed doesn't interfere with test cases run later.
+        FacesContextHelper.setCurrentInstance(null);
+    }
+    */
+
+    /**
+     * Simple test helper class to allow unit tests to configure
+     * mock FacesContext objects as the "current instance".
+     * <p>
+     * The method FacesContext.setCurrentInstance is protected, and
+     * hence cannot be accessed by unit tests wanting to configure
+     * a mock object as the value seen by code calling method
+     * FacesContext.getCurrentInstance().
+     */
+    /*
+    private static abstract class FacesContextHelper extends FacesContext
+    {
+        public static void setCurrentInstance(FacesContext other)
+        {
+            FacesContext.setCurrentInstance(other);
+        }
+    }*/
+
+    /**
+     * Configure a fake JSF environment for a test, consisting of a
+     * FacesContext and dependent objects.
+     * <p>
+     * EasyMock control objects are used to emulate the necessary bits.
+     */
+    /*
+    private static class MockState
+    {
+        Writer _writer;
+        ResponseWriter _htmlResponseWriter;
+        MockControl _servletRequestControl;
+        HttpServletRequest _servletRequest;
+        MockControl _servletResponseControl;
+        HttpServletResponse _servletResponse;
+        FacesContext _facesContext;
+
+        public void setup() throws IOException
+        {
+            // set up a writer object to be the "response" output stream.
+            _writer = new StringWriter();
+            String contentType = "text/html";
+            String charEncoding = "UTF-8";
+            _htmlResponseWriter = new HtmlResponseWriterImpl(_writer, contentType, charEncoding);
+
+            // Mock ServletRequest object that:
+            // * returns "/test" for context path
+            // * returns "/test/foo.jsp" for servlet path
+            // * returns "null" for getPathInfo
+            // * returns "null" for getHeader
+            // * returns "null" for getAttribute
+            // * returns null for getSession
+            _servletRequestControl = MockControl.createControl(HttpServletRequest.class);
+            _servletRequest = (HttpServletRequest) _servletRequestControl.getMock();
+            _servletRequest.getContextPath();
+            _servletRequestControl.setReturnValue("/test", MockControl.ZERO_OR_MORE);
+            _servletRequest.getServletPath();
+            _servletRequestControl.setReturnValue("/test/foo.jsp", MockControl.ZERO_OR_MORE);
+            _servletRequest.getPathInfo();
+            _servletRequestControl.setReturnValue("", MockControl.ZERO_OR_MORE);
+            _servletRequest.getHeader("");
+            _servletRequestControl.setMatcher(MockControl.ALWAYS_MATCHER);
+            _servletRequestControl.setReturnValue(null, MockControl.ZERO_OR_MORE);
+            _servletRequest.getAttribute("");
+            _servletRequestControl.setMatcher(MockControl.ALWAYS_MATCHER);
+            _servletRequestControl.setReturnValue(null, MockControl.ZERO_OR_MORE);
+            _servletRequest.setAttribute("", "");
+            _servletRequestControl.setMatcher(MockControl.ALWAYS_MATCHER);
+            _servletRequestControl.setVoidCallable(MockControl.ZERO_OR_MORE);
+            _servletRequest.getSession(false);
+            _servletRequestControl.setReturnValue(null, MockControl.ZERO_OR_MORE);
+            _servletRequestControl.replay();
+
+            // Mock ServletResponse object that:
+            // * returns appropriate encoded URLs
+            // * returns a PrintWriter wrapping this object's writer member for
+            //   calls to getWriter
+            _servletResponseControl = MockControl.createControl(HttpServletResponse.class);
+            _servletResponse = (HttpServletResponse) _servletResponseControl.getMock();
+            _servletResponse.encodeURL("/test/scripts/script1");
+            _servletResponseControl.setReturnValue("encoded(/test/scripts/script1)", MockControl.ZERO_OR_MORE);
+            _servletResponse.getWriter();
+            _servletResponseControl.setReturnValue(new PrintWriter(_writer), MockControl.ZERO_OR_MORE);
+            _servletResponse.getCharacterEncoding();
+            _servletResponseControl.setReturnValue("UTF-8", MockControl.ZERO_OR_MORE);
+            _servletResponseControl.replay();
+
+            // The FacesContext needs FactoryFinder configured.
+            FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, ApplicationFactoryImpl.class.getName());
+            FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, RenderKitFactoryImpl.class.getName());
+
+            // Now create a FacesContext....
+            _facesContext = new ServletFacesContextImpl(null,
+                    _servletRequest, _servletResponse);
+            _facesContext.setResponseWriter(_htmlResponseWriter);
+        }
+
+        public void verifyControls()
+        {
+            _servletRequestControl.verify();
+            _servletResponseControl.verify();
+        }
+    }*/
+
+    public void testAddJavaScriptHere() throws IOException
+    {
+        //MockState mockState = new MockState();
+        //mockState.setup();
+
+        request.setPathElements("/test", "", "", "");
+        // now start the test
+        AddResource instance1 = AddResourceFactory.getInstance(null,null,"/test", null);
+        instance1.addJavaScriptHere(facesContext, "/scripts/script1");
+
+        // verify that our mock objects got the expected callbacks
+        //mockState.verifyControls();
+
+        // verify that:
+        // *script tag is output
+        // * type attribute is right,
+        // * URL has context path prepended to it
+        // * URL has been encoded
+        // * HTML comments have been used to hide script from non-script-aware
+        //   browsers.
+        //
+        // NOTE: are comments required to hide this script from browsers when
+        // there isn't any script body content (just a src attr)?
+        String scriptValue = ((MockResponseWriter)facesContext.getResponseWriter()).getWriter().toString(); 
+        
+        assertEquals(scriptValue, "<script type=\"text/javascript\" src=\"/test/scripts/script1\"/>");
+    }
+    
+    public static class CustomMockExternalContext extends MockExternalContext
+    {
+        private Map _requestHeaderMap;
+        private Map _requestHeaderValuesMap;
+        
+        public CustomMockExternalContext(ServletContext context,
+                HttpServletRequest request, HttpServletResponse response)
+        {
+            super(context, request, response);
+        }
+
+        @Override
+        public Map getRequestHeaderMap()
+        {
+            if (_requestHeaderMap == null)
+            {
+                _requestHeaderMap = new RequestHeaderMap((HttpServletRequest)request);
+            }
+            return _requestHeaderMap;                        
+        }
+
+        @Override
+        public Map getRequestHeaderValuesMap()
+        {
+            if (_requestHeaderValuesMap == null)
+            {
+                _requestHeaderValuesMap = new RequestHeaderValuesMap((HttpServletRequest)request);
+            }
+            return _requestHeaderValuesMap;
+        }
+    }
+    
+    public static class RequestHeaderMap extends AbstractAttributeMap
+    {
+        private final HttpServletRequest _httpServletRequest;
+
+        RequestHeaderMap(HttpServletRequest httpServletRequest)
+        {
+            _httpServletRequest = httpServletRequest;
+        }
+
+        protected Object getAttribute(String key)
+        {
+            return _httpServletRequest.getHeader(key);
+        }
+
+        protected void setAttribute(String key, Object value)
+        {
+            throw new UnsupportedOperationException(
+                "Cannot set HttpServletRequest Header");
+        }
+
+        protected void removeAttribute(String key)
+        {
+            throw new UnsupportedOperationException(
+                "Cannot remove HttpServletRequest Header");
+        }
+
+        protected Enumeration getAttributeNames()
+        {
+            return _httpServletRequest.getHeaderNames();
+        }
+
+        public void putAll(Map t)
+        {
+            throw new UnsupportedOperationException();
+        }
+
+
+        public void clear()
+        {
+            throw new UnsupportedOperationException();
+        }    
+    }
+
+    public static class RequestHeaderValuesMap extends AbstractAttributeMap
+    {
+        private final HttpServletRequest _httpServletRequest;
+        private final Map                _valueCache = new HashMap();
+
+        RequestHeaderValuesMap(HttpServletRequest httpServletRequest)
+        {
+            _httpServletRequest = httpServletRequest;
+        }
+
+        protected Object getAttribute(String key)
+        {
+            Object ret = _valueCache.get(key);
+            if (ret == null)
+            {
+                _valueCache.put(key, ret = toArray(_httpServletRequest
+                    .getHeaders(key)));
+            }
+
+            return ret;
+        }
+
+        protected void setAttribute(String key, Object value)
+        {
+            throw new UnsupportedOperationException(
+                "Cannot set HttpServletRequest HeaderValues");
+        }
+
+        protected void removeAttribute(String key)
+        {
+            throw new UnsupportedOperationException(
+                "Cannot remove HttpServletRequest HeaderValues");
+        }
+
+        protected Enumeration getAttributeNames()
+        {
+            return _httpServletRequest.getHeaderNames();
+        }
+
+        private String[] toArray(Enumeration e)
+        {
+            List ret = new ArrayList();
+
+            while (e.hasMoreElements())
+            {
+                ret.add(e.nextElement());
+            }
+
+            return (String[]) ret.toArray(new String[ret.size()]);
+        }
+    }
+
+    public void testWriteWithFullHeader() throws IOException
+    {
+        //MockState mockState = new MockState();
+        //mockState.setup();
+        externalContext = new CustomMockExternalContext(servletContext, request, response);
+        facesContext.setExternalContext(externalContext);
+
+        request.setPathElements("/test", "", "", "");
+        String originalResponse =
+            "<html><head></head><body></body></html>";
+
+        AddResource ar = AddResourceFactory.getInstance(null,null,"/test", null);
+        ar.parseResponse(request,originalResponse,response);
+        ar.writeWithFullHeader(request,response);
+        ar.writeResponse(request,response);
+
+        //mockState.verifyControls();
+
+        String returnedResponse = new String(((MockPrintWriter)response.getWriter()).content());
+        
+        //System.out.println(facesContext.getResponseWriter().toString());
+        assertEquals(originalResponse, returnedResponse);
+    }
+}

Added: myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/renderkit/html/util/ReducedHTMLParserTest.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/renderkit/html/util/ReducedHTMLParserTest.java?rev=955793&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/renderkit/html/util/ReducedHTMLParserTest.java (added)
+++ myfaces/tomahawk/trunk/core12/src/test/java/org/apache/myfaces/renderkit/html/util/ReducedHTMLParserTest.java Thu Jun 17 23:57:54 2010
@@ -0,0 +1,511 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.renderkit.html.util;
+
+import junit.framework.TestCase;
+import org.apache.myfaces.renderkit.html.util.CallbackListener;
+import org.apache.myfaces.renderkit.html.util.ReducedHTMLParser;
+
+/**
+ * Unit test for the ReducedHTMLParser class which detects tags within an HTML document.
+ */
+public class ReducedHTMLParserTest extends TestCase
+{
+    public static class ParseCallbackListener implements CallbackListener
+    {
+        int beforeHeadStart = -1;
+        int afterHeadStart = -1;
+        int beforeHeadEnd = -1;
+        int afterHeadEnd = -1;
+        int beforeBodyStart = -1;
+        int afterBodyStart = -1;
+        int beforeBodyEnd = -1;
+        int afterBodyEnd = -1;
+
+        public void openedStartTag(int charIndex, int tagIdentifier)
+        {
+            if (tagIdentifier == ReducedHTMLParser.HEAD_TAG)
+            {
+                beforeHeadStart = charIndex;
+            }
+            else if (tagIdentifier == ReducedHTMLParser.BODY_TAG)
+            {
+                beforeBodyStart = charIndex;
+            }
+        }
+
+        public void closedStartTag(int charIndex, int tagIdentifier)
+        {
+            if (tagIdentifier == ReducedHTMLParser.HEAD_TAG)
+            {
+                afterHeadStart = charIndex;
+            }
+            else if (tagIdentifier == ReducedHTMLParser.BODY_TAG)
+            {
+                afterBodyStart = charIndex;
+            }
+        }
+
+        public void openedEndTag(int charIndex, int tagIdentifier)
+        {
+            if (tagIdentifier == ReducedHTMLParser.HEAD_TAG)
+            {
+                beforeHeadEnd = charIndex;
+            }
+            else if (tagIdentifier == ReducedHTMLParser.BODY_TAG)
+            {
+                beforeBodyEnd = charIndex;
+            }
+        }
+
+        public void closedEndTag(int charIndex, int tagIdentifier)
+        {
+            if (tagIdentifier == ReducedHTMLParser.HEAD_TAG)
+            {
+                afterHeadEnd = charIndex;
+            }
+            else if (tagIdentifier == ReducedHTMLParser.BODY_TAG)
+            {
+                afterBodyEnd = charIndex;
+            }
+        }
+
+        public void attribute(int charIndex, int tagIdentifier, String key, String value)
+        {
+        }
+    }
+
+    public void testIsFinished1()
+    {
+        CharSequence seq = "";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(seq, listener);
+        assertTrue("Empty sequence is finished", parser.isFinished());
+    }
+
+    public void testIsFinished2()
+    {
+        CharSequence seq = "xx yy";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(seq, listener);
+
+        assertFalse("Sequence is finished", parser.isFinished());
+        parser.consumeNonWhitespace();
+        assertFalse("Sequence is finished", parser.isFinished());
+        parser.consumeWhitespace();
+        assertFalse("Sequence is finished", parser.isFinished());
+        parser.consumeNonWhitespace();
+        assertTrue("Sequence is finished", parser.isFinished());
+    }
+
+    public void testConsumeWhitespace()
+    {
+        CharSequence seq = "  \t  \r\n   xx    yy  ";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(seq, listener);
+
+        // test that one call consumes all available whitespace
+        // and that all sorts of whitespace are consumed.
+        assertFalse("Sequence is finished", parser.isFinished());
+        parser.consumeWhitespace();
+        String word1 = parser.consumeNonWhitespace();
+        assertEquals("xx found", "xx", word1);
+
+        // test that multiple calls don't consume anything but whitespace
+        parser.consumeWhitespace();
+        parser.consumeWhitespace();
+        parser.consumeWhitespace();
+        String word2 = parser.consumeNonWhitespace();
+        assertEquals("yy found", "yy", word2);
+
+        // test that no failure occurs from consuming whitespace at the
+        // end of the sequence
+        assertFalse("Sequence is finished", parser.isFinished());
+        parser.consumeWhitespace();
+        parser.consumeWhitespace();
+        assertTrue("Sequence is finished", parser.isFinished());
+    }
+
+    public void testConsumeNonWhitespace()
+    {
+        CharSequence seq = "xx yy zz";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(seq, listener);
+
+        String word1 = parser.consumeNonWhitespace();
+        assertEquals("xx found", "xx", word1);
+
+        // test that a call against whitespace returns null
+        String noWord = parser.consumeNonWhitespace();
+        assertNull("ConsumeNonWhitespace when whitespace is present", noWord);
+
+        // test that no exception is generated for multiple calls
+        parser.consumeNonWhitespace();
+        parser.consumeNonWhitespace();
+
+        parser.consumeWhitespace();
+        String word2 = parser.consumeNonWhitespace();
+        assertEquals("yy found", "yy", word2);
+
+        // test word that is at end of sequence
+        parser.consumeWhitespace();
+        String word3 = parser.consumeNonWhitespace();
+        assertEquals("zz found", "zz", word3);
+
+        // test that isFinished is set
+        assertTrue("Sequence is finished", parser.isFinished());
+
+        // test that no failure occurs from consuming nonwhitespace at the
+        // end of the sequence
+        noWord = parser.consumeNonWhitespace();
+        assertNull("ConsumeNonWhitespace at end of sequence", noWord);
+    }
+
+    public void testConsumeMatch()
+    {
+        CharSequence seq = "xx <!-- yy --> zz";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(seq, listener);
+
+        // test non-match
+        assertFalse("Match non-matching pattern", parser.consumeMatch("ffff"));
+
+        // test valid match. Also verifies that previous match failure didn't
+        // move the parsing offset.
+        assertTrue("Match matching pattern", parser.consumeMatch("xx"));
+
+        // this won't match until whitespace removed
+        assertFalse("Match non-matching pattern", parser.consumeMatch("<!--"));
+        parser.consumeWhitespace();
+        assertTrue("Match matching pattern", parser.consumeMatch("<!--"));
+
+        // repeat
+        assertFalse("Match non-matching pattern", parser.consumeMatch("yy"));
+        parser.consumeWhitespace();
+        assertTrue("Match matching pattern", parser.consumeMatch("yy"));
+
+        parser.consumeWhitespace();
+        assertTrue("Match matching pattern", parser.consumeMatch("-->"));
+
+        // match at end of sequence
+        parser.consumeWhitespace();
+        assertTrue("Match matching pattern", parser.consumeMatch("zz"));
+
+        // check no exception on matching on finished sequence
+        assertFalse("Match non-matching pattern", parser.consumeMatch("aa"));
+    }
+
+    public void testConsumeElementName()
+    {
+        CharSequence seq = "  foo  t:foo t:FooBar t:foo_bar element-name/>";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(seq, listener);
+
+        // test that consumeElementName will automatically skip any leading whitespace
+        String name1 = parser.consumeElementName();
+        assertEquals("Element name matched", "foo", name1);
+
+        String name2 = parser.consumeElementName();
+        assertEquals("Element name matched", "t:foo", name2);
+
+        String name3 = parser.consumeElementName();
+        assertEquals("Element name matched", "t:FooBar", name3);
+
+        String name4 = parser.consumeElementName();
+        assertEquals("Element name matched", "t:foo_bar", name4);
+
+        String name5 = parser.consumeElementName();
+        assertEquals("Element name matched", "element-name", name5);
+    }
+
+    public void testConsumeStringBasic()
+    {
+        CharSequence s1 = "'string1' \"string2\"";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(s1, listener);
+
+        // Note that the consumeString method always expects the leading quote to
+        // have been consumed already..
+
+        // test single-quote delimited
+        parser.consumeMatch("'");
+        String str1 = parser.consumeString('\'');
+        assertEquals("String correctly parsed", "string1", str1);
+
+        // test double-quote delimited
+        parser.consumeWhitespace();
+        parser.consumeMatch("\"");
+        String str2 = parser.consumeString('\"');
+        assertEquals("String correctly parsed", "string2", str2);
+    }
+
+    public void testConsumeStringEscapedQuote()
+    {
+        char quoteMark = '\'';
+
+        // build literal sequence 'don\'t quote me' not-in-the-string
+        StringBuffer buf = new StringBuffer();
+        buf.append(quoteMark);
+        buf.append("don\\'t quote me");
+        buf.append(quoteMark);
+        buf.append(" not-in-the-string");
+
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(buf, listener);
+
+        // Note that the consumeString method always expects the leading quote to
+        // have been consumed already..
+
+        parser.consumeMatch("'");
+        String str1 = parser.consumeString('\'');
+        assertEquals("String correctly parsed", "don't quote me", str1);
+    }
+
+    public void testConsumeStringEscapedNonQuote()
+    {
+        char quoteMark = '"';
+
+        // build literal sequence 'don\'t quote me' not-in-the-string
+        StringBuffer buf = new StringBuffer();
+        buf.append(quoteMark);
+        buf.append("don\\'t quote me");
+        buf.append(quoteMark);
+        buf.append(" not-in-the-string");
+
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(buf, listener);
+
+        // Note that the consumeString method always expects the leading quote to
+        // have been consumed already..
+
+        parser.consumeMatch("\"");
+        String str1 = parser.consumeString('"');
+        assertEquals("String correctly parsed", "don\\'t quote me", str1);
+    }
+    
+    public void testConsumeStringEscapedEscape()
+    {
+        char quoteMark = '\'';
+        char backSlash = '\\';
+
+        // build literal sequence 'don\\'t escape me' not-in-the-string
+        // The double-backslash should be treated as a single backslash
+        // which does *not* escape the following quote.
+        StringBuffer buf = new StringBuffer();
+        buf.append(quoteMark);
+        buf.append("don");
+        buf.append(backSlash);
+        buf.append(backSlash);
+        buf.append(quoteMark);
+        buf.append("t escape me");
+        buf.append(quoteMark);
+
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(buf, listener);
+
+        // Note that the consumeString method always expects the leading quote to
+        // have been consumed already..
+
+        parser.consumeMatch("'");
+        String str1 = parser.consumeString('\'');
+        assertEquals("String correctly parsed", "don" + backSlash, str1);
+    }
+
+    public void testConsumeAttrValue()
+    {
+        CharSequence seq = "  bare 'quoted 1' \"quoted 2\" bare2 ";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(seq, listener);
+
+        String val1 = parser.consumeAttrValue();
+        assertEquals("Attr value matched", "bare", val1);
+
+        String val2 = parser.consumeAttrValue();
+        assertEquals("Attr value matched", "quoted 1", val2);
+
+        String val3 = parser.consumeAttrValue();
+        assertEquals("Attr value matched", "quoted 2", val3);
+
+        String val4 = parser.consumeAttrValue();
+        assertEquals("Attr value matched", "bare2", val4);
+    }
+
+    public void testConsumeExcept()
+    {
+        CharSequence seq = "abc$$#dd  ee#ff-gghh ii";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(seq, listener);
+
+        parser.consumeExcept("#e");
+        String val1 = parser.consumeNonWhitespace();
+        assertEquals("ConsumeExcept skipped expected chars", "#dd", val1);
+
+        parser.consumeExcept("z-");
+        String val2 = parser.consumeNonWhitespace();
+        assertEquals("ConsumeExcept skipped expected chars", "-gghh", val2);
+
+        // check that consumeExcept will reach end of buffer ok if none of
+        // the desired chars are found
+        assertFalse(parser.isFinished());
+        parser.consumeExcept("z");
+        assertTrue(parser.isFinished());
+
+        // check that calling consumeExcept is safe at end-of-buffer
+        parser.consumeExcept("z");
+    }
+
+    // test parsing completes when a lessthan is not followed by an element name,
+    // and there is just whitespace up to end of the input.
+    public void testParseBadTagNoElementName1()
+    {
+        String s = "xxxx \n\n <# \n\n";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(s, listener);
+
+        parser.parse();
+        assertTrue(parser.isFinished());
+    }
+
+    // test parsing completes when a lessthan is not followed by an element name,
+    public void testParseBadTagNoElementName2()
+    {
+        String s = "xxxx \n\n <# \n\n hi there";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(s, listener);
+
+        parser.parse();
+        assertTrue(parser.isFinished());
+    }
+
+    // test parsing completes when an invalid char is found where an attribute name
+    // is expected.
+    public void testParseBadTagInvalidAttributeName()
+    {
+        String s = "<foo )/>";
+        CallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(s, listener);
+
+        parser.parse();
+        assertTrue(parser.isFinished());
+    }
+
+    // test CDATA sections are handled
+    public void testParseCDATA()
+    {
+        String s = "xx<head> <![CDATA[ <head> ]]> <body>";
+        ParseCallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(s, listener);
+
+        parser.parse();
+        assertTrue(parser.isFinished());
+        assertEquals("CDATA works", 8, listener.afterHeadStart);
+        assertEquals("CDATA works", 30, listener.beforeBodyStart);
+    }
+
+    // test PI sections are handled
+    public void testParsePI()
+    {
+        String s = "<?xml version=\"1.0\"?> xx<head> ";
+        ParseCallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(s, listener);
+
+        parser.parse();
+        assertTrue(parser.isFinished());
+        assertEquals("PI works", 30, listener.afterHeadStart);
+    }
+
+    // Test script element support; the spec states that a <script> or
+    // <style> tag can contain anything except "/>"
+    public void testScript()
+    {
+        String s1 = "<head>";
+        String s2 = "<script type='text/javascript'>"
+                    + "if (1<2) alert('foo');\n"
+                    + "if (1>2) alert('bar');\n"
+                    + "</script>";
+        String s3 = "</head>";
+        String s4 = "<body>";
+        String s5 = "</body>";
+
+        StringBuffer buf = new StringBuffer();
+        buf.append(s1);
+        buf.append(s2);
+        buf.append(s3);
+        buf.append(s4);
+        buf.append(s5);
+
+        ParseCallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(buf.toString(), listener);
+
+        parser.parse();
+        assertTrue(parser.isFinished());
+        assertEquals("Script works", s1.length(), listener.afterHeadStart);
+        int beforeHeadEnd = s1.length() + s2.length();
+        assertEquals("Script works", beforeHeadEnd, listener.beforeHeadEnd);
+        int beforeBodyStart = beforeHeadEnd + s3.length();
+        assertEquals("Script works", beforeBodyStart, listener.beforeBodyStart);
+        int beforeBodyEnd = beforeBodyStart + s4.length();
+        assertEquals("Script works", beforeBodyEnd, listener.beforeBodyEnd);
+    }
+
+    // test the full parse method
+    public void testParse()
+    {
+        String s0 = "<!DOCTYPE PUBLIC \"sss\" \"http:foo\">\n";
+        String s1 = "<html><head>";
+        String s2 = "\n<!-- a comment --><title>foo</title>";
+        String s3 = "</head>";
+        String s4 = "< body onclick='zz'>";
+        String s5 = "  bodytext ";
+        // if comments aren't correctly parsed, then this will cause the
+        // head/body start positions to get corrupted.
+        String s6 = "  <!-- <head> <body> -->";
+        // if xml attr strings aren't correctly parsed, then this will cause
+        // the head/body start positions to get corrupted
+        String s7 = "<t:foo a1='<head>' a2='<body>'/>";
+        String s8 = "</body> </html>";
+
+        StringBuffer buf = new StringBuffer();
+        buf.append(s0);
+        buf.append(s1);
+        buf.append(s2);
+        buf.append(s3);
+        buf.append(s4);
+        buf.append(s5);
+        buf.append(s6);
+        buf.append(s7);
+        buf.append(s8);
+
+        ParseCallbackListener listener = new ParseCallbackListener();
+        ReducedHTMLParser parser = new ReducedHTMLParser(buf, listener);
+
+        parser.parse();
+
+        // check that listener has correctly computed the offset to the char just
+        // before the </head> tag starts.
+        int afterHeadStart = s0.length() + s1.length();
+        assertEquals("Pos after <head> tag ", afterHeadStart, listener.afterHeadStart);
+
+        int beforeBodyStart = afterHeadStart + s2.length() + s3.length();
+        assertEquals("Pos before <body> tag", beforeBodyStart, listener.beforeBodyStart);
+
+        int afterBodyStart = beforeBodyStart + s4.length();
+        assertEquals("Pos after <body> tag", afterBodyStart, listener.afterBodyStart);
+    }
+}