WICKET-5651 Add TagTester#getChild(String tagName) method

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/5d47267e
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/5d47267e
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/5d47267e

Branch: refs/heads/wicket-6.x
Commit: 5d47267e94ba2eae0d188132774cc2dc61b03f68
Parents: f9668b5
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Tue Jul 22 14:41:38 2014 +0300
Committer: Martin Tzvetanov Grigorov <[email protected]>
Committed: Tue Jul 22 14:41:38 2014 +0300

----------------------------------------------------------------------
 .../apache/wicket/util/tester/TagTester.java    | 127 +++++++++++++++++--
 .../wicket/util/tester/TagTesterTest.java       |  24 ++++
 2 files changed, 141 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/5d47267e/wicket-core/src/main/java/org/apache/wicket/util/tester/TagTester.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/util/tester/TagTester.java 
b/wicket-core/src/main/java/org/apache/wicket/util/tester/TagTester.java
index e5a27af..827aabb 100644
--- a/wicket-core/src/main/java/org/apache/wicket/util/tester/TagTester.java
+++ b/wicket-core/src/main/java/org/apache/wicket/util/tester/TagTester.java
@@ -24,6 +24,7 @@ import java.util.regex.Pattern;
 import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.markup.parser.XmlPullParser;
 import org.apache.wicket.markup.parser.XmlTag;
+import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.string.Strings;
 import org.apache.wicket.util.value.IValueMap;
 
