On Tue, Aug 19, 2008 at 4:37 PM, John Hjelmstad <[EMAIL PROTECTED]> wrote:
> Fixed in r687195. I'd ran this suite several times, but in retrospect > shouldn't have assumed that the particular Set in question (2-item Set of > attributes) would happen to be ordered the same across all JVMs. > Let me know if you find any other issues. It's not just across VMs -- having a different number of elements could change the ordering as well, since it's just using a hash table under the covers. > > > Apologies, > --John > > On Tue, Aug 19, 2008 at 4:32 PM, John Hjelmstad <[EMAIL PROTECTED]> wrote: > > > Well that's decidedly not good. Fixing now. > > > > On Tue, Aug 19, 2008 at 4:17 PM, Kevin Brown <[EMAIL PROTECTED]> wrote: > > > >> 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> > <http://www.foo.com/bar.css%5C> > >> <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(); > >> > + } > >> > } > >> > > >> > > >> > > >> > > > > >

