http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java ---------------------------------------------------------------------- diff --git a/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java b/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java new file mode 100644 index 0000000..b7a86dd --- /dev/null +++ b/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java @@ -0,0 +1,1616 @@ +// *************************************************************************************************************************** +// * 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.juneau.html; + +import static org.junit.Assert.*; + +import java.util.*; + +import org.apache.juneau.annotation.*; +import org.junit.*; +import org.junit.runner.*; +import org.junit.runners.*; + +@RunWith(Parameterized.class) +@SuppressWarnings({"javadoc","serial"}) +public class BasicHtmlTest { + + private static final HtmlSerializer + s1 = HtmlSerializer.DEFAULT_SQ, + s2 = HtmlSerializer.DEFAULT_SQ_READABLE; + private static final HtmlParser parser = HtmlParser.DEFAULT; + + @Parameterized.Parameters + public static Collection<Object[]> getParameters() { + return Arrays.asList(new Object[][] { + + { + "SimpleTypes-1", + "foo", + "<string>foo</string>", + "<string>foo</string>", + }, + { + "SimpleTypes-2", + true, + "<boolean>true</boolean>", + "<boolean>true</boolean>", + }, + { + "SimpleTypes-3", + 123, + "<number>123</number>", + "<number>123</number>", + }, + { + "SimpleTypes-4", + 1.23f, + "<number>1.23</number>", + "<number>1.23</number>", + }, + { + "SimpleTypes-5", + null, + "<null/>", + "<null/>", + }, + { + "Arrays-1", + new String[]{"foo"}, + "<ul><li>foo</li></ul>", + "<ul>\n\t<li>foo</li>\n</ul>\n", + }, + { + "Arrays-2", + new String[]{null}, + "<ul><li><null/></li></ul>", + "<ul>\n\t<li><null/></li>\n</ul>\n", + }, + { + "Arrays-3", + new Object[]{"foo",123,true}, + "<ul><li>foo</li><li><number>123</number></li><li><boolean>true</boolean></li></ul>", + "<ul>\n\t<li>foo</li>\n\t<li><number>123</number></li>\n\t<li><boolean>true</boolean></li>\n</ul>\n", + }, + { + "Arrays-4", + new int[]{123}, + "<ul><li>123</li></ul>", + "<ul>\n\t<li>123</li>\n</ul>\n", + }, + { + "Arrays-5", + new boolean[]{true}, + "<ul><li>true</li></ul>", + "<ul>\n\t<li>true</li>\n</ul>\n", + }, + { + "Arrays-6", + new String[][]{{"foo"}}, + "<ul><li><ul><li>foo</li></ul></li></ul>", + "<ul>\n\t<li>\n\t\t<ul>\n\t\t\t<li>foo</li>\n\t\t</ul>\n\t</li>\n</ul>\n", + }, + { + "MapWithStrings", + new MapWithStrings().append("k1", "v1").append("k2", null), + "<table>" + +"<tr>" + +"<td>k1</td>" + +"<td>v1</td>" + +"</tr>" + +"<tr>" + +"<td>k2</td>" + +"<td><null/></td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>k1</td>\n" + +"\t\t<td>v1</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>k2</td>\n" + +"\t\t<td><null/></td>\n" + +"\t</tr>\n" + +"</table>\n", + }, + { + "MapsWithNumbers", + new MapWithNumbers().append("k1", 123).append("k2", 1.23).append("k3", null), + "<table>" + +"<tr>" + +"<td>k1</td>" + +"<td>123</td>" + +"</tr>" + +"<tr>" + +"<td>k2</td>" + +"<td>1.23</td>" + +"</tr>" + +"<tr>" + +"<td>k3</td>" + +"<td><null/></td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>k1</td>\n" + +"\t\t<td>123</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>k2</td>\n" + +"\t\t<td>1.23</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>k3</td>\n" + +"\t\t<td><null/></td>\n" + +"\t</tr>\n" + +"</table>\n", + }, + { + "MapWithObjects", + new MapWithObjects().append("k1", "v1").append("k2", 123).append("k3", 1.23).append("k4", true).append("k5", null), + "<table>" + +"<tr>" + +"<td>k1</td>" + +"<td>v1</td>" + +"</tr>" + +"<tr>" + +"<td>k2</td>" + +"<td><number>123</number></td>" + +"</tr>" + +"<tr>" + +"<td>k3</td>" + +"<td><number>1.23</number></td>" + +"</tr>" + +"<tr>" + +"<td>k4</td>" + +"<td><boolean>true</boolean></td>" + +"</tr>" + +"<tr>" + +"<td>k5</td>" + +"<td><null/></td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>k1</td>\n" + +"\t\t<td>v1</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>k2</td>\n" + +"\t\t<td><number>123</number></td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>k3</td>\n" + +"\t\t<td><number>1.23</number></td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>k4</td>\n" + +"\t\t<td><boolean>true</boolean></td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>k5</td>\n" + +"\t\t<td><null/></td>\n" + +"\t</tr>\n" + +"</table>\n", + }, + { + "ListWithStrings", + new ListWithStrings().append("foo").append(null), + "<ul><li>foo</li><li><null/></li></ul>", + "<ul>\n\t<li>foo</li>\n\t<li><null/></li>\n</ul>\n", + }, + { + "ListWithNumbers", + new ListWithNumbers().append(123).append(1.23).append(null), + "<ul><li>123</li><li>1.23</li><li><null/></li></ul>", + "<ul>\n\t<li>123</li>\n\t<li>1.23</li>\n\t<li><null/></li>\n</ul>\n", + }, + { + "ListWithObjects", + new ListWithObjects().append("foo").append(123).append(1.23).append(true).append(null), + "<ul><li>foo</li><li><number>123</number></li><li><number>1.23</number></li><li><boolean>true</boolean></li><li><null/></li></ul>", + "<ul>\n\t<li>foo</li>\n\t<li><number>123</number></li>\n\t<li><number>1.23</number></li>\n\t<li><boolean>true</boolean></li>\n\t<li><null/></li>\n</ul>\n", + }, + { + "BeanWithNormalProperties", + new BeanWithNormalProperties().init(), + "<table>" + +"<tr>" + +"<td>a</td>" + +"<td>foo</td>" + +"</tr>" + +"<tr>" + +"<td>b</td>" + +"<td>123</td>" + +"</tr>" + +"<tr>" + +"<td>c</td>" + +"<td>bar</td>" + +"</tr>" + +"<tr>" + +"<td>d</td>" + +"<td><number>456</number></td>" + +"</tr>" + +"<tr>" + +"<td>e</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>h</td>" + +"<td>qux</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>f</td>" + +"<td>" + +"<ul>" + +"<li>baz</li>" + +"</ul>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>g</td>" + +"<td>" + +"<ul>" + +"<li>789</li>" + +"</ul>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>a</td>\n" + +"\t\t<td>foo</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b</td>\n" + +"\t\t<td>123</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>c</td>\n" + +"\t\t<td>bar</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>d</td>\n" + +"\t\t<td><number>456</number></td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>e</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>h</td>\n" + +"\t\t\t\t\t<td>qux</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>f</td>\n" + +"\t\t<td>\n" + +"\t\t\t<ul>\n" + +"\t\t\t\t<li>baz</li>\n" + +"\t\t\t</ul>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>g</td>\n" + +"\t\t<td>\n" + +"\t\t\t<ul>\n" + +"\t\t\t\t<li>789</li>\n" + +"\t\t\t</ul>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n", + }, + { + "BeanWithMapProperties", + new BeanWithMapProperties().init(), + "<table>" + +"<tr>" + +"<td>a</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>k1</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>b</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>k2</td>" + +"<td>123</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>c</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>k3</td>" + +"<td>bar</td>" + +"</tr>" + +"<tr>" + +"<td>k4</td>" + +"<td><number>456</number></td>" + +"</tr>" + +"<tr>" + +"<td>k5</td>" + +"<td><boolean>true</boolean></td>" + +"</tr>" + +"<tr>" + +"<td>k6</td>" + +"<td><null/></td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>a</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k1</td>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k2</td>\n" + +"\t\t\t\t\t<td>123</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>c</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k3</td>\n" + +"\t\t\t\t\t<td>bar</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k4</td>\n" + +"\t\t\t\t\t<td><number>456</number></td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k5</td>\n" + +"\t\t\t\t\t<td><boolean>true</boolean></td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k6</td>\n" + +"\t\t\t\t\t<td><null/></td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n" + }, + { + "BeanWithTypeName", + new BeanWithTypeName().init(), + "<table _type='X'>" + +"<tr>" + +"<td>a</td>" + +"<td>123</td>" + +"</tr>" + +"<tr>" + +"<td>b</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>", + "<table _type='X'>\n" + +"\t<tr>\n" + +"\t\t<td>a</td>\n" + +"\t\t<td>123</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b</td>\n" + +"\t\t<td>foo</td>\n" + +"\t</tr>\n" + +"</table>\n", + }, + { + "BeanWithPropertiesWithTypeNames", + new BeanWithPropertiesWithTypeNames().init(), + "<table>" + +"<tr>" + +"<td>b1</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>b</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>b2</td>" + +"<td>" + +"<table _type='B'>" + +"<tr>" + +"<td>b</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>b1</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>b</td>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b2</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='B'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>b</td>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n" + }, + { + "BeanWithPropertiesWithArrayTypeNames", + new BeanWithPropertiesWithArrayTypeNames().init(), + "<table>" + +"<tr>" + +"<td>b1</td>" + +"<td>" + +"<table _type='array'>" + +"<tr>" + +"<th>b</th>" + +"</tr>" + +"<tr>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>b2</td>" + +"<td>" + +"<table _type='B^'>" + +"<tr>" + +"<th>b</th>" + +"</tr>" + +"<tr>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>b3</td>" + +"<td>" + +"<table _type='array'>" + +"<tr>" + +"<th>b</th>" + +"</tr>" + +"<tr _type='B'>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>b1</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='array'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>b</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b2</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='B^'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>b</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b3</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='array'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>b</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr _type='B'>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n", + }, + { + "BeanWithPropertiesWithArrayTypeNames", + new BeanWithPropertiesWith2dArrayTypeNames().init(), + "<table>" + +"<tr>" + +"<td>b1</td>" + +"<td>" + +"<ul>" + +"<li>" + +"<table _type='array'>" + +"<tr>" + +"<th>b</th>" + +"</tr>" + +"<tr>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</li>" + +"</ul>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>b2</td>" + +"<td>" + +"<ul _type='B^^'>" + +"<li>" + +"<table _type='array'>" + +"<tr>" + +"<th>b</th>" + +"</tr>" + +"<tr>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</li>" + +"</ul>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>b3</td>" + +"<td>" + +"<ul>" + +"<li>" + +"<table _type='array'>" + +"<tr>" + +"<th>b</th>" + +"</tr>" + +"<tr _type='B'>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</li>" + +"</ul>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>b1</td>\n" + +"\t\t<td>\n" + +"\t\t\t<ul>\n" + +"\t\t\t\t<li>\n" + +"\t\t\t\t\t<table _type='array'>\n" + +"\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t<th>b</th>\n" + +"\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t</table>\n" + +"\t\t\t\t</li>\n" + +"\t\t\t</ul>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b2</td>\n" + +"\t\t<td>\n" + +"\t\t\t<ul _type='B^^'>\n" + +"\t\t\t\t<li>\n" + +"\t\t\t\t\t<table _type='array'>\n" + +"\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t<th>b</th>\n" + +"\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t</table>\n" + +"\t\t\t\t</li>\n" + +"\t\t\t</ul>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b3</td>\n" + +"\t\t<td>\n" + +"\t\t\t<ul>\n" + +"\t\t\t\t<li>\n" + +"\t\t\t\t\t<table _type='array'>\n" + +"\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t<th>b</th>\n" + +"\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t\t<tr _type='B'>\n" + +"\t\t\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t</table>\n" + +"\t\t\t\t</li>\n" + +"\t\t\t</ul>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n" + }, + { + "BeanWithPropertiesWithMapTypeNames", + new BeanWithPropertiesWithMapTypeNames().init(), + "<table>" + +"<tr>" + +"<td>b1</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>k1</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>b</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>b2</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>k2</td>" + +"<td>" + +"<table _type='B'>" + +"<tr>" + +"<td>b</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>b1</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k1</td>\n" + +"\t\t\t\t\t<td>\n" + +"\t\t\t\t\t\t<table>\n" + +"\t\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t\t<td>b</td>\n" + +"\t\t\t\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t\t</table>\n" + +"\t\t\t\t\t</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b2</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k2</td>\n" + +"\t\t\t\t\t<td>\n" + +"\t\t\t\t\t\t<table _type='B'>\n" + +"\t\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t\t<td>b</td>\n" + +"\t\t\t\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t\t</table>\n" + +"\t\t\t\t\t</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n", + }, + { + "LinkBean-1", + new LinkBean().init(), + "<a href='http://apache.org'>foo</a>", + "<a href='http://apache.org'>foo</a>" + }, + { + "LinkBean-2", + new LinkBean[]{new LinkBean().init(),new LinkBean().init()}, + "<ul><li><a href='http://apache.org'>foo</a></li><li><a href='http://apache.org'>foo</a></li></ul>", + "<ul>\n\t<li><a href='http://apache.org'>foo</a></li>\n\t<li><a href='http://apache.org'>foo</a></li>\n</ul>\n" + }, + { + "ListWithLinkBeans", + new ListWithLinkBeans().append(new LinkBean().init()).append(new LinkBean().init()), + "<ul><li><a href='http://apache.org'>foo</a></li><li><a href='http://apache.org'>foo</a></li></ul>", + "<ul>\n\t<li><a href='http://apache.org'>foo</a></li>\n\t<li><a href='http://apache.org'>foo</a></li>\n</ul>\n" + }, + { + "BeanWithLinkBeanProperties", + new BeanWithLinkBeanProperties().init(), + "<table>" + +"<tr>" + +"<td>a</td>" + +"<td><a href='http://apache.org'>foo</a></td>" + +"</tr>" + +"<tr>" + +"<td>b</td>" + +"<td>" + +"<ul>" + +"<li><a href='http://apache.org'>foo</a></li>" + +"</ul>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>c</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>c1</td>" + +"<td><a href='http://apache.org'>foo</a></td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>a</td>\n" + +"\t\t<td><a href='http://apache.org'>foo</a></td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b</td>\n" + +"\t\t<td>\n" + +"\t\t\t<ul>\n" + +"\t\t\t\t<li><a href='http://apache.org'>foo</a></li>\n" + +"\t\t\t</ul>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>c</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>c1</td>\n" + +"\t\t\t\t\t<td><a href='http://apache.org'>foo</a></td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n" + }, + { + "BeanWithSpecialCharacters", + new BeanWithSpecialCharacters().init(), + "<table><tr><td>a</td><td><br/><bs/><ff/><tb> </tb></td></tr></table>", + "<table>\n\t<tr>\n\t\t<td>a</td>\n\t\t<td><br/><bs/><ff/><tb> </tb></td>\n\t</tr>\n</table>\n" + }, + { + "BeanWithNullProperties", + new BeanWithNullProperties(), + "<table></table>", + "<table>\n</table>\n" + }, + { + "BeanWithAbstractFields", + new BeanWithAbstractFields().init(), + "<table>" + +"<tr>" + +"<td>a</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>a</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>ia</td>" + +"<td>" + +"<table _type='A'>" + +"<tr>" + +"<td>a</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>aa</td>" + +"<td>" + +"<table _type='A'>" + +"<tr>" + +"<td>a</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>o</td>" + +"<td>" + +"<table _type='A'>" + +"<tr>" + +"<td>a</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>a</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>a</td>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>ia</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='A'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>a</td>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>aa</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='A'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>a</td>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>o</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='A'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>a</td>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n" + }, + { + "BeanWithAbstractArrayFields", + new BeanWithAbstractArrayFields().init(), + "<table>" + +"<tr>" + +"<td>a</td>" + +"<td>" + +"<table _type='array'>" + +"<tr>" + +"<th>a</th>" + +"</tr>" + +"<tr>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>ia1</td>" + +"<td>" + +"<table _type='A^'>" + +"<tr>" + +"<th>a</th>" + +"</tr>" + +"<tr>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>ia2</td>" + +"<td>" + +"<table _type='array'>" + +"<tr>" + +"<th>a</th>" + +"</tr>" + +"<tr _type='A'>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>aa1</td>" + +"<td>" + +"<table _type='A^'>" + +"<tr>" + +"<th>a</th>" + +"</tr>" + +"<tr>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>aa2</td>" + +"<td>" + +"<table _type='array'>" + +"<tr>" + +"<th>a</th>" + +"</tr>" + +"<tr _type='A'>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>o1</td>" + +"<td>" + +"<table _type='A^'>" + +"<tr>" + +"<th>a</th>" + +"</tr>" + +"<tr>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>o2</td>" + +"<td>" + +"<table _type='array'>" + +"<tr>" + +"<th>a</th>" + +"</tr>" + +"<tr _type='A'>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>a</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='array'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>a</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>ia1</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='A^'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>a</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>ia2</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='array'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>a</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr _type='A'>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>aa1</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='A^'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>a</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>aa2</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='array'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>a</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr _type='A'>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>o1</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='A^'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>a</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>o2</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table _type='array'>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<th>a</th>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t\t<tr _type='A'>\n" + +"\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n", + }, + { + "BeanWithAbstractMapFields", + new BeanWithAbstractMapFields().init(), + "<table>" + +"<tr>" + +"<td>a</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>k1</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>a</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>b</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>k2</td>" + +"<td>" + +"<table _type='A'>" + +"<tr>" + +"<td>a</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>c</td>" + +"<td>" + +"<table>" + +"<tr>" + +"<td>k3</td>" + +"<td>" + +"<table _type='A'>" + +"<tr>" + +"<td>a</td>" + +"<td>foo</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + "<table>\n" + +"\t<tr>\n" + +"\t\t<td>a</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k1</td>\n" + +"\t\t\t\t\t<td>\n" + +"\t\t\t\t\t\t<table>\n" + +"\t\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t\t<td>a</td>\n" + +"\t\t\t\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t\t</table>\n" + +"\t\t\t\t\t</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>b</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k2</td>\n" + +"\t\t\t\t\t<td>\n" + +"\t\t\t\t\t\t<table _type='A'>\n" + +"\t\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t\t<td>a</td>\n" + +"\t\t\t\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t\t</table>\n" + +"\t\t\t\t\t</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"\t<tr>\n" + +"\t\t<td>c</td>\n" + +"\t\t<td>\n" + +"\t\t\t<table>\n" + +"\t\t\t\t<tr>\n" + +"\t\t\t\t\t<td>k3</td>\n" + +"\t\t\t\t\t<td>\n" + +"\t\t\t\t\t\t<table _type='A'>\n" + +"\t\t\t\t\t\t\t<tr>\n" + +"\t\t\t\t\t\t\t\t<td>a</td>\n" + +"\t\t\t\t\t\t\t\t<td>foo</td>\n" + +"\t\t\t\t\t\t\t</tr>\n" + +"\t\t\t\t\t\t</table>\n" + +"\t\t\t\t\t</td>\n" + +"\t\t\t\t</tr>\n" + +"\t\t\t</table>\n" + +"\t\t</td>\n" + +"\t</tr>\n" + +"</table>\n" + } + }); + } + + private String label, e1, e2; + private Object in; + + public BasicHtmlTest(String label, Object in, String e1, String e2) throws Exception { + this.label = label; + this.in = in; + this.e1 = e1; + this.e2 = e2; + } + + @Test + public void serializeNormal() { + try { + String r = s1.serialize(in); + assertEquals(label + " serialize-normal failed", e1, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + @Test + public void parseNormal() { + try { + String r = s1.serialize(in); + Class<?> c = in == null ? Object.class : in.getClass(); + Object o = parser.parse(r, c); + r = s1.serialize(o); + assertEquals(label + " parse-normal failed", e1, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + @Test + public void serializeReadable() { + try { + String r = s2.serialize(in); + assertEquals(label + " serialize-readable failed", e2, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + @Test + public void parseReadable() { + try { + String r = s2.serialize(in); + Class<?> c = in == null ? Object.class : in.getClass(); + Object o = parser.parse(r, c); + r = s2.serialize(o); + assertEquals(label + " parse-readable failed", e2, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + + //-------------------------------------------------------------------------------- + // Test beans + //-------------------------------------------------------------------------------- + + public static class MapWithStrings extends LinkedHashMap<String,String> { + public MapWithStrings append(String key, String value) { + put(key, value); + return this; + } + } + + public static class MapWithNumbers extends LinkedHashMap<String,Number> { + public MapWithNumbers append(String key, Number value) { + put(key, value); + return this; + } + } + + public static class MapWithObjects extends LinkedHashMap<String,Object> { + public MapWithObjects append(String key, Object value) { + put(key, value); + return this; + } + } + + public static class ListWithStrings extends ArrayList<String> { + public ListWithStrings append(String value) { + this.add(value); + return this; + } + } + + public static class ListWithNumbers extends ArrayList<Number> { + public ListWithNumbers append(Number value) { + this.add(value); + return this; + } + } + + public static class ListWithObjects extends ArrayList<Object> { + public ListWithObjects append(Object value) { + this.add(value); + return this; + } + } + + public static class BeanWithNormalProperties { + public String a; + public int b; + public Object c; + public Object d; + public Bean1a e; + public String[] f; + public int[] g; + + BeanWithNormalProperties init() { + a = "foo"; + b = 123; + c = "bar"; + d = 456; + e = new Bean1a().init(); + f = new String[]{ "baz" }; + g = new int[]{ 789 }; + return this; + } + } + + public static class Bean1a { + public String h; + + Bean1a init() { + h = "qux"; + return this; + } + } + + public static class BeanWithMapProperties { + @BeanProperty(type=MapWithStrings.class) + public Map<String,String> a; + @BeanProperty(type=MapWithNumbers.class) + public Map<String,Number> b; + @BeanProperty(type=MapWithObjects.class) + public Map<String,Object> c; + + BeanWithMapProperties init() { + a = new MapWithStrings().append("k1","foo"); + b = new MapWithNumbers().append("k2",123); + c = new MapWithObjects().append("k3","bar").append("k4",456).append("k5",true).append("k6",null); + return this; + } + } + + @Bean(typeName="X") + public static class BeanWithTypeName { + public int a; + public String b; + + BeanWithTypeName init() { + a = 123; + b = "foo"; + return this; + } + } + + @Bean(beanDictionary={B.class}) + public static class BeanWithPropertiesWithTypeNames { + public B b1; + public Object b2; + + BeanWithPropertiesWithTypeNames init() { + b1 = new B().init(); + b2 = new B().init(); + return this; + } + } + + @Bean(beanDictionary={B.class}) + public static class BeanWithPropertiesWithArrayTypeNames { + public B[] b1; + public Object[] b2; + public Object[] b3; + + BeanWithPropertiesWithArrayTypeNames init() { + b1 = new B[]{new B().init()}; + b2 = new B[]{new B().init()}; + b3 = new Object[]{new B().init()}; + return this; + } + } + + @Bean(beanDictionary={B.class}) + public static class BeanWithPropertiesWith2dArrayTypeNames { + public B[][] b1; + public Object[][] b2; + public Object[][] b3; + + BeanWithPropertiesWith2dArrayTypeNames init() { + b1 = new B[][]{{new B().init()}}; + b2 = new B[][]{{new B().init()}}; + b3 = new Object[][]{{new B().init()}}; + return this; + } + } + + @Bean(beanDictionary={B.class}) + public static class BeanWithPropertiesWithMapTypeNames { + public Map<String,B> b1; + public Map<String,Object> b2; + + BeanWithPropertiesWithMapTypeNames init() { + b1 = new HashMap<String,B>(); + b1.put("k1", new B().init()); + b2 = new HashMap<String,Object>(); + b2.put("k2", new B().init()); + return this; + } + } + + @Bean(typeName="B") + public static class B { + public String b; + + B init() { + b = "foo"; + return this; + } + } + + @HtmlLink(nameProperty="a",hrefProperty="b") + public static class LinkBean { + public String a; + public String b; + + LinkBean init() { + a = "foo"; + b = "http://apache.org"; + return this; + } + } + + public static class ListWithLinkBeans extends ArrayList<LinkBean> { + public ListWithLinkBeans append(LinkBean value) { + this.add(value); + return this; + } + } + + public static class BeanWithLinkBeanProperties { + public LinkBean a; + public List<LinkBean> b; + public Map<String,LinkBean> c; + + BeanWithLinkBeanProperties init() { + a = new LinkBean().init(); + b = new ListWithLinkBeans().append(new LinkBean().init()); + c = new LinkedHashMap<String,LinkBean>(); + c.put("c1", new LinkBean().init()); + return this; + } + } + + public static class BeanWithSpecialCharacters { + public String a; + + BeanWithSpecialCharacters init() { + a = "\n\b\f\t"; + return this; + } + } + + public static class BeanWithNullProperties { + public String a; + public String[] b; + } + + @Bean(beanDictionary={A.class}) + public static class BeanWithAbstractFields { + public A a; + public IA ia; + public AA aa; + public Object o; + + BeanWithAbstractFields init() { + ia = new A().init(); + aa = new A().init(); + a = new A().init(); + o = new A().init(); + return this; + } + } + + @Bean(beanDictionary={A.class}) + public static class BeanWithAbstractArrayFields { + public A[] a; + public IA[] ia1, ia2; + public AA[] aa1, aa2; + public Object[] o1, o2; + + BeanWithAbstractArrayFields init() { + a = new A[]{new A().init()}; + ia1 = new A[]{new A().init()}; + aa1 = new A[]{new A().init()}; + o1 = new A[]{new A().init()}; + ia2 = new IA[]{new A().init()}; + aa2 = new AA[]{new A().init()}; + o2 = new Object[]{new A().init()}; + return this; + } + } + + @Bean(beanDictionary={A.class}) + public static class BeanWithAbstractMapFields { + public Map<String,A> a; + public Map<String,AA> b; + public Map<String,Object> c; + + BeanWithAbstractMapFields init() { + a = new HashMap<String,A>(); + b = new HashMap<String,AA>(); + c = new HashMap<String,Object>(); + a.put("k1", new A().init()); + b.put("k2", new A().init()); + c.put("k3", new A().init()); + return this; + } + } + + public static interface IA { + public String getA(); + public void setA(String a); + } + + public static abstract class AA implements IA {} + + @Bean(typeName="A") + public static class A extends AA { + private String a; + + @Override + public String getA() { + return a; + } + + @Override + public void setA(String a) { + this.a = a; + } + + A init() { + this.a = "foo"; + return this; + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java ---------------------------------------------------------------------- diff --git a/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java new file mode 100755 index 0000000..abc948f --- /dev/null +++ b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java @@ -0,0 +1,164 @@ +// *************************************************************************************************************************** +// * 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.juneau.html; + +import static org.apache.juneau.BeanContext.*; +import static org.apache.juneau.serializer.SerializerContext.*; +import static org.junit.Assert.*; + +import java.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.annotation.*; +import org.apache.juneau.parser.*; +import org.junit.*; + +@SuppressWarnings({"rawtypes","serial","javadoc"}) +public class CommonParserTest { + + //==================================================================================================== + // testFromSerializer + //==================================================================================================== + @Test + public void testFromSerializer() throws Exception { + ReaderParser p = HtmlParser.DEFAULT.clone().setClassLoader(getClass().getClassLoader()).addToDictionary(A1.class); + Map m = null; + String in; + + in = "<table _type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>a</string></td><td><number>1</number></td></tr></table>"; + m = (Map)p.parse(in, Object.class); + assertEquals(1, m.get("a")); + + in = "<table _type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>a</string></td><td><number>1</number></td></tr><tr><td><string>b</string></td><td><string>foo bar</string></td></tr></table>"; + m = (Map)p.parse(in, Object.class); + assertEquals(1, m.get("a")); + assertEquals("foo bar", m.get("b")); + + in = "<table _type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>a</string></td><td><number>1</number></td></tr><tr><td><string>b</string></td><td><string>foo bar</string></td></tr><tr><td><string>c</string></td><td><boolean>false</boolean></td></tr></table>"; + m = (Map)p.parse(in, Object.class); + assertEquals(1, m.get("a")); + assertEquals(false, m.get("c")); + + in = " <table _type='object'> <tr> <th> <string> key </string> </th> <th> <string> value </string> </th> </tr> <tr> <td> <string> a </string> </td> <td> <number> 1 </number> </td> </tr> <tr> <td> <string> b </string> </td> <td> <string> foo </string> </td> </tr> <tr> <td> <string> c </string> </td> <td> <boolean> false </boolean> </td> </tr> </table> "; + m = (Map)p.parse(in, Object.class); + assertEquals(1, m.get("a")); + assertEquals("foo", m.get("b")); + assertEquals(false, m.get("c")); + + in = "<table _type='array'><tr><th>attribute</th></tr><tr><td><string>value</string></td></tr><tr><td><string>value</string></td></tr></table>"; + ObjectList jl = (ObjectList)p.parse(in, Object.class); + assertEquals("value", jl.getObjectMap(0).getString("attribute")); + assertEquals("value", jl.getObjectMap(1).getString("attribute")); + + A1 t1 = new A1(); + A2 t2 = new A2(); + t2.add(new A3("name0","value0")); + t2.add(new A3("name1","value1")); + t1.list = t2; + in = new HtmlSerializer().setProperty(SERIALIZER_addBeanTypeProperties, true).serialize(t1); + t1 = (A1)p.parse(in, Object.class); + assertEquals("value1", t1.list.get(1).value); + + in = HtmlSerializer.DEFAULT.serialize(t1); + t1 = p.parse(in, A1.class); + assertEquals("value1", t1.list.get(1).value); + } + + @Bean(typeName="A1") + public static class A1 { + public A2 list; + } + + public static class A2 extends LinkedList<A3> { + } + + public static class A3 { + public String name, value; + public A3(){} + public A3(String name, String value) { + this.name = name; + this.value = value; + } + } + + //==================================================================================================== + // Correct handling of unknown properties. + //==================================================================================================== + @Test + public void testCorrectHandlingOfUnknownProperties() throws Exception { + ReaderParser p = new HtmlParser().setProperty(BEAN_ignoreUnknownBeanProperties, true); + B t; + + String in = "<table _type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>a</string></td><td><number>1</number></td></tr><tr><td><string>unknown</string></td><td><number>1</number></td></tr><tr><td><string>b</string></td><td><number>2</number></td></tr></table>"; + t = p.parse(in, B.class); + assertEquals(t.a, 1); + assertEquals(t.b, 2); + + try { + p = new HtmlParser(); + p.parse(in, B.class); + fail("Exception expected"); + } catch (ParseException e) {} + } + + public static class B { + public int a, b; + } + + //==================================================================================================== + // Writing to Collection properties with no setters. + //==================================================================================================== + @Test + public void testCollectionPropertiesWithNoSetters() throws Exception { + ReaderParser p = HtmlParser.DEFAULT; + + String in = "<table _type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>ints</string></td><td><ul><li><number>1</number></li><li><number>2</number></li><li><number>3</number></li></ul></td></tr><tr><td><string>beans</string></td><td><table _type='array'><tr><th>a</th><th>b</th></tr><tr><td><number>1</number></td><td><number>2</number></td></tr></table></td></tr></table>"; + C t = p.parse(in, C.class); + assertEquals(t.getInts().size(), 3); + assertEquals(t.getBeans().get(0).b, 2); + } + + public static class C { + private Collection<Integer> ints = new LinkedList<Integer>(); + private List<B> beans = new LinkedList<B>(); + public Collection<Integer> getInts() { + return ints; + } + public List<B> getBeans() { + return beans; + } + } + + //==================================================================================================== + // Parser listeners. + //==================================================================================================== + @Test + public void testParserListeners() throws Exception { + final List<String> events = new LinkedList<String>(); + HtmlParser p = new HtmlParser().setProperty(BEAN_ignoreUnknownBeanProperties, true); + p.addListener( + new ParserListener() { + @Override /* ParserListener */ + public <T> void onUnknownProperty(String propertyName, Class<T> beanClass, T bean, int line, int col) { + events.add(propertyName + "," + line + "," + col); + } + } + ); + + String in = "<table _type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>a</string></td><td><number>1</number></td></tr><tr><td><string>unknown</string></td><td><string>/foo</string></td></tr><tr><td><string>b</string></td><td><number>2</number></td></tr></table>"; + p.parse(in, B.class); + assertEquals(1, events.size()); + assertEquals("unknown,-1,-1", events.get(0)); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/html/CommonTest.java ---------------------------------------------------------------------- diff --git a/juneau-core-test/src/test/java/org/apache/juneau/html/CommonTest.java b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonTest.java new file mode 100755 index 0000000..e5f316d --- /dev/null +++ b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonTest.java @@ -0,0 +1,675 @@ +// *************************************************************************************************************************** +// * 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.juneau.html; + +import static org.apache.juneau.BeanContext.*; +import static org.apache.juneau.TestUtils.*; +import static org.apache.juneau.html.HtmlSerializerContext.*; +import static org.junit.Assert.*; + +import java.net.*; +import java.net.URI; +import java.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.annotation.*; +import org.apache.juneau.serializer.*; +import org.apache.juneau.testbeans.*; +import org.apache.juneau.xml.*; +import org.junit.*; + +@SuppressWarnings({"serial","javadoc"}) +public class CommonTest { + + //==================================================================================================== + // Trim nulls from beans + //==================================================================================================== + @Test + public void testTrimNullsFromBeans() throws Exception { + HtmlSerializer s = new HtmlSerializer.Sq().setProperty(HTML_addKeyValueTableHeaders, true); + HtmlParser p = HtmlParser.DEFAULT; + A t1 = A.create(), t2; + + s.setProperty(SERIALIZER_trimNullProperties, false); + String r = s.serialize(t1); + assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>s1</td><td><null/></td></tr><tr><td>s2</td><td>s2</td></tr></table>", r); + t2 = p.parse(r, A.class); + assertEqualObjects(t1, t2); + + s.setProperty(SERIALIZER_trimNullProperties, true); + r = s.serialize(t1); + assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>s2</td><td>s2</td></tr></table>", r); + t2 = p.parse(r, A.class); + assertEqualObjects(t1, t2); + } + + public static class A { + public String s1, s2; + + public static A create() { + A t = new A(); + t.s2 = "s2"; + return t; + } + } + + //==================================================================================================== + // Trim empty maps + //==================================================================================================== + @Test + public void testTrimEmptyMaps() throws Exception { + HtmlSerializer s = new HtmlSerializer.Sq().setProperty(HTML_addKeyValueTableHeaders, true); + HtmlParser p = HtmlParser.DEFAULT; + B t1 = B.create(), t2; + String r; + + s.setProperty(SERIALIZER_trimEmptyMaps, false); + r = s.serialize(t1); + assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><table><tr><th>key</th><th>value</th></tr></table></td></tr><tr><td>f2</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>f2a</td><td><null/></td></tr><tr><td>f2b</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>s2</td><td>s2</td></tr></table></td></tr></table></td></tr></table>", r); + t2 = p.parse(r, B.class); + assertEqualObjects(t1, t2); + + s.setProperty(SERIALIZER_trimEmptyMaps, true); + r = s.serialize(t1); + assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f2</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>f2a</td><td><null/></td></tr><tr><td>f2b</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>s2</td><td>s2</td></tr></table></td></tr></table></td></tr></table>", r); + t2 = p.parse(r, B.class); + assertNull(t2.f1); + } + + public static class B { + public TreeMap<String,A> f1, f2; + + public static B create() { + B t = new B(); + t.f1 = new TreeMap<String,A>(); + t.f2 = new TreeMap<String,A>(){{put("f2a",null);put("f2b",A.create());}}; + return t; + } + } + + //==================================================================================================== + // Trim empty lists + //==================================================================================================== + @Test + public void testTrimEmptyLists() throws Exception { + HtmlSerializer s = new HtmlSerializer.Sq().setProperty(HTML_addKeyValueTableHeaders, true); + HtmlParser p = HtmlParser.DEFAULT; + C t1 = C.create(), t2; + String r; + + s.setProperty(SERIALIZER_trimEmptyCollections, false); + r = s.serialize(t1); + assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><ul></ul></td></tr><tr><td>f2</td><td><table _type='array'><tr><th>s2</th></tr><tr><null/></tr><tr><td>s2</td></tr></table></td></tr></table>", r); + t2 = p.parse(r, C.class); + assertEqualObjects(t1, t2); + + s.setProperty(SERIALIZER_trimEmptyCollections, true); + r = s.serialize(t1); + assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f2</td><td><table _type='array'><tr><th>s2</th></tr><tr><null/></tr><tr><td>s2</td></tr></table></td></tr></table>", r); + t2 = p.parse(r, C.class); + assertNull(t2.f1); + } + + public static class C { + public List<A> f1, f2; + + public static C create() { + C t = new C(); + t.f1 = new LinkedList<A>(); + t.f2 = new LinkedList<A>(){{add(null);add(A.create());}}; + return t; + } + } + + //==================================================================================================== + // Trim empty arrays + //==================================================================================================== + @Test + public void testTrimEmptyArrays() throws Exception { + HtmlSerializer s = new HtmlSerializer.Sq().setProperty(HTML_addKeyValueTableHeaders, true); + HtmlParser p = HtmlParser.DEFAULT; + D t1 = D.create(), t2; + String r; + + s.setProperty(SERIALIZER_trimEmptyCollections, false); + r = s.serialize(t1); + assertEquals( + "<table>" + +"<tr><th>key</th><th>value</th></tr>" + +"<tr>" + +"<td>f1</td>" + +"<td><ul></ul></td>" + +"</tr>" + +"<tr>" + +"<td>f2</td>" + +"<td>" + +"<table _type='array'>" + +"<tr><th>s2</th></tr>" + +"<tr><null/></tr>" + +"<tr><td>s2</td></tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + r); + t2 = p.parse(r, D.class); + assertEqualObjects(t1, t2); + + s.setProperty(SERIALIZER_trimEmptyCollections, true); + r = s.serialize(t1); + assertEquals( + "<table>" + +"<tr><th>key</th><th>value</th></tr>" + +"<tr>" + +"<td>f2</td>" + +"<td>" + +"<table _type='array'>" + +"<tr><th>s2</th></tr>" + +"<tr><null/></tr>" + +"<tr><td>s2</td></tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + r); + t2 = p.parse(r, D.class); + assertNull(t2.f1); + } + + public static class D { + public A[] f1, f2; + + public static D create() { + D t = new D(); + t.f1 = new A[]{}; + t.f2 = new A[]{null, A.create()}; + return t; + } + } + + //==================================================================================================== + // @BeanProperty.properties annotation. + //==================================================================================================== + @Test + public void testBeanPropertyProperties() throws Exception { + HtmlSerializer s = HtmlSerializer.DEFAULT_SQ.clone().setProperty(HTML_addKeyValueTableHeaders, true); + E1 t = new E1(); + String r; + + r = s.serialize(t); + assertEquals( + "<table>" + +"<tr>" + +"<th>key</th>" + +"<th>value</th>" + +"</tr>" + +"<tr>" + +"<td>x1</td>" + +"<td>" + +"<table>" + +"<tr><th>key</th><th>value</th></tr>" + +"<tr><td>f1</td><td>1</td></tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>x2</td>" + +"<td>" + +"<table>" + +"<tr><th>key</th><th>value</th></tr>" + +"<tr><td>f1</td><td>3</td></tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>x3</td>" + +"<td>" + +"<table _type='array'>" + +"<tr><th>f1</th></tr>" + +"<tr><td>1</td></tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>x4</td>" + +"<td>" + +"<table _type='array'>" + +"<tr><th>f1</th></tr>" + +"<tr><td>1</td></tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>x5</td>" + +"<td>" + +"<table _type='array'>" + +"<tr><th>f1</th></tr>" + +"<tr><td><number>5</number></td></tr>" + +"</table>" + +"</td>" + +"</tr>" + +"<tr>" + +"<td>x6</td>" + +"<td>" + +"<table _type='array'>" + +"<tr><th>f1</th></tr>" + +"<tr><td><number>7</number></td></tr>" + +"</table>" + +"</td>" + +"</tr>" + +"</table>", + r); + r = s.getSchemaSerializer().serialize(new E1()); + assertTrue(r.indexOf("f2") == -1); + } + + public static class E1 { + @BeanProperty(properties="f1") public E2 x1 = new E2(); + @BeanProperty(properties="f1") public Map<String,Integer> x2 = new LinkedHashMap<String,Integer>() {{ + put("f1",3); put("f2",4); + }}; + @BeanProperty(properties="f1") public E2[] x3 = {new E2()}; + @BeanProperty(properties="f1") public List<E2> x4 = new LinkedList<E2>() {{ + add(new E2()); + }}; + @BeanProperty(properties="f1") public ObjectMap[] x5 = {new ObjectMap().append("f1",5).append("f2",6)}; + @BeanProperty(properties="f1") public List<ObjectMap> x6 = new LinkedList<ObjectMap>() {{ + add(new ObjectMap().append("f1",7).append("f2",8)); + }}; + } + + public static class E2 { + public int f1 = 1; + public int f2 = 2; + } + + //==================================================================================================== + // @BeanProperty.properties annotation on list of beans. + //==================================================================================================== + @Test + public void testBeanPropertyPropertiesOnListOfBeans() throws Exception { + HtmlSerializer s = HtmlSerializer.DEFAULT_SQ; + List<F> l = new LinkedList<F>(); + F t = new F(); + t.x1.add(new F()); + l.add(t); + String html = s.serialize(l); + assertEquals( + "<table _type='array'>" + +"<tr><th>x1</th><th>x2</th></tr>" + +"<tr>" + +"<td>" + +"<table _type='array'>" + +"<tr><th>x2</th></tr>" + +"<tr><td>2</td></tr>" + +"</table>" + +"</td>" + +"<td>2</td>" + +"</tr>" + +"</table>", html); + } + + public static class F { + @BeanProperty(properties="x2") public List<F> x1 = new LinkedList<F>(); + public int x2 = 2; + } + + //==================================================================================================== + // Test that URLs and URIs are serialized and parsed correctly. + //==================================================================================================== + @Test + public void testURIAttr() throws Exception { + HtmlSerializer s = HtmlSerializer.DEFAULT_SQ; + HtmlParser p = HtmlParser.DEFAULT; + + G t = new G(); + t.uri = new URI("http://uri"); + t.f1 = new URI("http://f1"); + t.f2 = new URL("http://f2"); + + String html = s.serialize(t); + t = p.parse(html, G.class); + assertEquals("http://uri", t.uri.toString()); + assertEquals("http://f1", t.f1.toString()); + assertEquals("http://f2", t.f2.toString()); + } + + public static class G { + public URI uri; + public URI f1; + public URL f2; + } + + //==================================================================================================== + // Test URIs with URI_CONTEXT and URI_AUTHORITY + //==================================================================================================== + @Test + public void testUris() throws Exception { + HtmlSerializer s = new HtmlSerializer.Sq().setProperty(HTML_uriAnchorText, PROPERTY_NAME).setProperty(SERIALIZER_useIndentation, false).setProperty(HTML_addKeyValueTableHeaders, true); + TestURI t = new TestURI(); + String r; + String expected; + + s.setProperty(SERIALIZER_relativeUriBase, null); + r = strip(s.serialize(t)); + expected = "" + +"\n[f0]=<a href='f0/x0'>f0</a>" + +"\n[f1]=<a href='f1/x1'>f1</a>" + +"\n[f2]=<a href='/f2/x2'>f2</a>" + +"\n[f3]=<a href='http://www.apache.org/f3/x3'>f3</a>" + +"\n[f4]=<a href='f4/x4'>f4</a>" + +"\n[f5]=<a href='/f5/x5'>f5</a>" + +"\n[f6]=<a href='http://www.apache.org/f6/x6'>f6</a>" + +"\n[f7]=<a href='http://www.apache.org/f7/x7'>f7</a>" + +"\n[f8]=<a href='f8/x8'>f8</a>" + +"\n[f9]=<a href='f9/x9'>f9</a>" + +"\n[fa]=<a href='http://www.apache.org/fa/xa#MY_LABEL'>fa</a>" + +"\n[fb]=<a href='http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar'>MY_LABEL</a>" + +"\n[fc]=<a href='http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL'>MY_LABEL</a>" + +"\n[fd]=<a href='http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar'>fd</a>" + +"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>fe</a>" + ; + assertEquals(expected, r); + + s.setProperty(SERIALIZER_relativeUriBase, ""); // Same as null. + r = strip(s.serialize(t)); + expected = "" + +"\n[f0]=<a href='f0/x0'>f0</a>" + +"\n[f1]=<a href='f1/x1'>f1</a>" + +"\n[f2]=<a href='/f2/x2'>f2</a>" + +"\n[f3]=<a href='http://www.apache.org/f3/x3'>f3</a>" + +"\n[f4]=<a href='f4/x4'>f4</a>" + +"\n[f5]=<a href='/f5/x5'>f5</a>" + +"\n[f6]=<a href='http://www.apache.org/f6/x6'>f6</a>" + +"\n[f7]=<a href='http://www.apache.org/f7/x7'>f7</a>" + +"\n[f8]=<a href='f8/x8'>f8</a>" + +"\n[f9]=<a href='f9/x9'>f9</a>" + +"\n[fa]=<a href='http://www.apache.org/fa/xa#MY_LABEL'>fa</a>" + +"\n[fb]=<a href='http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar'>MY_LABEL</a>" + +"\n[fc]=<a href='http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL'>MY_LABEL</a>" + +"\n[fd]=<a href='http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar'>fd</a>" + +"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>fe</a>" + ; + assertEquals(expected, r); + + s.setProperty(SERIALIZER_relativeUriBase, "/cr"); + r = strip(s.serialize(t)); + expected = "" + +"\n[f0]=<a href='/cr/f0/x0'>f0</a>" + +"\n[f1]=<a href='/cr/f1/x1'>f1</a>" + +"\n[f2]=<a href='/f2/x2'>f2</a>" + +"\n[f3]=<a href='http://www.apache.org/f3/x3'>f3</a>" + +"\n[f4]=<a href='/cr/f4/x4'>f4</a>" + +"\n[f5]=<a href='/f5/x5'>f5</a>" + +"\n[f6]=<a href='http://www.apache.org/f6/x6'>f6</a>" + +"\n[f7]=<a href='http://www.apache.org/f7/x7'>f7</a>" + +"\n[f8]=<a href='/cr/f8/x8'>f8</a>" + +"\n[f9]=<a href='/cr/f9/x9'>f9</a>" + +"\n[fa]=<a href='http://www.apache.org/fa/xa#MY_LABEL'>fa</a>" + +"\n[fb]=<a href='http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar'>MY_LABEL</a>" + +"\n[fc]=<a href='http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL'>MY_LABEL</a>" + +"\n[fd]=<a href='http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar'>fd</a>" + +"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>fe</a>" + ; + assertEquals(expected, r); + + s.setProperty(SERIALIZER_relativeUriBase, "/cr/"); // Same as above + r = strip(s.serialize(t)); + expected = "" + +"\n[f0]=<a href='/cr/f0/x0'>f0</a>" + +"\n[f1]=<a href='/cr/f1/x1'>f1</a>" + +"\n[f2]=<a href='/f2/x2'>f2</a>" + +"\n[f3]=<a href='http://www.apache.org/f3/x3'>f3</a>" + +"\n[f4]=<a href='/cr/f4/x4'>f4</a>" + +"\n[f5]=<a href='/f5/x5'>f5</a>" + +"\n[f6]=<a href='http://www.apache.org/f6/x6'>f6</a>" + +"\n[f7]=<a href='http://www.apache.org/f7/x7'>f7</a>" + +"\n[f8]=<a href='/cr/f8/x8'>f8</a>" + +"\n[f9]=<a href='/cr/f9/x9'>f9</a>" + +"\n[fa]=<a href='http://www.apache.org/fa/xa#MY_LABEL'>fa</a>" + +"\n[fb]=<a href='http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar'>MY_LABEL</a>" + +"\n[fc]=<a href='http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL'>MY_LABEL</a>" + +"\n[fd]=<a href='http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar'>fd</a>" + +"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>fe</a>" + ; + assertEquals(expected, r); + + s.setProperty(SERIALIZER_relativeUriBase, "/"); + r = strip(s.serialize(t)); + expected = "" + +"\n[f0]=<a href='/f0/x0'>f0</a>" + +"\n[f1]=<a href='/f1/x1'>f1</a>" + +"\n[f2]=<a href='/f2/x2'>f2</a>" + +"\n[f3]=<a href='http://www.apache.org/f3/x3'>f3</a>" + +"\n[f4]=<a href='/f4/x4'>f4</a>" + +"\n[f5]=<a href='/f5/x5'>f5</a>" + +"\n[f6]=<a href='http://www.apache.org/f6/x6'>f6</a>" + +"\n[f7]=<a href='http://www.apache.org/f7/x7'>f7</a>" + +"\n[f8]=<a href='/f8/x8'>f8</a>" + +"\n[f9]=<a href='/f9/x9'>f9</a>" + +"\n[fa]=<a href='http://www.apache.org/fa/xa#MY_LABEL'>fa</a>" + +"\n[fb]=<a href='http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar'>MY_LABEL</a>" + +"\n[fc]=<a href='http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL'>MY_LABEL</a>" + +"\n[fd]=<a href='http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar'>fd</a>" + +"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>fe</a>" + ; + assertEquals(expected, r); + + s.setProperty(SERIALIZER_relativeUriBase, null); + + s.setProperty(SERIALIZER_absolutePathUriBase, "http://foo"); + r = strip(s.serialize(t)); + expected = "" + +"\n[f0]=<a href='f0/x0'>f0</a>" + +"\n[f1]=<a href='f1/x1'>f1</a>" + +"\n[f2]=<a href='http://foo/f2/x2'>f2</a>" + +"\n[f3]=<a href='http://www.apache.org/f3/x3'>f3</a>" + +"\n[f4]=<a href='f4/x4'>f4</a>" + +"\n[f5]=<a href='http://foo/f5/x5'>f5</a>" + +"\n[f6]=<a href='http://www.apache.org/f6/x6'>f6</a>" + +"\n[f7]=<a href='http://www.apache.org/f7/x7'>f7</a>" + +"\n[f8]=<a href='f8/x8'>f8</a>" + +"\n[f9]=<a href='f9/x9'>f9</a>" + +"\n[fa]=<a href='http://www.apache.org/fa/xa#MY_LABEL'>fa</a>" + +"\n[fb]=<a href='http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar'>MY_LABEL</a>" + +"\n[fc]=<a href='http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL'>MY_LABEL</a>" + +"\n[fd]=<a href='http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar'>fd</a>" + +"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>fe</a>" + ; + assertEquals(expected, r); + + s.setProperty(SERIALIZER_absolutePathUriBase, "http://foo/"); + r = strip(s.serialize(t)); + expected = "" + +"\n[f0]=<a href='f0/x0'>f0</a>" + +"\n[f1]=<a href='f1/x1'>f1</a>" + +"\n[f2]=<a href='http://foo/f2/x2'>f2</a>" + +"\n[f3]=<a href='http://www.apache.org/f3/x3'>f3</a>" + +"\n[f4]=<a href='f4/x4'>f4</a>" + +"\n[f5]=<a href='http://foo/f5/x5'>f5</a>" + +"\n[f6]=<a href='http://www.apache.org/f6/x6'>f6</a>" + +"\n[f7]=<a href='http://www.apache.org/f7/x7'>f7</a>" + +"\n[f8]=<a href='f8/x8'>f8</a>" + +"\n[f9]=<a href='f9/x9'>f9</a>" + +"\n[fa]=<a href='http://www.apache.org/fa/xa#MY_LABEL'>fa</a>" + +"\n[fb]=<a href='http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar'>MY_LABEL</a>" + +"\n[fc]=<a href='http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL'>MY_LABEL</a>" + +"\n[fd]=<a href='http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar'>fd</a>" + +"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>fe</a>" + ; + assertEquals(expected, r); + + s.setProperty(SERIALIZER_absolutePathUriBase, ""); // Same as null. + r = strip(s.serialize(t)); + expected = "" + +"\n[f0]=<a href='f0/x0'>f0</a>" + +"\n[f1]=<a href='f1/x1'>f1</a>" + +"\n[f2]=<a href='/f2/x2'>f2</a>" + +"\n[f3]=<a href='http://www.apache.org/f3/x3'>f3</a>" + +"\n[f4]=<a href='f4/x4'>f4</a>" + +"\n[f5]=<a href='/f5/x5'>f5</a>" + +"\n[f6]=<a href='http://www.apache.org/f6/x6'>f6</a>" + +"\n[f7]=<a href='http://www.apache.org/f7/x7'>f7</a>" + +"\n[f8]=<a href='f8/x8'>f8</a>" + +"\n[f9]=<a href='f9/x9'>f9</a>" + +"\n[fa]=<a href='http://www.apache.org/fa/xa#MY_LABEL'>fa</a>" + +"\n[fb]=<a href='http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar'>MY_LABEL</a>" + +"\n[fc]=<a href='http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL'>MY_LABEL</a>" + +"\n[fd]=<a href='http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar'>fd</a>" + +"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>fe</a>" + ; + assertEquals(expected, r); + } + + private String strip(String html) { + return html + .replace("<table><tr><th>key</th><th>value</th></tr>", "") + .replace("</table>", "") + .replace("<tr><td>", "\n[") + .replace("</td><td>", "]=") + .replace("</td></tr>", ""); + } + + //==================================================================================================== + // Validate that you cannot update properties on locked serializer. + //==================================================================================================== + @Test + public void testLockedSerializer() throws Exception { + HtmlSerializer s = new HtmlSerializer().lock(); + try { + s.setProperty(XmlSerializerContext.XML_enableNamespaces, true); + fail("Locked exception not thrown"); + } catch (LockedException e) {} + try { + s.setProperty(SerializerContext.SERIALIZER_addBeanTypeProperties, true); + fail("Locked exception not thrown"); + } catch (LockedException e) {} + try { + s.setProperty(BeanContext.BEAN_beanMapPutReturnsOldValue, true); + fail("Locked exception not thrown"); + } catch (LockedException e) {} + } + + //==================================================================================================== + // Recursion + //==================================================================================================== + @Test + public void testRecursion() throws Exception { + HtmlSerializer s = new HtmlSerializer.Sq().setProperty(HTML_addKeyValueTableHeaders, true); + + R1 r1 = new R1(); + R2 r2 = new R2(); + R3 r3 = new R3(); + r1.r2 = r2; + r2.r3 = r3; + r3.r1 = r1; + + // No recursion detection + try { + s.serialize(r1); + fail("Exception expected!"); + } catch (Exception e) { + String msg = e.getLocalizedMessage(); + assertTrue(msg.contains("It's recommended you use the SerializerContext.SERIALIZER_detectRecursions setting to help locate the loop.")); + } + + // Recursion detection, no ignore + s.setProperty(SERIALIZER_detectRecursions, true); + try { + s.serialize(r1); + fail("Exception expected!"); + } catch (Exception e) { + String msg = e.getLocalizedMessage(); + assertTrue(msg.contains("[0]<noname>:org.apache.juneau.html.CommonTest$R1")); + assertTrue(msg.contains("->[1]r2:org.apache.juneau.html.CommonTest$R2")); + assertTrue(msg.contains("->[2]r3:org.apache.juneau.html.CommonTest$R3")); + assertTrue(msg.contains("->[3]r1:org.apache.juneau.html.CommonTest$R1")); + } + + s.setProperty(SERIALIZER_ignoreRecursions, true); + assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>name</td><td>foo</td></tr><tr><td>r2</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>name</td><td>bar</td></tr><tr><td>r3</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>name</td><td>baz</td></tr></table></td></tr></table></td></tr></table>", + s.serialize(r1)); + + // Make sure this doesn't blow up. + s.getSchemaSerializer().serialize(r1); + } + + public static class R1 { + public String name = "foo"; + public R2 r2; + } + public static class R2 { + public String name = "bar"; + public R3 r3; + } + public static class R3 { + public String name = "baz"; + public R1 r1; + } + + //==================================================================================================== + // Basic bean + //==================================================================================================== + @Test + public void testBasicBean() throws Exception { + WriterSerializer s = new HtmlSerializer.Sq().setProperty(SERIALIZER_trimNullProperties, false).setProperty(BEAN_sortProperties, true).setProperty(HTML_addKeyValueTableHeaders, true); + + J a = new J(); + a.setF1("J"); + a.setF2(100); + a.setF3(true); + assertEquals( + "<table>" + +"<tr><th>key</th><th>value</th></tr>" + +"<tr><td>f1</td><td>J</td></tr>" + +"<tr><td>f2</td><td>100</td></tr>" + +"<tr><td>f3</td><td>true</td></tr>" + +"</table>", + s.serialize(a)); + } + + public static class J { + private String f1 = null; + private int f2 = -1; + private boolean f3 = false; + + public String getF1() { + return this.f1; + } + + public void setF1(String f1) { + this.f1 = f1; + } + + public int getF2() { + return this.f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public boolean isF3() { + return this.f3; + } + + public void setF3(boolean f3) { + this.f3 = f3; + } + + @Override /* Object */ + public String toString() { + return ("J(f1: " + this.getF1() + ", f2: " + this.getF2() + ")"); + } + } +}
