Author: ivaynberg
Date: Sat Jul  9 07:24:18 2011
New Revision: 1144611

URL: http://svn.apache.org/viewvc?rev=1144611&view=rev
Log:
ported wicket:for attribute to trunk
Issue: WICKET-1469

Added:
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
   (with props)
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
   (with props)
    
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
   (with props)
Modified:
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java

Modified: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java?rev=1144611&r1=1144610&r2=1144611&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java
 (original)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java
 Sat Jul  9 07:24:18 2011
@@ -19,6 +19,7 @@ package org.apache.wicket.markup;
 import java.util.ArrayList;
 
 import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.form.AutoLabelTagHandler;
 import org.apache.wicket.markup.parser.IMarkupFilter;
 import org.apache.wicket.markup.parser.IXmlPullParser;
 import org.apache.wicket.markup.parser.filter.ConditionalCommentFilter;
@@ -146,6 +147,7 @@ public class MarkupParser extends Abstra
                filters.add(new HtmlHandler());
                filters.add(new WicketRemoveTagHandler());
                filters.add(new WicketLinkTagHandler());
+               filters.add(new AutoLabelTagHandler());
                filters.add(new WicketNamespaceHandler(markupResourceStream));
 
                // Provided the wicket component requesting the markup is known 
...

Added: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java?rev=1144611&view=auto
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
 (added)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
 Sat Jul  9 07:24:18 2011
