/* * Copyright (C) 2010 The Android Open Source Project * * Licensed 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 libcore.xml; import java.io.ByteArrayInputStream; import java.io.StringReader; import junit.framework.TestCase; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; public abstract class PullParserTest extends TestCase { public void testAttributeNoValueWithRelaxed() throws Exception { XmlPullParser parser = newPullParser(); parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("input", parser.getName()); assertEquals("checked", parser.getAttributeName(0)); assertEquals("checked", parser.getAttributeValue(0)); } public void testAttributeUnquotedValueWithRelaxed() throws Exception { XmlPullParser parser = newPullParser(); parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("input", parser.getName()); assertEquals("checked", parser.getAttributeName(0)); assertEquals("true", parser.getAttributeValue(0)); } public void testUnterminatedEntityWithRelaxed() throws Exception { XmlPullParser parser = newPullParser(); parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); parser.setInput(new StringReader("mac&cheese")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("foo", parser.getName()); assertEquals("bar", parser.getAttributeName(0)); assertEquals("A&W", parser.getAttributeValue(0)); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("mac&cheese", parser.getText()); } public void testEntitiesAndNamespaces() throws Exception { XmlPullParser parser = newPullParser(); parser.setFeature("http://xmlpull.org/v1/doc/features.html#process-namespaces", true); parser.setInput(new StringReader( "")); testNamespace(parser); } public void testEntitiesAndNamespacesWithRelaxed() throws Exception { XmlPullParser parser = newPullParser(); parser.setFeature("http://xmlpull.org/v1/doc/features.html#process-namespaces", true); parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); parser.setInput(new StringReader( "")); testNamespace(parser); } private void testNamespace(XmlPullParser parser) throws Exception { assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("http://foo", parser.getNamespace()); assertEquals("a", parser.getName()); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("http://bar", parser.getNamespace()); assertEquals("b", parser.getName()); assertEquals(XmlPullParser.END_TAG, parser.next()); assertEquals("http://bar", parser.getNamespace()); assertEquals("b", parser.getName()); assertEquals(XmlPullParser.END_TAG, parser.next()); assertEquals("http://foo", parser.getNamespace()); assertEquals("a", parser.getName()); } public void testRegularNumericEntities() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("A")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.ENTITY_REF, parser.nextToken()); assertEquals("#65", parser.getName()); assertEquals("A", parser.getText()); } public void testNumericEntitiesLargerThanChar() throws Exception { assertParseFailure("� &#-2147483648;"); } public void testNumericEntitiesLargerThanInt() throws Exception { assertParseFailure(""); } public void testCharacterReferenceOfHexUtf16Surrogates() throws Exception { testCharacterReferenceOfUtf16Surrogates("𐀀 𐎁 􏿰"); } public void testCharacterReferenceOfDecimalUtf16Surrogates() throws Exception { testCharacterReferenceOfUtf16Surrogates("𐀀 𐎁 􏿰"); } private void testCharacterReferenceOfUtf16Surrogates(String xml) throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader(xml)); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals(new String(new int[]{65536, ' ', 66433, ' ', 1114096}, 0, 5), parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testCharacterReferenceOfLastUtf16Surrogate() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("􏿿")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals(new String(new int[]{0x10FFFF}, 0, 1), parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testOmittedNumericEntities() throws Exception { assertParseFailure("&#;"); } /** * Carriage returns followed by line feeds are silently discarded. */ public void testCarriageReturnLineFeed() throws Exception { testLineEndings("\r\nd\r\ne\r\n"); } /** * Lone carriage returns are treated like newlines. */ public void testLoneCarriageReturn() throws Exception { testLineEndings("\rd\re\r"); } public void testLoneNewLine() throws Exception { testLineEndings("\nd\ne\n"); } private void testLineEndings(String xml) throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader(xml)); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("foo", parser.getName()); assertEquals("b c", parser.getAttributeValue(0)); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("d\ne", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); assertEquals("foo", parser.getName()); assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); } public void testXmlDeclaration() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader( "")); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals("1.0", parser.getProperty( "http://xmlpull.org/v1/doc/properties.html#xmldecl-version")); assertEquals(Boolean.FALSE, parser.getProperty( "http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone")); assertEquals("UTF-8", parser.getInputEncoding()); } public void testXmlDeclarationExtraAttributes() throws Exception { assertParseFailure(""); } public void testCustomEntitiesUsingNext() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader( "wx&aaaaaaaaaa;yz")); parser.defineEntityReplacementText("aaaaaaaaaa", "b"); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("cdbef", parser.getAttributeValue(0)); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("wxbyz", parser.getText()); } public void testCustomEntitiesUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader( "wx&aaaaaaaaaa;yz")); parser.defineEntityReplacementText("aaaaaaaaaa", "b"); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals("cdbef", parser.getAttributeValue(0)); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals("wx", parser.getText()); assertEquals(XmlPullParser.ENTITY_REF, parser.nextToken()); assertEquals("aaaaaaaaaa", parser.getName()); assertEquals("b", parser.getText()); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals("yz", parser.getText()); } public void testCustomEntitiesAreNotEvaluated() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader( "&a;")); parser.defineEntityReplacementText("a", "& &a;"); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("& &a;", parser.getAttributeValue(0)); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("& &a;", parser.getText()); } public void testMissingEntities() throws Exception { assertParseFailure("&aaa;"); } public void testMissingEntitiesWithRelaxed() throws Exception { XmlPullParser parser = newPullParser(); parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); parser.setInput(new StringReader("&aaa;")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals(null, parser.getName()); assertEquals("Expected unresolved entities to be left in-place. The old parser " + "would resolve these to the empty string.", "&aaa;", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testMissingEntitiesUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); testMissingEntitiesUsingNextToken(parser); } public void testMissingEntitiesUsingNextTokenWithRelaxed() throws Exception { XmlPullParser parser = newPullParser(); parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); testMissingEntitiesUsingNextToken(parser); } private void testMissingEntitiesUsingNextToken(XmlPullParser parser) throws Exception { parser.setInput(new StringReader("&aaa;")); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals(XmlPullParser.ENTITY_REF, parser.nextToken()); assertEquals("aaa", parser.getName()); assertEquals(null, parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testEntityInAttributeUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals("foo", parser.getName()); assertEquals("&", parser.getAttributeValue(null, "bar")); } public void testMissingEntitiesInAttributesUsingNext() throws Exception { assertParseFailure(""); } public void testMissingEntitiesInAttributesUsingNextWithRelaxed() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals(1, parser.getAttributeCount()); assertEquals("b", parser.getAttributeName(0)); assertEquals("Expected unresolved entities to be left in-place. The old parser " + "would resolve these to the empty string.", "&aaa;", parser.getAttributeValue(0)); } public void testMissingEntitiesInAttributesUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); testMissingEntitiesInAttributesUsingNextToken(parser); } public void testMissingEntitiesInAttributesUsingNextTokenWithRelaxed() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); testMissingEntitiesInAttributesUsingNextToken(parser); } private void testMissingEntitiesInAttributesUsingNextToken(XmlPullParser parser) throws Exception { assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals(1, parser.getAttributeCount()); assertEquals("b", parser.getAttributeName(0)); assertEquals("Expected unresolved entities to be left in-place. The old parser " + "would resolve these to the empty string.", "&aaa;", parser.getAttributeValue(0)); } public void testGreaterThanInText() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader(">")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals(">", parser.getText()); } public void testGreaterThanInAttribute() throws Exception{ XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(">", parser.getAttributeValue(0)); } public void testLessThanInText() throws Exception{ assertParseFailure("<"); } public void testLessThanInAttribute() throws Exception{ assertParseFailure(""); } public void testQuotesInAttribute() throws Exception{ XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("\"", parser.getAttributeValue(0)); assertEquals("'", parser.getAttributeValue(1)); } public void testQuotesInText() throws Exception{ XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("\" '")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("\" '", parser.getText()); } public void testCdataDelimiterInAttribute() throws Exception{ XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("]]>", parser.getAttributeValue(0)); } public void testCdataDelimiterInText() throws Exception{ assertParseFailure("]]>"); } public void testUnexpectedEof() throws Exception { assertParseFailure(""); } public void testThreeDashCommentDelimiter() throws Exception { assertParseFailure(""); } public void testTwoDashesInComment() throws Exception { assertParseFailure(""); } public void testEmptyComment() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.COMMENT, parser.nextToken()); assertEquals("", parser.getText()); } /** * Close braces require lookaheads because we need to defend against "]]>". */ public void testManyCloseBraces() throws Exception{ XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("]]]]]]]]]]]]]]]]]]]]]]]")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("]]]]]]]]]]]]]]]]]]]]]]]", parser.getText()); } public void testCommentUsingNext() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("abcd")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("abcd", parser.getText()); } public void testCommentUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("abcd")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals("ab", parser.getText()); assertEquals(XmlPullParser.COMMENT, parser.nextToken()); assertEquals(" comment! ", parser.getText()); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals("cd", parser.getText()); } public void testCdataUsingNext() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("abjk")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("abcdef]]gh&ijk", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testCdataUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("abjk")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals("ab", parser.getText()); assertEquals(XmlPullParser.CDSECT, parser.nextToken()); assertEquals("cdef]]gh&i", parser.getText()); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals("jk", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.nextToken()); } public void testEntityLooksLikeCdataClose() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("]]>")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("]]>", parser.getText()); } public void testProcessingInstructionUsingNext() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("abkl")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals("abkl", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testProcessingInstructionUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("abkl")); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals("ab", parser.getText()); assertEquals(XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken()); assertEquals("cd efg hij", parser.getText()); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals("kl", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testWhitespaceUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader(" \n \n \n ")); assertEquals(XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken()); assertEquals(true, parser.isWhitespace()); assertEquals(" \n ", parser.getText()); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals(true, parser.isWhitespace()); assertEquals(" \n ", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.nextToken()); assertEquals(XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken()); assertEquals(true, parser.isWhitespace()); assertEquals(" \n ", parser.getText()); assertEquals(XmlPullParser.END_DOCUMENT, parser.nextToken()); } public void testLinesAndColumns() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("\n" + " fg\n" + "")); assertEquals("1,1", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken()); assertEquals("2,3", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals("2,8", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals("3,11", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.END_TAG, parser.nextToken()); assertEquals("4,2", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.COMMENT, parser.nextToken()); assertEquals("6,4", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals("6,10", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.END_TAG, parser.nextToken()); assertEquals("6,10", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.TEXT, parser.nextToken()); assertEquals("7,1", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.END_TAG, parser.nextToken()); assertEquals("7,7", parser.getLineNumber() + "," + parser.getColumnNumber()); assertEquals(XmlPullParser.END_DOCUMENT, parser.nextToken()); assertEquals("7,7", parser.getLineNumber() + "," + parser.getColumnNumber()); } public void testEmptyEntityReferenceUsingNext() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); parser.defineEntityReplacementText("empty", ""); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testEmptyEntityReferenceUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); parser.defineEntityReplacementText("empty", ""); assertEquals(XmlPullParser.START_TAG, parser.nextToken()); assertEquals(XmlPullParser.ENTITY_REF, parser.nextToken()); assertEquals("empty", parser.getName()); assertEquals("", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.nextToken()); } public void testEmptyCdataUsingNext() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testEmptyCdataUsingNextToken() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.CDSECT, parser.nextToken()); assertEquals("", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); } public void testParseReader() throws Exception { String snippet = "hello"; XmlPullParser parser = newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(new StringReader(snippet)); validate(parser); } public void testParseInputStream() throws Exception { String snippet = "hello"; XmlPullParser parser = newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(new ByteArrayInputStream(snippet.getBytes()), "UTF-8"); validate(parser); } static void validate(XmlPullParser parser) throws Exception { assertEquals(XmlPullParser.START_DOCUMENT, parser.getEventType()); assertEquals(0, parser.getDepth()); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(1, parser.getDepth()); assertEquals("dagny", parser.getName()); assertEquals(1, parser.getAttributeCount()); assertEquals("dad", parser.getAttributeName(0)); assertEquals("bob", parser.getAttributeValue(0)); assertEquals("bob", parser.getAttributeValue(null, "dad")); assertEquals(XmlPullParser.TEXT, parser.next()); assertEquals(1, parser.getDepth()); assertEquals("hello", parser.getText()); assertEquals(XmlPullParser.END_TAG, parser.next()); assertEquals(1, parser.getDepth()); assertEquals("dagny", parser.getName()); assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); assertEquals(0, parser.getDepth()); } public void testNextAfterEndDocument() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(XmlPullParser.END_TAG, parser.next()); assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); } public void testNamespaces() throws Exception { String xml = "\n" + " text\n" + ""; XmlPullParser parser = newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); parser.setInput(new StringReader(xml)); assertEquals(0, parser.getDepth()); assertEquals(0, parser.getNamespaceCount(0)); try { parser.getNamespaceCount(1); fail(); } catch (IndexOutOfBoundsException e) { /* expected */ } // one assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals(1, parser.getDepth()); checkNamespacesInOne(parser); // n1:two assertEquals(XmlPullParser.START_TAG, parser.nextTag()); assertEquals(2, parser.getDepth()); checkNamespacesInTwo(parser); // Body of two. assertEquals(XmlPullParser.TEXT, parser.next()); // End of two. assertEquals(XmlPullParser.END_TAG, parser.nextTag()); // Depth should still be 2. assertEquals(2, parser.getDepth()); // We should still be able to see the namespaces from two. checkNamespacesInTwo(parser); // End of one. assertEquals(XmlPullParser.END_TAG, parser.nextTag()); // Depth should be back to 1. assertEquals(1, parser.getDepth()); // We can still see the namespaces in one. checkNamespacesInOne(parser); // We shouldn't be able to see the namespaces in two anymore. try { parser.getNamespaceCount(2); fail(); } catch (IndexOutOfBoundsException e) { /* expected */ } assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); // We shouldn't be able to see the namespaces in one anymore. try { parser.getNamespaceCount(1); fail(); } catch (IndexOutOfBoundsException e) { /* expected */ } assertEquals(0, parser.getNamespaceCount(0)); } private void checkNamespacesInOne(XmlPullParser parser) throws XmlPullParserException { assertEquals(2, parser.getNamespaceCount(1)); // Prefix for default namespace is null. assertNull(parser.getNamespacePrefix(0)); assertEquals("ns:default", parser.getNamespaceUri(0)); assertEquals("n1", parser.getNamespacePrefix(1)); assertEquals("ns:1", parser.getNamespaceUri(1)); assertEquals("ns:default", parser.getNamespace(null)); // KXML returns null. // assertEquals("ns:default", parser.getNamespace("")); } private void checkNamespacesInTwo(XmlPullParser parser) throws XmlPullParserException { // These should still be valid. checkNamespacesInOne(parser); assertEquals(3, parser.getNamespaceCount(2)); // Default ns should still be in the stack assertNull(parser.getNamespacePrefix(0)); assertEquals("ns:default", parser.getNamespaceUri(0)); } public void testTextBeforeDocumentElement() throws Exception { assertParseFailure("not xml"); } public void testTextAfterDocumentElement() throws Exception { assertParseFailure("not xml"); } public void testTextNoDocumentElement() throws Exception { assertParseFailure("not xml"); } public void testBomAndByteInput() throws Exception { byte[] xml = "\ufeff".getBytes("UTF-8"); XmlPullParser parser = newPullParser(); parser.setInput(new ByteArrayInputStream(xml), null); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("input", parser.getName()); assertEquals(XmlPullParser.END_TAG, parser.next()); assertEquals("input", parser.getName()); assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); } public void testBomAndByteInputWithExplicitCharset() throws Exception { byte[] xml = "\ufeff".getBytes("UTF-8"); XmlPullParser parser = newPullParser(); parser.setInput(new ByteArrayInputStream(xml), "UTF-8"); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("input", parser.getName()); assertEquals(XmlPullParser.END_TAG, parser.next()); assertEquals("input", parser.getName()); assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); } public void testBomAndCharacterInput() throws Exception { assertParseFailure("\ufeff"); } // http://code.google.com/p/android/issues/detail?id=21425 public void testNextTextAdvancesToEndTag() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader("bar")); assertEquals(XmlPullParser.START_TAG, parser.next()); assertEquals("bar", parser.nextText()); assertEquals(XmlPullParser.END_TAG, parser.getEventType()); } public void testNextTag() throws Exception { XmlPullParser parser = newPullParser(); parser.setInput(new StringReader(" ")); assertEquals(XmlPullParser.START_TAG, parser.nextTag()); assertEquals("foo", parser.getName()); assertEquals(XmlPullParser.START_TAG, parser.nextTag()); assertEquals("bar", parser.getName()); assertEquals(XmlPullParser.END_TAG, parser.nextTag()); assertEquals("bar", parser.getName()); assertEquals(XmlPullParser.END_TAG, parser.nextTag()); assertEquals("foo", parser.getName()); } public void testEofInElementSpecRelaxed() throws Exception { assertRelaxedParseFailure("') } public void testEofAfterReadCharArrayRelaxed() throws Exception { assertRelaxedParseFailure("') } public void testWhitespacesAfterDOCTYPE() throws Exception { XmlPullParser parser = newPullParser(); String test = "\n" + "\n" + "]> \n" + ""; assertParseSuccess(test, parser); } // Regression test for https://code.google.com/p/android/issues/detail?id=182605 public void testSetInputParserReuse() throws Exception { XmlPullParser parser = newPullParser(); String test = "\n" + "\n" + "]> \n" + ""; assertParseSuccess(test, parser); // A second call to parser.setInput() on a parser should result in a fully-reset parser. assertParseSuccess(test, parser); } private void assertParseFailure(String xml) throws Exception { XmlPullParser parser = newPullParser(); assertParseFailure(xml, parser); } private void assertRelaxedParseFailure(String xml) throws Exception { XmlPullParser parser = newPullParser(); parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); assertParseFailure(xml, parser); } private void assertParseFailure(String xml, XmlPullParser parser) throws Exception { parser.setInput(new StringReader(xml)); try { while (parser.next() != XmlPullParser.END_DOCUMENT) { } fail(); } catch (XmlPullParserException expected) { } } private void assertParseSuccess(String xml, XmlPullParser parser) throws Exception { parser.setInput(new StringReader(xml)); while (parser.next() != XmlPullParser.END_DOCUMENT) { } } /** * Creates a new pull parser. */ abstract XmlPullParser newPullParser(); }