WICKET-5651 Add TagTester#getChild(String tagName) method (cherry picked from commit 5d47267e94ba2eae0d188132774cc2dc61b03f68)
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/112929d1 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/112929d1 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/112929d1 Branch: refs/heads/master Commit: 112929d1a879e446c1bb8a152f3b2b87b8b20beb Parents: 4ec4a07 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:46:18 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/112929d1/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 3c4e309..415117d 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/112929d1/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 */