@@ -0,0 +1,365 @@
+package org.apache.wicket.markup.html.form;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.RawMarkup;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.parser.XmlPullParser;
+import org.apache.wicket.markup.parser.XmlTag;
+import org.apache.wicket.markup.resolver.IComponentResolver;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.util.string.AppendingStringBuffer;
+import org.apache.wicket.util.string.Strings;
+import org.apache.wicket.util.visit.IVisit;
+import org.apache.wicket.util.visit.IVisitor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Resolver that implements the {@code wicket:for} attribute functionality. 
The attribute makes it
+ * easy to set up {@code <label>} tags for form components by providing the 
following features
+ * without having to add any additional components in code:
+ * <ul>
+ * <li>Outputs the {@code for} attribute with the value equivalent to the 
markup id of the
+ * referenced form component</li>
+ * <li>Appends {@code required} css class to the {@code <label>} tag if the 
referenced form
+ * component is required</li>
+ * <li>Appends {@code error} css class to the {@code <label>} tag if the 
referenced form component
+ * has failed validation</li>
+ * <li>If the {@code <label>} tag contains {@code <span class='text'></span>} 
markup and the form
+ * component has a label configured either via the label model or a property 
files, the body of the
+ * {code <span>} will be replaced with the label</li>
+ * <li>If the {@code <label>} tag contains {@code <span 
class='text'>body</span>} markup and the
+ * form component does not have a label configured either via the label model 
or a properties file,
+ * the label of the form component will be set to the body of the {@code 
<span>} tag - in this
+ * example {@code body}</li>
+ * </ul>
+ * 
+ * <p>
+ * The value of the {@code wicket:for} atribute can either contain an id of 
the form component or a
+ * path a path to it using the standard {@code :} path separator. Note that 
{@code ..} can be used
+ * as part of the path to construct a reference to the parent container, eg 
{@code ..:..:foo:bar}.
+ * First the value of the attribute will be treated as a path and the {@code 
<label>} tag's closest
+ * parent container will be queried for the form component. If the form 
component cannot be resolved
+ * the value of the {@code wicket:for} attribute will be treated as an id and 
all containers will be
+ * searched from the closest parent to the page.
+ * </p>
+ * 
+ * <p>
+ * Given markup like this:
+ * 
+ * <code>
+ * [label wicket:for="name"][span class="text"]Name[/span]:[/label][input 
wicket:id="name" type="text"/]
+ * </code>
+ * 
+ * If the {@code name} component has its label set to 'First Name' the 
resulting output will be:
+ * <code>
+ * [label for="name5"][span class="text"]First Name[/span]:[/label][input 
name="name" type="text" id="name5"/]
+ * </code>
+ * 
+ * However, if the {@code name} component does not have a label set then it 
will be set to
+ * {@code Name} based on the markup.
+ * </p>
+ * 
+ * @author igor
+ */
+public class AutoLabelResolver implements IComponentResolver
+{
+       private static Logger logger = 
LoggerFactory.getLogger(AutoLabelResolver.class);
+
+       public Component resolve(MarkupContainer container, MarkupStream 
markupStream, ComponentTag tag)
+       {
+               if (!AutoLabelTagHandler.class.getName().equals(tag.getId()))
+               {
+                       return null;
+               }
+
+               final String id = tag.getAttribute("wicket:for").trim();
+
+               FormComponent<?> component = findRelatedComponent(container, 
id);
+
+               if (component == null)
+               {
+                       throw new WicketRuntimeException("Could not find form 
component with id: " + id +
+                               " while trying to resolve wicket:for 
attribute");
+               }
+               if (!(component instanceof FormComponent<?>))
+               {
+                       throw new WicketRuntimeException("Component pointed to 
by wicket:for attribute: " + id +
+                               " is not a form component");
+               }
+
+               if (!component.getOutputMarkupId())
+               {
+                       component.setOutputMarkupId(true);
+                       if (!component.hasBeenRendered())
+                       {
+                               logger.warn(
+                                       "Form component: {} is reference via a 
wicket:for attribute but does not have its outputMarkupId property set to true",
+                                       component.toString(false));
+                       }
+               }
+               final FormComponent<?> fc = component;
+
+               return new AutoLabel("label" + 
container.getPage().getAutoIndex(), fc);
+       }
+
+       protected FormComponent<?> findRelatedComponent(MarkupContainer 
container, final String id)
+       {
+               // try the quick and easy route first
+
+               Component component = container.get(id);
+               if (component != null && (component instanceof 
FormComponent<?>))
+               {
+                       return (FormComponent<?>)component;
+               }
+
+               // try the long way, search the hierarchy from the closest 
container up to the page
+
+               final Component[] searched = new Component[] { null };
+               while (container != null)
+               {
+                       component = container.visitChildren(Component.class,
+                               new IVisitor<Component, Component>()
+                               {
+                                       public void component(Component child, 
IVisit<Component> visit)
+                                       {
+                                               if (child == searched[0])
+                                               {
+                                                       // this container was 
already searched
+                                                       visit.dontGoDeeper();
+                                                       return;
+                                               }
+                                               if (id.equals(child.getId()) && 
(child instanceof FormComponent))
+                                               {
+                                                       visit.stop(child);
+                                                       return;
+                                               }
+                                       }
+                               });
+
+                       if (component != null && (component instanceof 
FormComponent))
+                       {
+                               return (FormComponent<?>)component;
+                       }
+
+                       // remember the container so we dont search it again, 
and search the parent
+                       searched[0] = container;
+                       container = container.getParent();
+               }
+
+               return null;
+       }
+
+       /**
+        * Component that is attached to the {@code <label>} tag and takes care 
of writing out the label
+        * text as well as setting classes on the {@code <label>} tag
+        * 
+        * @author igor
+        */
+       protected static class AutoLabel extends WebMarkupContainer
+       {
+               private final FormComponent<?> fc;
+
+               public AutoLabel(String id, FormComponent<?> fc)
+               {
+                       super(id);
+                       this.fc = fc;
+               }
+
+               @Override
+               protected void onComponentTag(ComponentTag tag)
+               {
+                       super.onComponentTag(tag);
+                       tag.put("for", fc.getMarkupId());
+                       if (fc.isRequired())
+                       {
+                               tag.append("class", "required", " ");
+                       }
+                       if (!fc.isValid())
+                       {
+                               tag.append("class", "error", " ");
+                       }
+               }
+
+               @Override
+               public void onComponentTagBody(MarkupStream markupStream, 
ComponentTag openTag)
+               {
+                       if (!(markupStream.get() instanceof RawMarkup))
+                       {
+                               // no raw markup found inside the label, do not 
modify the contents
+                               return;
+                       }
+
+                       // read all raw markup in the body and find the range 
of the label text inside it. the
+                       // range is specified as the body of the <span 
class='text'></span> tag.
+
+                       AppendingStringBuffer markup = 
readBodyMarkup(markupStream);
+                       int[] range = findLabelTextRange(markup);
+                       final int start = range[0];
+                       final int end = range[1];
+
+                       if (start < 0)
+                       {
+                               // if we could not find the range of the label 
text in the markup we have nothing
+                               // further to do
+
+                               super.onComponentTagBody(markupStream, openTag);
+                               return;
+                       }
+
+                       // based on whether or not the form component has a 
label set read or write it into the
+                       // markup
+
+                       String label = getFormComponentLabelText(fc);
+
+                       if (label != null)
+                       {
+                               // if label is set write it into the markup
+
+                               markup = markup.replace(start, end, label);
+                               replaceComponentTagBody(markupStream, openTag, 
markup);
+                       }
+                       else
+                       {
+                               // if label is not set, read it from the markup 
into the form component
+
+                               String markupLabel = markup.substring(start, 
end);
+                               fc.setLabel(Model.of(markupLabel));
+                               super.onComponentTagBody(markupStream, openTag);
+                       }
+               }
+
+               /**
+                * Finds start and end index of text in the label. This range 
is represented by the body of
+                * the {@code <span class='text'></span>} tag
+                * 
+                * @param markup
+                * @return
+                */
+               protected int[] findLabelTextRange(AppendingStringBuffer markup)
+               {
+                       int[] range = new int[] { -1, -1 };
+
+                       XmlPullParser parser = new XmlPullParser();
+                       XmlTag opening = null; // opening label text span tag
+                       XmlTag closing = null; // close label text span tag
+
+                       try
+                       {
+                               parser.parse(markup);
+
+                               XmlTag tag = null; // current tag
+
+                               int depth = 0; // depth of span tags
+                               int openDepth = -1; // depth of the label text 
open span tag
+
+                               while (((tag = parser.nextTag()) != null))
+                               {
+                                       if 
(!"span".equalsIgnoreCase(tag.getName()) || tag.getNamespace() != null)
+                                       {
+                                               // skip non-span tags
+                                               continue;
+                                       }
+
+                                       if (opening != null && tag.isClose() && 
depth == openDepth)
+                                       {
+                                               // found the closing tag we 
need, we are done
+                                               closing = tag;
+                                               break;
+                                       }
+
+                                       depth += tag.isOpen() ? 1 : -1;
+
+                                       if (opening == null && isTextSpan(tag))
+                                       {
+                                               // found the opening tag, keep 
looking for the closing one
+                                               opening = tag;
+                                               openDepth = depth;
+                                               continue;
+                                       }
+                               }
+                       }
+                       catch (Exception e)
+                       {
+                               throw new WicketRuntimeException(
+                                       "Could not parse markup while 
processing an auto label for component: " +
+                                               fc.toString(false), e);
+                       }
+
+                       if (opening != null)
+                       {
+                               // calculate the range of the tag's body, this 
is where the label text is/will be
+                               range[0] = opening.getPos() + 
opening.getLength();
+                               range[1] = closing.getPos();
+                       }
+
+                       return range;
+               }
+
+               protected AppendingStringBuffer readBodyMarkup(MarkupStream 
markupStream)
+               {
+                       int streamIndex = markupStream.getCurrentIndex();
+
+                       AppendingStringBuffer markup = new 
AppendingStringBuffer();
+                       do
+                       {
+                               
markup.append(((RawMarkup)markupStream.get()).toString());
+                               markupStream.next();
+                       }
+                       while ((markupStream.get() instanceof RawMarkup));
+
+                       markupStream.setCurrentIndex(streamIndex);
+
+                       return markup;
+               }
+
+               protected String getFormComponentLabelText(FormComponent<?> fc)
+               {
+                       String label = fc.getLabel() != null ? 
fc.getLabel().getObject() : null;
+                       if (label == null)
+                       {
+                               label = fc.getDefaultLabel("wicket:unknown");
+                               if ("wicket:unknown".equals(label))
+                               {
+                                       label = null;
+                               }
+                       }
+                       return label;
+               }
+
+               protected final boolean isTextSpan(XmlTag tag)
+               {
+                       if (!tag.isOpen())
+                               return false;
+
+                       if (!"span".equalsIgnoreCase(tag.getName()) || 
tag.getNamespace() != null)
+                               return false;
+
+                       String classNames = 
tag.getAttributes().getString("class");
+                       if (Strings.isEmpty(classNames))
+                               return false;
+
+                       boolean textClassFound = false;
+                       for (String className : classNames.split(" "))
+                       {
+                               if ("text".equals(className))
+                               {
+                                       textClassFound = true;
+                                       break;
+                               }
+                       }
+                       if (!textClassFound)
+                               return false;
+
+
+                       return true;
+               }
+
+       }
+
+
+}

Propchange: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java?rev=1144611&view=auto
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
 (added)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
 Sat Jul  9 07:24:18 2011
@@ -0,0 +1,53 @@
+package org.apache.wicket.markup.html.form;
+
+import java.text.ParseException;
+
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.MarkupElement;
+import org.apache.wicket.markup.WicketTag;
+import org.apache.wicket.markup.parser.AbstractMarkupFilter;
+
+/**
+ * Markup filter that identifies tags with the {@code wicket:for} attribute. 
See
+ * {@link AutoLabelResolver} for details.
+ * 
+ * @author igor
+ */
+public class AutoLabelTagHandler extends AbstractMarkupFilter
+{
+       @Override
+       protected MarkupElement onComponentTag(ComponentTag tag) throws 
ParseException
+       {
+               if (tag == null || tag.isClose() || tag instanceof WicketTag)
+               {
+                       return tag;
+               }
+
+               String related = tag.getAttribute("wicket:for");
+               if (related == null)
+               {
+                       return tag;
+               }
+
+               related = related.trim();
+               if (related.isEmpty())
+               {
+                       throw new ParseException("Tag contains an empty 
wicket:for attribute", tag.getPos());
+               }
+               if (!"label".equalsIgnoreCase(tag.getName()))
+               {
+                       throw new ParseException("Attribute wicket:for can only 
be attached to <label> tag",
+                               tag.getPos());
+               }
+               if (tag.getId() != null)
+               {
+                       throw new ParseException(
+                               "Attribute wicket:for cannot be used in 
conjunction with wicket:id", tag.getPos());
+               }
+
+               tag.setId(getClass().getName());
+               tag.setModified(true);
+               return tag;
+       }
+
+}

Propchange: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java?rev=1144611&r1=1144610&r2=1144611&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
 (original)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
 Sat Jul  9 07:24:18 2011
@@ -33,6 +33,7 @@ import org.apache.wicket.ajax.AjaxReques
 import org.apache.wicket.ajax.AjaxRequestTargetListenerCollection;
 import org.apache.wicket.markup.MarkupType;
 import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.form.AutoLabelResolver;
 import org.apache.wicket.markup.html.pages.AccessDeniedPage;
 import org.apache.wicket.markup.html.pages.InternalErrorPage;
 import org.apache.wicket.markup.html.pages.PageExpiredErrorPage;
@@ -535,6 +536,7 @@ public abstract class WebApplication ext
 
                // Add resolver for automatically resolving HTML links
                getPageSettings().addComponentResolver(new AutoLinkResolver());
+               getPageSettings().addComponentResolver(new AutoLabelResolver());
 
                // Set resource finder to web app path
                getResourceSettings().setResourceFinder(getResourceFinder());

Added: 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java?rev=1144611&view=auto
==============================================================================
--- 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
 (added)
+++ 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
 Sat Jul  9 07:24:18 2011
@@ -0,0 +1,206 @@
+/*
+ * 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.wicket.markup.html.form;
+
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.Page;
+import org.apache.wicket.WicketTestCase;
+import org.apache.wicket.markup.IMarkupCacheKeyProvider;
+import org.apache.wicket.markup.IMarkupResourceStreamProvider;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.resource.StringResourceStream;
+
+/**
+ * Tests {@code wicket:for} attribute functionality
+ * 
+ * @author igor
+ */
+public class AutoLabelTest extends WicketTestCase
+{
+       public void testLabelIntoMarkupInsertion()
+       {
+               class MyTestPage extends TestPage
+               {
+                       public MyTestPage(String labelMarkup)
+                       {
+                               super("<label wicket:for='t'>" + labelMarkup + 
"</label>");
+                               field.setLabel(Model.of("t"));
+                       }
+               }
+
+               // simple insertion
+               assertRendered(new MyTestPage("<span class='text'>text</span>"),
+                       "<span class='text'>t</span>");
+
+
+               // preserves markup before and after
+               assertRendered(new MyTestPage(" <div> a </div> <span 
class='text'>text</span> b "),
+                       " <div> a </div> <span class='text'>t</span> b ");
+
+
+               // embedded span tags
+               assertRendered(new MyTestPage(" a <div> b <span 
class='text'>text</span> c </div> d"),
+                       " a <div> b <span class='text'>t</span> c </div> d");
+
+               // double text span tags - only the first one is touched
+               assertRendered(new MyTestPage(
+                       "<span class='text'>text</span><span 
class='text'>text</span>"),
+                       "<span class='text'>t</span><span 
class='text'>text</span>");
+
+               // no span - no insertion
+               assertRendered(new MyTestPage(" text "), " text ");
+
+               // empty label tag
+               assertRendered(new MyTestPage(""), "></label>");
+
+               // empty span tag
+               assertRendered(new MyTestPage("<span class='text'></span>"), 
"<span class='text'>t</span>");
+
+               // open/close span tag
+               assertRendered(new MyTestPage("<span class='text'/>"), "<span 
class='text'>t</span>");
+
+               // test additional classes on the span are preserved
+               assertRendered(new MyTestPage("<span class='foo text bar'/>"),
+                       "<span class='foo text bar'>t</span>");
+       }
+
+       public void testMarkupIntoLabelInsertion()
+       {
+               class MyTestPage extends TestPage
+               {
+                       public MyTestPage(String labelMarkup)
+                       {
+                               super("<label wicket:for='t'>" + labelMarkup + 
"</label>");
+                       }
+               }
+
+               // test form component label is defaulted to the contents of 
span class='text'
+
+               MyTestPage page = new MyTestPage("<span 
class='text'>text</span>");
+               tester.startPage(page);
+               assertEquals("text", 
((MyTestPage)tester.getLastRenderedPage()).field.getLabel()
+                       .getObject());
+       }
+
+       public void testLabelTagClasses()
+       {
+               class MyTestPage extends TestPage
+               {
+                       public MyTestPage()
+                       {
+                               super("<label wicket:for='t'><span 
class='text'>field</span></label>");
+                       }
+               }
+               class MyErrorTestPage extends MyTestPage
+               {
+                       @Override
+                       protected void onConfigure()
+                       {
+                               super.onConfigure();
+                               field.error("too short");
+                       }
+               }
+
+               // test required class
+               TestPage page = new MyTestPage();
+               assertNotRendered(page, "class='required'");
+               page.field.setRequired(true);
+               assertRendered(page, "class='required'");
+
+               // test error class
+               page = new MyTestPage();
+               assertNotRendered(page, "class='error'");
+               page = new MyErrorTestPage();
+               assertRendered(page, "class='error'");
+
+               // test classes are appended and not overridden
+               page = new MyErrorTestPage();
+               page.field.setRequired(true);
+               tester.startPage(page);
+               String markup = tester.getLastResponse().getDocument();
+               assertTrue(markup.contains("class=\"required error\"") ||
+                       markup.contains("class=\"error required\""));
+
+               // test existing classes are preserved
+               class MyTestPage2 extends TestPage
+               {
+                       public MyTestPage2()
+                       {
+                               super("<label class='long' wicket:for='t'><span 
class='text'>field</span></label>");
+                       }
+               }
+
+               MyTestPage2 page2 = new MyTestPage2();
+               page2.field.setRequired(true);
+               tester.startPage(page2);
+               markup = tester.getLastResponse().getDocument();
+               assertTrue(markup.contains("class=\"required long\"") ||
+                       markup.contains("class=\"long required\""));
+
+       }
+
+       private void assertRendered(Page page, String markupFragment)
+       {
+               tester.startPage(page);
+               String markup = tester.getLastResponse().getDocument();
+               markup = markup.replace("'", "\"");
+               assertTrue("fragment: [" + markupFragment + "] not found in 
generated markup: [" + markup +
+                       "]", markup.contains(markupFragment.replace("'", 
"\"")));
+       }
+
+       private void assertNotRendered(Page page, String markupFragment)
+       {
+               tester.startPage(page);
+               String markup = tester.getLastResponse().getDocument();
+               markup = markup.replace("'", "\"");
+               assertFalse("fragment: [" + markupFragment + "] not found in 
generated markup: [" + markup +
+                       "]", markup.contains(markupFragment.replace("'", 
"\"")));
+       }
+
+       private static class TestPage extends WebPage
+               implements
+                       IMarkupResourceStreamProvider,
+                       IMarkupCacheKeyProvider
+       {
+               TextField<String> field;
+
+               private final String labelMarkup;
+
+               public TestPage(String labelMarkup)
+               {
+                       this.labelMarkup = labelMarkup;
+                       Form<?> form = new Form<Void>("f");
+                       add(form);
+                       form.add(field = new TextField<String>("t", 
Model.of("")));
+               }
+
+               public IResourceStream getMarkupResourceStream(MarkupContainer 
container,
+                       Class<?> containerClass)
+               {
+                       return new StringResourceStream("<html><body><form 
wicket:id='f'>\n" + labelMarkup +
+                               "\n<input type='text' 
wicket:id='t'/>\n</form></body></html>");
+               }
+
+               public String getCacheKey(MarkupContainer container, Class<?> 
containerClass)
+               {
+                       // no cache
+                       return null;
+               }
+       }
+}
\ No newline at end of file

Propchange: 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain


Reply via email to