Some of these tests are failing because the internal code is returning sets that don't guarantee ordering, and the tests are assuming that they do.
On Mon, Aug 18, 2008 at 7:27 PM, <[EMAIL PROTECTED]> wrote: > Author: johnh > Date: Mon Aug 18 19:27:54 2008 > New Revision: 686935 > > URL: http://svn.apache.org/viewvc?rev=686935&view=rev > Log: > Adding ability for GadgetHtmlNode to render itself as HTML via > GadgetHtmlNode.render(Writer w). > > > Modified: > > > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java > > > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java > > Modified: > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java > URL: > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java?rev=686935&r1=686934&r2=686935&view=diff > > ============================================================================== > --- > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java > (original) > +++ > incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/parse/GadgetHtmlNode.java > Mon Aug 18 19:27:54 2008 > @@ -17,6 +17,8 @@ > */ > package org.apache.shindig.gadgets.parse; > > +import java.io.IOException; > +import java.io.Writer; > import java.util.ArrayList; > import java.util.Collections; > import java.util.HashMap; > @@ -25,6 +27,8 @@ > import java.util.Map; > import java.util.Set; > > +import org.apache.commons.lang.StringEscapeUtils; > + > /** > * Mutable wrapper around a [EMAIL PROTECTED] ParsedHtmlNode}. > * Used by rewriting to manipulate a parsed gadget DOM, and > @@ -280,6 +284,44 @@ > this.text = text; > } > > + /** > + * Render self as HTML. Rendering is relatively simple as no > + * additional validation is performed on content beyond what > + * the rest of the class provides, such as attribute key > + * validation. All whitespace and comments are maintained. Nodes > + * with zero children are rendered short-form (<foo/>) > + * unless tagName is "style" since many browsers dislike short-form for > that. > + * One space is provided between attributes. Attribute values are > surrounded > + * in double-quotes. Null-valued attributes are rendered without > ="value". > + * Attributes are rendered in no particular order. > + * @param w Writer to which to send content > + * @throws IOException If the writer throws an error on append(...) > + */ > + public void render(Writer w) throws IOException { > + if (isText()) { > + w.append(StringEscapeUtils.escapeHtml(getText())); > + } else { > + w.append('<').append(tagName); > + for (String attrKey : getAttributeKeys()) { > + String attrValue = getAttributeValue(attrKey); > + w.append(' ').append(attrKey); > + if (attrValue != null) { > + > w.append("=\"").append(StringEscapeUtils.escapeHtml(attrValue)).append('"'); > + } > + } > + if (children.size() == 0 && > + !tagName.equalsIgnoreCase("style")) { > + w.append("/>"); > + } else { > + w.append('>'); > + for (GadgetHtmlNode child : children) { > + child.render(w); > + } > + w.append("</").append(tagName).append('>'); > + } > + } > + } > + > // Helper that cleans up and validates an attribute key > private String validateAttributeKey(String key) { > if (key == null) { > > Modified: > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java > URL: > http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java?rev=686935&r1=686934&r2=686935&view=diff > > ============================================================================== > --- > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java > (original) > +++ > incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/parse/GadgetHtmlNodeTest.java > Mon Aug 18 19:27:54 2008 > @@ -24,6 +24,8 @@ > > import junit.framework.TestCase; > > +import java.io.IOException; > +import java.io.StringWriter; > import java.util.LinkedList; > import java.util.List; > import java.util.Set; > @@ -431,4 +433,78 @@ > // Expected condition > } > } > + > + public void testRenderOnlyTextNode() { > + String content = " hello, world!\n "; > + assertEquals(content, renderNode(new GadgetHtmlNode(content))); > + } > + > + public void testRenderOnlyTagNodeShortForm() { > + String[][] attribs = { { "id", "foo" }, { "bar", "baz" } }; > + GadgetHtmlNode tag = new GadgetHtmlNode("div", attribs); > + assertEquals("<div bar=\"baz\" id=\"foo\"/>", renderNode(tag)); > + } > + > + public void testRenderStyleSrcTag() { > + String[][] attribs = { { "src", "http://www.foo.com/bar.css" } }; > + GadgetHtmlNode styleTag = new GadgetHtmlNode("style", attribs); > + assertEquals("<style > src=\"http://www.foo.com/bar.css\<http://www.foo.com/bar.css%5C> > "></style>", > + renderNode(styleTag)); > + } > + > + public void testRenderEscapedAttribute() { > + String[][] attribs = { { "foo", "<script&\"data\">" } }; > + GadgetHtmlNode escapedTag = new GadgetHtmlNode("div", attribs); > + assertEquals("<div foo=\"<script&"data">\"/>", > + renderNode(escapedTag)); > + } > + > + public void testRenderNullValuedAttribute() { > + String[][] attribs = { { "marker", null } }; > + GadgetHtmlNode tag = new GadgetHtmlNode("span", attribs); > + assertEquals("<span marker/>", renderNode(tag)); > + } > + > + public void testRenderEscapedTextContent() { > + GadgetHtmlNode escapedTextNode = new > GadgetHtmlNode("<script&\"data'>"); > + assertEquals("<script&"data'>", > + renderNode(escapedTextNode)); > + } > + > + public void testRenderAdjacentStringsInTag() { > + GadgetHtmlNode container = new GadgetHtmlNode("div", null); > + container.appendChild(new GadgetHtmlNode("one")); > + container.appendChild(new GadgetHtmlNode("\n")); > + container.appendChild(new GadgetHtmlNode(" two ")); > + assertEquals("<div>one\n two </div>", renderNode(container)); > + } > + > + public void testRenderMixedContent() { > + // Something of a catch-all for smaller above tests. > + String[][] attribs = { { "readonly", null } }; > + GadgetHtmlNode parent = new GadgetHtmlNode("div", attribs); > + parent.appendChild(new GadgetHtmlNode(" content\n")); > + parent.appendChild(new GadgetHtmlNode("<br>")); > + GadgetHtmlNode child1 = new GadgetHtmlNode("span", null); > + child1.appendChild(new GadgetHtmlNode("hr", null)); > + parent.appendChild(child1); > + parent.appendChild(new GadgetHtmlNode("\"after text\"")); > + GadgetHtmlNode child2 = new GadgetHtmlNode("p", null); > + child2.appendChild(new GadgetHtmlNode("paragraph!")); > + parent.appendChild(child2); > + assertEquals("<div readonly> content\n<br><span><hr/>" + > + "</span>"after text"<p>paragraph!</p></div>", > + renderNode(parent)); > + } > + > + private String renderNode(GadgetHtmlNode node) { > + StringWriter sw = new StringWriter(); > + try { > + node.render(sw); > + } catch (IOException e) { > + // Should never happen, but fail just in case. > + fail("Unexpected IOException on StringWriter operation"); > + } > + return sw.toString(); > + } > } > > >

