/*
* 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.parser;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import org.apache.wicket.markup.parser.IXmlPullParser.HttpTagType;
import org.apache.wicket.util.resource.StringResourceStream;
import org.junit.Assert;
import org.junit.Test;
/**
* Quite some tests are already with MarkupParser.
*
* @author Juergen Donnerstag
*/
public class XmlPullParserTest extends Assert
{
/**
*
* @throws Exception
*/
@Test
public final void basics() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("This is a text");
XmlTag elem = parser.nextTag();
assertNull(elem);
parser.parse("<tag/>");
XmlTag tag = parser.nextTag();
assertFalse(tag.isOpen());
// assertFalse(tag.isOpen("tag"));
// assertFalse(tag.isOpen("xxx"));
assertFalse(tag.isClose());
assertTrue(tag.isOpenClose());
// assertTrue(tag.isOpenClose("tag"));
assertEquals("tag", tag.getName());
assertNull(tag.getNamespace());
assertEquals(0, tag.getAttributes().size());
// extra spaces
parser.parse("<tag ></tag >");
tag = parser.nextTag();
assertTrue(tag.isOpen());
// assertTrue(tag.isOpen("tag"));
// assertFalse(tag.isOpen("xxx"));
assertFalse(tag.isClose());
assertFalse(tag.isOpenClose());
// assertFalse(tag.isOpenClose("tag"));
assertEquals("tag", tag.getName());
assertNull(tag.getNamespace());
assertEquals(0, tag.getAttributes().size());
tag = parser.nextTag();
assertFalse(tag.isOpen());
// assertFalse(tag.isOpen("tag"));
// assertFalse(tag.isOpen("xxx"));
assertTrue(tag.isClose());
assertFalse(tag.isOpenClose());
// assertFalse(tag.isOpenClose("tag"));
assertEquals("tag", tag.getName());
assertNull(tag.getNamespace());
assertEquals(0, tag.getAttributes().size());
parser.parse("<tag> </tag>");
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
tag = parser.nextTag();
assertTrue(tag.isClose());
parser.parse("xx <tag> yy </tag> zz");
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
tag = parser.nextTag();
assertTrue(tag.isClose());
// XmlPullParser does NOT check that tags get properly closed
parser.parse("<tag>");
tag = parser.nextTag();
tag = parser.nextTag();
assertNull(elem);
parser.parse("<tag> <tag> <tag>");
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
parser.parse("<ns:tag/>");
tag = parser.nextTag();
// assertTrue(tag.isOpenClose("tag"));
assertEquals("ns", tag.getNamespace());
assertEquals("tag", tag.getName());
parser.parse("<ns:tag></ns:tag>");
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
assertEquals("ns", tag.getNamespace());
assertEquals("tag", tag.getName());
XmlTag closeTag = parser.nextTag();
assertTrue(closeTag.isClose());
assertEquals("ns", closeTag.getNamespace());
assertEquals("tag", closeTag.getName());
}
/**
*
* @throws Exception
*/
@Test
public final void encoding() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse(
new StringResourceStream("<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>").getInputStream(),
null);
assertEquals("iso-8859-1", parser.getEncoding());
XmlTag tag = parser.nextTag();
assertNull(tag);
parser.parse(new StringResourceStream(
"<?xml version=\"1.0\" encoding='iso-8859-1' ?> test test").getInputStream(), null);
assertEquals("iso-8859-1", parser.getEncoding());
tag = parser.nextTag();
assertNull(tag);
// re-order and move close (remove whitespaces
parser.parse(new StringResourceStream(
" <?xml encoding='iso-8859-1'version=\"1.0\"?> test test").getInputStream(), null);
assertEquals("iso-8859-1", parser.getEncoding());
tag = parser.nextTag();
assertNull(tag);
// attribute value must be enclosed by ""
parser.parse(
new StringResourceStream("<?xml encoding=iso-8859-1 ?> test test").getInputStream(),
null);
assertEquals("iso-8859-1", parser.getEncoding());
// Invaluid encoding
Exception ex = null;
try
{
parser.parse(new StringResourceStream("<?xml encoding='XXX' ?>").getInputStream(), null);
}
catch (UnsupportedEncodingException e)
{
ex = e;
}
assertNotNull(ex);
// no extra characters allowed before <?xml>
// TODO General: I'd certainly prefer an exception
parser.parse(
new StringResourceStream("xxxx <?xml encoding='iso-8859-1' ?>").getInputStream(), null);
assertNull(parser.getEncoding());
tag = parser.nextTag();
assertNull(tag);
// no extra characters allowed before <?xml>
// Are comments allowed preceding the encoding string?
parser.parse(
new StringResourceStream("<!-- Comment --> <?xml encoding='iso-8859-1' ?>").getInputStream(),
null);
assertNull(parser.getEncoding());
tag = parser.nextTag();
assertNull(tag);
// 'test' is not a valid attribut. But we currently don't test it.
parser.parse(new StringResourceStream("<?xml test='123' >").getInputStream(), null);
assertNull(parser.getEncoding());
tag = parser.nextTag();
assertNull(tag);
}
/**
* WICKET-5398 parsing from String
*/
@Test
public void encodingOfString() throws Exception
{
// use an encoding that is not the system's file encoding
final String encoding;
if ("UTF-8".equals(System.getProperty("file.encoding")))
{
encoding = "ISO-8859-1";
}
else
{
encoding = "UTF-8";
}
final XmlPullParser parser = new XmlPullParser();
parser.parse(String.format("<?xml encoding='%s' ?><span id='umlaut-äöü'></span>", encoding));
assertEquals("umlaut-äöü", parser.nextTag().getAttribute("id"));
}
/**
*
* @throws Exception
*/
@Test
public final void attributes() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("<tag>");
XmlTag tag = parser.nextTag();
assertEquals(0, tag.getAttributes().size());
// assertTrue(tag.isOpen("tag"));
assertFalse(tag.getAttributes().containsKey("attr"));
assertNull(tag.getAttributes().getString("attr"));
parser.parse("<tag attr='1234'>");
tag = parser.nextTag();
assertEquals(1, tag.getAttributes().size());
assertTrue(tag.getAttributes().containsKey("attr"));
assertEquals("1234", tag.getAttributes().getString("attr"));
parser.parse("<tag attr=1234>");
tag = parser.nextTag();
assertEquals(1, tag.getAttributes().size());
assertTrue(tag.getAttributes().containsKey("attr"));
assertEquals("1234", tag.getAttributes().getString("attr"));
parser.parse("<tag attr=1234 >");
tag = parser.nextTag();
assertEquals(1, tag.getAttributes().size());
assertTrue(tag.getAttributes().containsKey("attr"));
assertEquals("1234", tag.getAttributes().getString("attr"));
parser.parse("<tag attr-withHypen=1234 >");
tag = parser.nextTag();
assertEquals(1, tag.getAttributes().size());
assertTrue(tag.getAttributes().containsKey("attr-withHypen"));
assertEquals("1234", tag.getAttributes().getString("attr-withHypen"));
parser.parse("<tag attr=\"1234\">");
tag = parser.nextTag();
assertEquals(1, tag.getAttributes().size());
assertTrue(tag.getAttributes().containsKey("attr"));
assertEquals("1234", tag.getAttributes().getString("attr"));
parser.parse("<tag attr='1234' test='23'>");
tag = parser.nextTag();
assertEquals(2, tag.getAttributes().size());
assertTrue(tag.getAttributes().containsKey("attr"));
assertEquals("1234", tag.getAttributes().getString("attr"));
assertTrue(tag.getAttributes().containsKey("test"));
assertEquals("23", tag.getAttributes().getString("test"));
parser.parse("<tag attr='1234' attr='23'>");
Exception ex = null;
try
{
tag = parser.nextTag();
}
catch (ParseException e)
{
ex = e;
}
assertNotNull(ex);
}
/**
*
* @throws Exception
*/
@Test
public final void comments() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("<!-- test --><tag>");
XmlTag tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
parser.parse("<!-- test --><tag> aaa <!-- test 1 --> bbb <tag> <!-- test --> </tag>");
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
tag = parser.nextTag();
assertTrue(tag.isClose());
tag = parser.nextTag();
assertNull(tag);
// As you can see, XmlPullParser is really a shallow parser only
parser.parse("<!-- test --><tag> aaa <?tag test 1 ?> bbb <tag> <!DOCTYPE test > </tag>");
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
tag = parser.nextTag();
// assertTrue(tag.isOpen("tag"));
tag = parser.nextTag();
assertTrue(tag.isClose());
tag = parser.nextTag();
assertNull(tag);
}
/**
*
* @throws Exception
*/
@Test
public final void compressWhitespace() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>");
}
/**
*
* @throws Exception
*/
@Test
public final void script() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("<html><script language=\"JavaScript\">... <x a> ...</script></html>");
XmlTag tag = parser.nextTag();
assertTrue(tag.isOpen());
assertEquals("html", tag.getName());
tag = parser.nextTag();
assertTrue(tag.isOpen());
assertEquals("script", tag.getName());
tag = parser.nextTag();
assertTrue(tag.isClose());
assertEquals("script", tag.getName());
tag = parser.nextTag();
assertTrue(tag.isClose());
assertEquals("html", tag.getName());
}
/**
*
* @throws Exception
*/
@Test
public final void conditionalComments() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("<!--[if IE]><a href='test.html'>my link</a><![endif]-->");
XmlTag tag = parser.nextTag();
assertTrue(tag.isOpen());
assertEquals("a", tag.getName());
tag = parser.nextTag();
assertTrue(tag.isClose());
assertEquals("a", tag.getName());
tag = parser.nextTag();
assertNull(tag);
}
/**
*
* @throws Exception
*/
@Test
public final void conditionalComments2() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("<!--[if IE]><a href='test.html'>my link</a><![endif]-->");
HttpTagType type = parser.next();
assertEquals(type, HttpTagType.CONDITIONAL_COMMENT);
type = parser.next();
assertEquals(type, HttpTagType.TAG);
assertTrue((parser.getElement()).isOpen());
type = parser.next();
assertEquals(type, HttpTagType.BODY);
type = parser.next();
assertEquals(type, HttpTagType.TAG);
assertEquals("a", (parser.getElement()).getName());
assertTrue((parser.getElement()).isClose());
type = parser.next();
assertEquals(type, HttpTagType.CONDITIONAL_COMMENT_ENDIF);
type = parser.next();
assertEquals(type, HttpTagType.NOT_INITIALIZED);
}
/**
*
* @throws Exception
*/
@Test
public final void names() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("<filter-mapping>");
XmlTag tag = parser.nextTag();
assertTrue(tag.isOpen());
assertEquals("filter-mapping", tag.getName());
parser.parse("<filter.mapping>");
tag = parser.nextTag();
assertTrue(tag.isOpen());
assertEquals("filter.mapping", tag.getName());
parser.parse("<filter_mapping>");
tag = parser.nextTag();
assertTrue(tag.isOpen());
assertEquals("filter_mapping", tag.getName());
}
/**
*
* @throws Exception
*/
@Test
public final void doctype() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("<!DOCTYPE html>");
HttpTagType type = parser.next();
assertEquals(HttpTagType.DOCTYPE, type);
assertEquals("!DOCTYPE html", parser.getDoctype());
}
/**
* @throws Exception
*/
@Test
public final void downlevelRevealedConditionalComments() throws Exception
{
final XmlPullParser parser = new XmlPullParser();
parser.parse("<!--[if (gt IE 9)|!(IE)]><!--><html lang=\"en\" class=\"no-js\"><!--<![endif]--> <span>test</span>");
HttpTagType type = parser.next();
assertEquals(HttpTagType.CONDITIONAL_COMMENT, type);
type = parser.next();
assertEquals(HttpTagType.COMMENT, type);
type = parser.next();
assertEquals(HttpTagType.TAG, type);
XmlTag componentTag = parser.getElement();
assertEquals("html", componentTag.getName());
type = parser.next();
assertEquals(HttpTagType.CONDITIONAL_COMMENT_ENDIF, type);
}
}