@@ -235,19 +236,16 @@ public class TagTester
 
        /**
         * Checks if the tag has a child with the given <code>tagName</code>.
-        * 
+        *
         * @param tagName
         *            the tag name to search for
         * @return <code>true</code> if this tag has a child with the given 
<code>tagName</code>.
         */
        public boolean hasChildTag(String tagName)
        {
-               boolean hasChild = false;
+               Args.notEmpty(tagName, "tagName");
 
-               if (Strings.isEmpty(tagName))
-               {
-                       throw new IllegalArgumentException("You need to provide 
a not empty/not null argument.");
-               }
+               boolean hasChild = false;
 
                if (openTag.isOpen())
                {
@@ -263,7 +261,7 @@ public class TagTester
                                        XmlPullParser p = new XmlPullParser();
                                        p.parse(markup);
 
-                                       XmlTag tag = null;
+                                       XmlTag tag;
                                        while ((tag = p.nextTag()) != null)
                                        {
                                                if 
(tagName.equalsIgnoreCase(tag.getName()))
@@ -276,16 +274,40 @@ public class TagTester
                        }
                        catch (Exception e)
                        {
-                               // NOTE: IllegalStateException(Throwable) only 
exists since Java 1.5
                                throw new WicketRuntimeException(e);
                        }
-
                }
 
                return hasChild;
        }
 
        /**
+        * Checks if the tag has a child with the given <code>tagName</code>.
+        *
+        * @param tagName
+        *            the tag name to search for
+        * @return <code>true</code> if this tag has a child with the given 
<code>tagName</code>.
+        */
+       public TagTester getChild(String tagName)
+       {
+               Args.notNull(tagName, "tagName");
+
+               TagTester childTagTester = null;
+
+               if (openTag.isOpen())
+               {
+                       // Get the content of the tag
+                       int startPos = openTag.getPos() + openTag.getLength();
+                       int endPos = closeTag.getPos();
+                       String markup = parser.getInput(startPos, 
endPos).toString();
+
+                       childTagTester = createTagByAttribute(markup, tagName);
+               }
+
+               return childTagTester;
+       }
+
+       /**
         * Gets a child tag for testing. If this tag contains child tags, you 
can get one of them as a
         * {@link TagTester} instance.
         * 
@@ -343,6 +365,92 @@ public class TagTester
        }
 
        /**
+        * Static factory method for creating a <code>TagTester</code> based on 
a tag name. Please note
+        * that it will return the first tag which matches the criteria.
+        *
+        * @param markup
+        *            the markup to look for the tag to create the 
<code>TagTester</code> from
+        *            the value which the attribute must have
+        * @return the <code>TagTester</code> which matches the tag by name in 
the markup
+        */
+       public static TagTester createTagByAttribute(String markup, String 
tagName)
+       {
+               TagTester tester = null;
+
+               if (Strings.isEmpty(markup) == false && 
Strings.isEmpty(tagName) == false)
+               {
+                       try
+                       {
+                               // remove the CDATA and
+                               // the id attribute of the component because it 
is often the same as the element's id
+                               markup = 
AJAX_COMPONENT_CDATA_OPEN.matcher(markup).replaceAll("<component>");
+                               markup = 
AJAX_COMPONENT_CDATA_CLOSE.matcher(markup).replaceAll("</component>");
+
+                               XmlPullParser parser = new XmlPullParser();
+                               parser.parse(markup);
+
+                               XmlTag elm;
+                               XmlTag openTag = null;
+                               XmlTag closeTag = null;
+                               int level = 0;
+                               while ((elm = parser.nextTag()) != null && 
closeTag == null)
+                               {
+                                       XmlTag xmlTag = elm;
+
+                                       String xmlTagName = xmlTag.getName();
+                                       if (openTag == null && 
xmlTagName.equalsIgnoreCase(tagName))
+                                       {
+                                               if (xmlTag.isOpen())
+                                               {
+                                                       openTag = xmlTag;
+                                               }
+                                               else if (xmlTag.isOpenClose())
+                                               {
+                                                       openTag = xmlTag;
+                                                       closeTag = xmlTag;
+                                               }
+                                       }
+                                       else if (openTag != null)
+                                       {
+                                               String openTagName = 
openTag.getName();
+                                               if (xmlTag.isOpen() && 
xmlTagName.equals(openTagName))
+                                               {
+                                                       level++;
+                                               }
+
+                                               if (xmlTag.isClose())
+                                               {
+                                                       if 
(xmlTagName.equals(openTagName))
+                                                       {
+                                                               if (level == 0)
+                                                               {
+                                                                       
closeTag = xmlTag;
+                                                                       
closeTag.setOpenTag(openTag);
+                                                               }
+                                                               else
+                                                               {
+                                                                       level--;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               if (openTag != null && closeTag != null)
+                               {
+                                       tester = new TagTester(parser, openTag, 
closeTag);
+                               }
+                       }
+                       catch (Exception e)
+                       {
+                               throw new WicketRuntimeException(e);
+                       }
+               }
+
+               return tester;
+       }
+
+       /**
         * Static factory method for creating a <code>TagTester</code> based on 
a tag found by an
         * attribute with a specific value. Please note that it will return the 
first tag which matches
         * the criteria. It's therefore good for attributes such as "id" or 
"wicket:id", but only if
@@ -435,7 +543,6 @@ public class TagTester
                        }
                        catch (Exception e)
                        {
-                               // NOTE: IllegalStateException(Throwable) only 
exists since Java 1.5
                                throw new WicketRuntimeException(e);
                        }
                }

http://git-wip-us.apache.org/repos/asf/wicket/blob/5d47267e/wicket-core/src/test/java/org/apache/wicket/util/tester/TagTesterTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/util/tester/TagTesterTest.java 
b/wicket-core/src/test/java/org/apache/wicket/util/tester/TagTesterTest.java
index 5674436..8041601 100644
--- a/wicket-core/src/test/java/org/apache/wicket/util/tester/TagTesterTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/util/tester/TagTesterTest.java
@@ -16,6 +16,11 @@
  */
 package org.apache.wicket.util.tester;
 
+import static org.hamcrest.Matchers.endsWith;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -250,6 +255,25 @@ public class TagTesterTest extends Assert
                assertFalse(tester.hasChildTag("p"));
        }
 
+       @Test
+       public void getChildByTagName()
+       {
+               TagTester tester = TagTester.createTagByAttribute(
+                       "<div id=\"id\">" +
+                               "<div class=\"radio\">" +
+                                       "<label>" +
+                                               "<input name=\"id\" 
type=\"radio\" value=\"0\" id=\"id1-0\"/> One" +
+                                       "</label>" +
+                               "</div>" +
+                       "</div>", "id", "id");
+               assertThat(tester.getChild("DIV"), is(notNullValue())); // 
case-insensitive
+               TagTester divClassRadioTagTester = tester.getChild("div");
+               assertThat(divClassRadioTagTester, is(notNullValue()));
+               TagTester labelTagTester = 
divClassRadioTagTester.getChild("label");
+               String labelMarkup = labelTagTester.getValue();
+               assertThat(labelMarkup, endsWith(" One"));
+       }
+
        /**
         * Test getMarkup returns the open-tag + content + close-tag
         */

Reply via email to