diff options
author | Brian Carlstrom <bdc@google.com> | 2010-11-30 17:25:59 -0800 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2010-11-30 17:25:59 -0800 |
commit | 3b5d436bb2345a0b8b9cb764a5b4fc6e6aa5711a (patch) | |
tree | 3bf671319352efca792581d7db3b58740f102dcb /luni/src/test | |
parent | d57c5b796b43f14437701833795a2ad5ed275d1b (diff) | |
parent | 29b81d92eb59bc4e5b5a64e862dd8decb21f42d4 (diff) | |
download | libcore-3b5d436bb2345a0b8b9cb764a5b4fc6e6aa5711a.zip libcore-3b5d436bb2345a0b8b9cb764a5b4fc6e6aa5711a.tar.gz libcore-3b5d436bb2345a0b8b9cb764a5b4fc6e6aa5711a.tar.bz2 |
Merge remote branch 'goog/dalvik-dev' into dalvik-dev-to-master
Diffstat (limited to 'luni/src/test')
28 files changed, 1865 insertions, 451 deletions
diff --git a/luni/src/test/java/libcore/internal/StringPoolTest.java b/luni/src/test/java/libcore/internal/StringPoolTest.java new file mode 100644 index 0000000..82c7c4e --- /dev/null +++ b/luni/src/test/java/libcore/internal/StringPoolTest.java @@ -0,0 +1,44 @@ +/* + * 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.internal; + +import junit.framework.TestCase; +import libcore.internal.StringPool; + +public final class StringPoolTest extends TestCase { + + public void testStringPool() { + StringPool stringPool = new StringPool(); + String bcd = stringPool.get(new char[] { 'a', 'b', 'c', 'd', 'e' }, 1, 3); + assertEquals("bcd", bcd); + assertSame(bcd, stringPool.get(new char[] { 'a', 'b', 'c', 'd', 'e' }, 1, 3)); + } + + public void testHashCollision() { + StringPool stringPool = new StringPool(); + char[] a = { (char) 1, (char) 0 }; + char[] b = { (char) 0, (char) 31 }; + assertEquals(new String(a).hashCode(), new String(b).hashCode()); + + String aString = stringPool.get(a, 0, 2); + assertEquals(new String(a), aString); + String bString = stringPool.get(b, 0, 2); + assertEquals(new String(b), bString); + assertSame(bString, stringPool.get(b, 0, 2)); + assertNotSame(aString, stringPool.get(a, 0, 2)); + } +} diff --git a/luni/src/test/java/libcore/java/io/FileTest.java b/luni/src/test/java/libcore/java/io/FileTest.java index cd9b877..535975d 100644 --- a/luni/src/test/java/libcore/java/io/FileTest.java +++ b/luni/src/test/java/libcore/java/io/FileTest.java @@ -186,18 +186,6 @@ public class FileTest extends junit.framework.TestCase { } private static void ln_s(String target, String linkName) throws Exception { - String[] args = new String[] { "ln", "-s", target, linkName }; - // System.err.println("ln -s " + target + " " + linkName); - Process p = Runtime.getRuntime().exec(args); - int result = p.waitFor(); - if (result != 0) { - BufferedReader r = new BufferedReader(new InputStreamReader(p.getErrorStream())); - String line; - while ((line = r.readLine()) != null) { - System.err.println(line); - } - fail("ln -s " + target + " " + linkName + " failed. " + - "Does that file system support symlinks?"); - } + File.symlink(target, linkName); } } diff --git a/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java b/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java index ee7f6e8..041b931 100644 --- a/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java +++ b/luni/src/test/java/libcore/java/lang/ArrayIndexOutOfBoundsExceptionTest.java @@ -24,7 +24,7 @@ public final class ArrayIndexOutOfBoundsExceptionTest extends TestCase { try { bs[2] = 0; fail(); - } catch (Exception ex) { + } catch (ArrayIndexOutOfBoundsException ex) { assertEquals("index=2 length=1", ex.getMessage()); } } @@ -34,7 +34,7 @@ public final class ArrayIndexOutOfBoundsExceptionTest extends TestCase { try { byte b = bs[2]; fail(); - } catch (Exception ex) { + } catch (ArrayIndexOutOfBoundsException ex) { assertEquals("index=2 length=1", ex.getMessage()); } } @@ -44,7 +44,7 @@ public final class ArrayIndexOutOfBoundsExceptionTest extends TestCase { try { ds[2] = 0.0; fail(); - } catch (Exception ex) { + } catch (ArrayIndexOutOfBoundsException ex) { assertEquals("index=2 length=1", ex.getMessage()); } } @@ -54,7 +54,7 @@ public final class ArrayIndexOutOfBoundsExceptionTest extends TestCase { try { double d = ds[2]; fail(); - } catch (Exception ex) { + } catch (ArrayIndexOutOfBoundsException ex) { assertEquals("index=2 length=1", ex.getMessage()); } } @@ -64,7 +64,7 @@ public final class ArrayIndexOutOfBoundsExceptionTest extends TestCase { try { os[2] = null; fail(); - } catch (Exception ex) { + } catch (ArrayIndexOutOfBoundsException ex) { assertEquals("index=2 length=1", ex.getMessage()); } } @@ -74,7 +74,7 @@ public final class ArrayIndexOutOfBoundsExceptionTest extends TestCase { try { Object o = os[2]; fail(); - } catch (Exception ex) { + } catch (ArrayIndexOutOfBoundsException ex) { assertEquals("index=2 length=1", ex.getMessage()); } } diff --git a/luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java b/luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java new file mode 100644 index 0000000..1b4288e --- /dev/null +++ b/luni/src/test/java/libcore/java/lang/ArrayStoreExceptionTest.java @@ -0,0 +1,33 @@ +/* + * 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.java.lang; + +import junit.framework.TestCase; + +public final class ArrayStoreExceptionTest extends TestCase { + public void testArrayStoreException() throws Exception { + Object[] array = new String[10]; + Object o = new Exception(); + try { + array[0] = o; + fail(); + } catch (ArrayStoreException ex) { + ex.printStackTrace(); + assertEquals("java.lang.Exception cannot be stored in an array of type java.lang.String[]", ex.getMessage()); + } + } +} diff --git a/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java b/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java new file mode 100644 index 0000000..780f620 --- /dev/null +++ b/luni/src/test/java/libcore/java/lang/ClassCastExceptionTest.java @@ -0,0 +1,123 @@ +/* + * 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.java.lang; + +import java.util.EnumMap; +import java.util.EnumSet; +import junit.framework.TestCase; + +public final class ClassCastExceptionTest extends TestCase { + public void testCast() throws Exception { + Object o = new Exception(); + try { + String s = (String) o; + fail(); + } catch (ClassCastException ex) { + assertEquals("java.lang.Exception cannot be cast to java.lang.String", ex.getMessage()); + } + } + + public void testClassCast() throws Exception { + Object o = new Exception(); + try { + String.class.cast(o); + fail(); + } catch (ClassCastException ex) { + assertEquals("java.lang.Exception cannot be cast to java.lang.String", ex.getMessage()); + } + } + + public void testClassAsSubclass() throws Exception { + try { + Exception.class.asSubclass(String.class); + fail(); + } catch (ClassCastException ex) { + assertEquals("java.lang.Exception cannot be cast to java.lang.String", ex.getMessage()); + } + } + + enum E { A, B, C }; + enum F { A, B, C }; + + public void testEnumMapPut() throws Exception { + EnumMap m = new EnumMap(E.class); + try { + m.put(F.A, "world"); + fail(); + } catch (ClassCastException ex) { + ex.printStackTrace(); + assertNotNull(ex.getMessage()); + } + } + + public void testMiniEnumSetAdd() throws Exception { + EnumSet m = EnumSet.noneOf(E.class); + try { + m.add(F.A); + fail(); + } catch (ClassCastException ex) { + ex.printStackTrace(); + assertNotNull(ex.getMessage()); + } + } + + public void testMiniEnumSetAddAll() throws Exception { + EnumSet m = EnumSet.noneOf(E.class); + EnumSet n = EnumSet.allOf(F.class); + try { + m.addAll(n); + fail(); + } catch (ClassCastException ex) { + ex.printStackTrace(); + assertNotNull(ex.getMessage()); + } + } + + enum HugeE { + A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0, S0, T0, U0, V0, W0, X0, Y0, Z0, + A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, K1, L1, M1, N1, O1, P1, Q1, R1, S1, T1, U1, V1, W1, X1, Y1, Z1, + A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2, V2, W2, X2, Y2, Z2, + }; + enum HugeF { + A0, B0, C0, D0, E0, F0, G0, H0, I0, J0, K0, L0, M0, N0, O0, P0, Q0, R0, S0, T0, U0, V0, W0, X0, Y0, Z0, + A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, K1, L1, M1, N1, O1, P1, Q1, R1, S1, T1, U1, V1, W1, X1, Y1, Z1, + A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2, V2, W2, X2, Y2, Z2, + }; + + public void testHugeEnumSetAdd() throws Exception { + EnumSet m = EnumSet.noneOf(HugeE.class); + try { + m.add(HugeF.A0); + fail(); + } catch (ClassCastException ex) { + ex.printStackTrace(); + assertNotNull(ex.getMessage()); + } + } + + public void testHugeEnumSetAddAll() throws Exception { + EnumSet m = EnumSet.noneOf(HugeE.class); + EnumSet n = EnumSet.allOf(HugeF.class); + try { + m.addAll(n); + fail(); + } catch (ClassCastException ex) { + ex.printStackTrace(); + assertNotNull(ex.getMessage()); + } + } +} diff --git a/luni/src/test/java/libcore/java/net/ConcurrentCloseTest.java b/luni/src/test/java/libcore/java/net/ConcurrentCloseTest.java index 5968fdf..726b05a 100644 --- a/luni/src/test/java/libcore/java/net/ConcurrentCloseTest.java +++ b/luni/src/test/java/libcore/java/net/ConcurrentCloseTest.java @@ -28,6 +28,7 @@ import java.nio.channels.SocketChannel; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import tests.net.StuckServer; /** * Test that Socket.close called on another thread interrupts a thread that's blocked doing @@ -47,24 +48,28 @@ public class ConcurrentCloseTest extends junit.framework.TestCase { } public void test_connect() throws Exception { + StuckServer ss = new StuckServer(); Socket s = new Socket(); new Killer(s).start(); try { System.err.println("connect..."); - s.connect(new InetSocketAddress("10.0.0.1", 7)); + s.connect(ss.getLocalSocketAddress()); fail("connect returned!"); } catch (SocketException expected) { assertEquals("Socket closed", expected.getMessage()); + } finally { + ss.close(); } } public void test_connect_nonBlocking() throws Exception { + StuckServer ss = new StuckServer(); SocketChannel s = SocketChannel.open(); new Killer(s.socket()).start(); try { System.err.println("connect (non-blocking)..."); s.configureBlocking(false); - s.connect(new InetSocketAddress("10.0.0.2", 7)); + s.connect(ss.getLocalSocketAddress()); while (!s.finishConnect()) { // Spin like a mad thing! } @@ -76,6 +81,8 @@ public class ConcurrentCloseTest extends junit.framework.TestCase { } catch (ClosedChannelException alsoOkay) { // For now, I'm assuming that we're happy as long as we get any reasonable exception. // It may be that we're supposed to guarantee only one or the other. + } finally { + ss.close(); } } diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java index a1f99e9..1a11bd9 100644 --- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java +++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java @@ -68,6 +68,7 @@ import tests.http.DefaultResponseCache; import tests.http.MockResponse; import tests.http.MockWebServer; import tests.http.RecordedRequest; +import tests.net.StuckServer; public class URLConnectionTest extends junit.framework.TestCase { @@ -1393,27 +1394,16 @@ public class URLConnectionTest extends junit.framework.TestCase { } public void testConnectTimeouts() throws IOException { - // Set a backlog and use it up so that we can expect the - // URLConnection to properly timeout. According to Steven's - // 4.5 "listen function", linux adds 3 to the specified - // backlog, so we need to connect 4 times before it will hang. - ServerSocket serverSocket = new ServerSocket(0, 1); - int serverPort = serverSocket.getLocalPort(); - Socket[] sockets = new Socket[4]; - for (int i = 0; i < sockets.length; i++) { - sockets[i] = new Socket("localhost", serverPort); - } - + StuckServer ss = new StuckServer(); + int serverPort = ss.getLocalPort(); URLConnection urlConnection = new URL("http://localhost:" + serverPort).openConnection(); urlConnection.setConnectTimeout(1000); try { urlConnection.getInputStream(); fail(); } catch (SocketTimeoutException expected) { - } - - for (Socket s : sockets) { - s.close(); + } finally { + ss.close(); } } diff --git a/luni/src/test/java/libcore/java/net/URLTest.java b/luni/src/test/java/libcore/java/net/URLTest.java new file mode 100644 index 0000000..1a2846b --- /dev/null +++ b/luni/src/test/java/libcore/java/net/URLTest.java @@ -0,0 +1,29 @@ +/* + * 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.java.net; + +import java.net.URL; +import junit.framework.TestCase; + +public class URLTest extends TestCase { + // http://code.google.com/p/android/issues/detail?id=12724 + public void testExplicitPort() throws Exception { + URL url = new URL("http://www.google.com:80/example?language[id]=2"); + assertEquals("www.google.com", url.getHost()); + assertEquals(80, url.getPort()); + } +} diff --git a/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java index a4012a8..4da54e6 100644 --- a/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java +++ b/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java @@ -408,12 +408,6 @@ public class OldSimpleDateFormatTest extends junit.framework.TestCase { assertFalse(test.testsFailed); } - public void testDefaultMinimalDaysInFirstWeek() { - Locale.setDefault(Locale.US); - assertEquals(1, new GregorianCalendar().getMinimalDaysInFirstWeek()); - assertEquals(1, new GregorianCalendar().getFirstDayOfWeek()); - } - /** * @tests java.text.SimpleDateFormat#format(java.util.Date) */ diff --git a/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java b/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java index 1f66653..24ecd84 100644 --- a/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java +++ b/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java @@ -27,6 +27,7 @@ import java.util.jar.JarFile; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import junit.framework.TestCase; +import libcore.base.Streams; import static tests.support.Support_Exec.execAndGetOutput; import tests.support.resource.Support_Resources; @@ -113,7 +114,7 @@ public class DalvikExecTest extends TestCase { // Fill in the classes.dex contents, i.e. the Dalvik executable code: // (See below for the detailed source code contents.) - Support_Resources.writeResourceToStream("cts_dalvikExecTest_classes.dex", jarOut); + Streams.copy(Support_Resources.getResourceStream("cts_dalvikExecTest_classes.dex"), jarOut); // Now add a resource file: // @@ -168,7 +169,7 @@ public class DalvikExecTest extends TestCase { // Fill in the classes.dex contents, i.e. the Dalvik executable code: // (See below for the detailed source code contents.) - Support_Resources.writeResourceToStream("cts_dalvikExecTest_classes.dex", jarOut); + Streams.copy(Support_Resources.getResourceStream("cts_dalvikExecTest_classes.dex"), jarOut); // Now add a resource file: // diff --git a/luni/src/test/java/libcore/java/util/zip/GzipTest.java b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java index f7e03dc..a28fae5 100644 --- a/luni/src/test/java/libcore/java/util/zip/GzipTest.java +++ b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java @@ -27,23 +27,25 @@ import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import junit.framework.TestCase; -public final class GzipTest extends TestCase { - - public void testRoundtripShortMessage() throws IOException { - byte[] data = gzip(("Hello World").getBytes("UTF-8")); - assertTrue(Arrays.equals(data, gunzip(gzip(data)))); +public final class GZIPInputStreamTest extends TestCase { + public void testShortMessage() throws IOException { + byte[] data = new byte[] { + 31, -117, 8, 0, 0, 0, 0, 0, 0, 0, -13, 72, -51, -55, -55, 87, 8, -49, + 47, -54, 73, 1, 0, 86, -79, 23, 74, 11, 0, 0, 0 + }; + assertEquals("Hello World", new String(gunzip(data), "UTF-8")); } - public void testRoundtripLongMessage() throws IOException { + public void testLongMessage() throws IOException { byte[] data = new byte[1024 * 1024]; new Random().nextBytes(data); - assertTrue(Arrays.equals(data, gunzip(gzip(data)))); + assertTrue(Arrays.equals(data, gunzip(GZIPOutputStreamTest.gzip(data)))); } /** http://b/3042574 GzipInputStream.skip() causing CRC failures */ public void testSkip() throws IOException { byte[] data = new byte[1024 * 1024]; - byte[] gzipped = gzip(data); + byte[] gzipped = GZIPOutputStreamTest.gzip(data); GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(gzipped)); long totalSkipped = 0; @@ -53,19 +55,11 @@ public final class GzipTest extends TestCase { totalSkipped += count; } while (count > 0); - assertEquals(data.length, totalSkipped); + in.close(); } - public byte[] gzip(byte[] bytes) throws IOException { - ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - OutputStream gzippedOut = new GZIPOutputStream(bytesOut); - gzippedOut.write(bytes); - gzippedOut.close(); - return bytesOut.toByteArray(); - } - - public byte[] gunzip(byte[] bytes) throws IOException { + public static byte[] gunzip(byte[] bytes) throws IOException { InputStream in = new GZIPInputStream(new ByteArrayInputStream(bytes)); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; @@ -73,6 +67,7 @@ public final class GzipTest extends TestCase { while ((count = in.read(buffer)) != -1) { out.write(buffer, 0, count); } + in.close(); return out.toByteArray(); } } diff --git a/luni/src/test/java/libcore/java/util/zip/GZIPOutputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/GZIPOutputStreamTest.java new file mode 100644 index 0000000..a61880f --- /dev/null +++ b/luni/src/test/java/libcore/java/util/zip/GZIPOutputStreamTest.java @@ -0,0 +1,50 @@ +/* + * 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.java.util.zip; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Random; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; +import junit.framework.TestCase; + +public final class GZIPOutputStreamTest extends TestCase { + public void testShortMessage() throws IOException { + byte[] data = gzip(("Hello World").getBytes("UTF-8")); + assertEquals("[31, -117, 8, 0, 0, 0, 0, 0, 0, 0, -13, 72, -51, -55, -55, 87, 8, -49, " + + "47, -54, 73, 1, 0, 86, -79, 23, 74, 11, 0, 0, 0]", Arrays.toString(data)); + } + + public void testLongMessage() throws IOException { + byte[] data = new byte[1024 * 1024]; + new Random().nextBytes(data); + assertTrue(Arrays.equals(data, GZIPInputStreamTest.gunzip(gzip(data)))); + } + + public static byte[] gzip(byte[] bytes) throws IOException { + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + OutputStream gzippedOut = new GZIPOutputStream(bytesOut); + gzippedOut.write(bytes); + gzippedOut.close(); + return bytesOut.toByteArray(); + } +} diff --git a/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java new file mode 100644 index 0000000..cb98322 --- /dev/null +++ b/luni/src/test/java/libcore/java/util/zip/ZipInputStreamTest.java @@ -0,0 +1,62 @@ +/* + * 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.java.util.zip; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Random; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; +import junit.framework.TestCase; + +public final class ZipInputStreamTest extends TestCase { + public void testShortMessage() throws IOException { + byte[] data = "Hello World".getBytes("UTF-8"); + byte[] zipped = ZipOutputStreamTest.zip("short", data); + assertEquals(Arrays.toString(data), Arrays.toString(unzip("short", zipped))); + } + + public void testLongMessage() throws IOException { + byte[] data = new byte[1024 * 1024]; + new Random().nextBytes(data); + assertTrue(Arrays.equals(data, unzip("r", ZipOutputStreamTest.zip("r", data)))); + } + + public static byte[] unzip(String name, byte[] bytes) throws IOException { + ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(bytes)); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + ZipEntry entry = in.getNextEntry(); + assertEquals(name, entry.getName()); + + byte[] buffer = new byte[1024]; + int count; + while ((count = in.read(buffer)) != -1) { + out.write(buffer, 0, count); + } + + assertNull(in.getNextEntry()); // There's only one entry in the Zip files we create. + + in.close(); + return out.toByteArray(); + } +} diff --git a/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java new file mode 100644 index 0000000..e7c518f --- /dev/null +++ b/luni/src/test/java/libcore/java/util/zip/ZipOutputStreamTest.java @@ -0,0 +1,63 @@ +/* + * 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.java.util.zip; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Random; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; +import junit.framework.TestCase; + +public final class ZipOutputStreamTest extends TestCase { + public void testShortMessage() throws IOException { + byte[] data = "Hello World".getBytes("UTF-8"); + byte[] zipped = zip("short", data); + assertEquals(Arrays.toString(data), Arrays.toString(ZipInputStreamTest.unzip("short", zipped))); + } + + // http://b/3181430 --- a sign-extension bug on CRCs with the top bit set. + public void test3181430() throws IOException { + byte[] data = new byte[1]; // CRC32({ 0 }) == 0xd202ef8d + byte[] zipped = zip("z", data); + assertEquals(Arrays.toString(data), Arrays.toString(ZipInputStreamTest.unzip("z", zipped))); + } + + public void testLongMessage() throws IOException { + byte[] data = new byte[1024 * 1024]; + new Random().nextBytes(data); + assertTrue(Arrays.equals(data, ZipInputStreamTest.unzip("r", zip("r", data)))); + } + + public static byte[] zip(String name, byte[] bytes) throws IOException { + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ZipOutputStream zippedOut = new ZipOutputStream(bytesOut); + + ZipEntry entry = new ZipEntry(name); + zippedOut.putNextEntry(entry); + zippedOut.write(bytes); + zippedOut.closeEntry(); + + zippedOut.close(); + return bytesOut.toByteArray(); + } +} diff --git a/luni/src/test/java/libcore/xml/ExpatPullParserDtdTest.java b/luni/src/test/java/libcore/xml/ExpatPullParserDtdTest.java new file mode 100644 index 0000000..5e62310 --- /dev/null +++ b/luni/src/test/java/libcore/xml/ExpatPullParserDtdTest.java @@ -0,0 +1,26 @@ +/* + * 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 org.apache.harmony.xml.ExpatPullParser; +import org.xmlpull.v1.XmlPullParser; + +public class ExpatPullParserDtdTest extends PullParserDtdTest { + @Override XmlPullParser newPullParser() { + return new ExpatPullParser(); + } +} diff --git a/luni/src/test/java/org/apache/harmony/xml/ExpatPullParserTest.java b/luni/src/test/java/libcore/xml/ExpatPullParserTest.java index 71e2671..5d1725d 100644 --- a/luni/src/test/java/org/apache/harmony/xml/ExpatPullParserTest.java +++ b/luni/src/test/java/libcore/xml/ExpatPullParserTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.apache.harmony.xml; +package libcore.xml; +import org.apache.harmony.xml.ExpatPullParser; import org.xmlpull.v1.XmlPullParser; public final class ExpatPullParserTest extends PullParserTest { @Override XmlPullParser newPullParser() { - ExpatPullParser parser = new ExpatPullParser(); - return parser; + return new ExpatPullParser(); } } diff --git a/luni/src/test/java/org/apache/harmony/xml/ExpatSaxParserTest.java b/luni/src/test/java/libcore/xml/ExpatSaxParserTest.java index 51804f2..2db8e82 100644 --- a/luni/src/test/java/org/apache/harmony/xml/ExpatSaxParserTest.java +++ b/luni/src/test/java/libcore/xml/ExpatSaxParserTest.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.apache.harmony.xml; +package libcore.xml; import junit.framework.Assert; import junit.framework.TestCase; +import org.apache.harmony.xml.ExpatReader; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; @@ -45,6 +46,19 @@ public class ExpatSaxParserTest extends TestCase { private static final String SNIPPET = "<dagny dad=\"bob\">hello</dagny>"; + public void testGlobalReferenceTableOverflow() throws Exception { + // We used to use a JNI global reference per interned string. + // Framework apps have a limit of 2000 JNI global references per VM. + StringBuilder xml = new StringBuilder(); + xml.append("<root>"); + for (int i = 0; i < 4000; ++i) { + xml.append("<tag" + i + ">"); + xml.append("</tag" + i + ">"); + } + xml.append("</root>"); + parse(xml.toString(), new DefaultHandler()); + } + public void testExceptions() { // From startElement(). ContentHandler contentHandler = new DefaultHandler() { @@ -675,8 +689,7 @@ public class ExpatSaxParserTest extends TestCase { XMLReader reader = new ExpatReader(); reader.setContentHandler(contentHandler); reader.parse(new InputSource(new StringReader(xml))); - } - catch (IOException e) { + } catch (IOException e) { throw new AssertionError(e); } } diff --git a/luni/src/test/java/org/apache/harmony/xml/JaxenXPathTestSuite.java b/luni/src/test/java/libcore/xml/JaxenXPathTestSuite.java index 17f0341..eb790aa 100644 --- a/luni/src/test/java/org/apache/harmony/xml/JaxenXPathTestSuite.java +++ b/luni/src/test/java/libcore/xml/JaxenXPathTestSuite.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.apache.harmony.xml; +package libcore.xml; import junit.framework.AssertionFailedError; import junit.framework.Test; diff --git a/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java b/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java new file mode 100644 index 0000000..3175b37 --- /dev/null +++ b/luni/src/test/java/libcore/xml/KxmlPullParserDtdTest.java @@ -0,0 +1,29 @@ +/* + * 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 org.kxml2.io.KXmlParser; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +public class KxmlPullParserDtdTest extends PullParserDtdTest { + @Override XmlPullParser newPullParser() throws XmlPullParserException { + KXmlParser result = new KXmlParser(); + result.setFeature(XmlPullParser.FEATURE_PROCESS_DOCDECL, true); + return result; + } +} diff --git a/luni/src/test/java/org/apache/harmony/xml/KxmlPullParserTest.java b/luni/src/test/java/libcore/xml/KxmlPullParserTest.java index 3603d89..71f25e9 100644 --- a/luni/src/test/java/org/apache/harmony/xml/KxmlPullParserTest.java +++ b/luni/src/test/java/libcore/xml/KxmlPullParserTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.apache.harmony.xml; +package libcore.xml; import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; diff --git a/luni/src/test/java/org/apache/harmony/xml/NamespacedAttributesLookupTest.java b/luni/src/test/java/libcore/xml/NamespacedAttributesLookupTest.java index 4f58262..cf12000 100644 --- a/luni/src/test/java/org/apache/harmony/xml/NamespacedAttributesLookupTest.java +++ b/luni/src/test/java/libcore/xml/NamespacedAttributesLookupTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.apache.harmony.xml; +package libcore.xml; import junit.framework.TestCase; import org.xml.sax.Attributes; diff --git a/luni/src/test/java/libcore/xml/PullParserDtdTest.java b/luni/src/test/java/libcore/xml/PullParserDtdTest.java new file mode 100644 index 0000000..0101d7b --- /dev/null +++ b/luni/src/test/java/libcore/xml/PullParserDtdTest.java @@ -0,0 +1,512 @@ +/* + * 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.IOException; +import java.io.StringReader; +import java.util.Arrays; +import junit.framework.TestCase; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +/** + * Test doctype handling in pull parsers. + */ +public abstract class PullParserDtdTest extends TestCase { + + private static final int READ_BUFFER_SIZE = 8192; + + /** + * Android's Expat pull parser permits parameter entities to be declared, + * but it doesn't permit such entities to be used. + */ + public void testDeclaringParameterEntities() throws Exception { + String xml = "<!DOCTYPE foo [" + + " <!ENTITY % a \"android\">" + + "]><foo></foo>"; + XmlPullParser parser = newPullParser(xml); + while (parser.next() != XmlPullParser.END_DOCUMENT) { + } + } + + public void testUsingParameterEntitiesInDtds() throws Exception { + String xml = "<!DOCTYPE foo [" + + " <!ENTITY % a \"android\">" + + " <!ENTITY b \"%a;\">" + + "]><foo></foo>"; + XmlPullParser parser = newPullParser(xml); + assertParseFailure(parser); + } + + public void testUsingParameterInDocuments() throws Exception { + String xml = "<!DOCTYPE foo [" + + " <!ENTITY % a \"android\">" + + "]><foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertParseFailure(parser); + } + + public void testGeneralAndParameterEntityWithTheSameName() throws Exception { + String xml = "<!DOCTYPE foo [" + + " <!ENTITY a \"aaa\">" + + " <!ENTITY % a \"bbb\">" + + "]><foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals("aaa", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testInternalEntities() throws Exception { + String xml = "<!DOCTYPE foo [" + + " <!ENTITY a \"android\">" + + "]><foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals("android", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testExternalDtdIsSilentlyIgnored() throws Exception { + String xml = "<!DOCTYPE foo SYSTEM \"http://127.0.0.1:1/no-such-file.dtd\"><foo></foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testExternalAndInternalDtd() throws Exception { + String xml = "<!DOCTYPE foo SYSTEM \"http://127.0.0.1:1/no-such-file.dtd\" [" + + " <!ENTITY a \"android\">" + + "]><foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals("android", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testInternalEntitiesAreParsed() throws Exception { + String xml = "<!DOCTYPE foo [" + + " <!ENTITY a \"&#65;\">" // & expands to '&', A expands to 'A' + + "]><foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals("A", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testFoolishlyRecursiveInternalEntities() throws Exception { + String xml = "<!DOCTYPE foo [" + + " <!ENTITY a \"&#38;#38;#38;\">" // expand & to '&' only twice + + "]><foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals("&#38;", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + /** + * Test that the output of {@code &} is parsed, but {@code &} isn't. + * http://www.w3.org/TR/2008/REC-xml-20081126/#sec-entexpand + */ + public void testExpansionOfEntityAndCharacterReferences() throws Exception { + String xml = "<!DOCTYPE foo [" + + "<!ENTITY example \"<p>An ampersand (&#38;) may be escaped\n" + + "numerically (&#38;#38;) or with a general entity\n" + + "(&amp;).</p>\" >" + + "]><foo>&example;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("p", parser.getName()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals("An ampersand (&) may be escaped\n" + + "numerically (&) or with a general entity\n" + + "(&).", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals("p", parser.getName()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testGeneralEntitiesAreStoredUnresolved() throws Exception { + String xml = "<!DOCTYPE foo [" + + "<!ENTITY b \"&a;\" >" + + "<!ENTITY a \"android\" >" + + "]><foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals("android", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + /** + * Android's Expat replaces external entities with the empty string. + */ + public void testUsingExternalEntities() throws Exception { + String xml = "<!DOCTYPE foo [" + + " <!ENTITY a SYSTEM \"http://localhost:1/no-such-file.xml\">" + + "]><foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + // &a; is dropped! + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + /** + * Android's ExpatPullParser replaces missing entities with the empty string + * when an external DTD is declared. + */ + public void testExternalDtdAndMissingEntity() throws Exception { + String xml = "<!DOCTYPE foo SYSTEM \"http://127.0.0.1:1/no-such-file.dtd\">" + + "<foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + + public void testExternalIdIsCaseSensitive() throws Exception { + // The spec requires 'SYSTEM' in upper case + String xml = "<!DOCTYPE foo [" + + " <!ENTITY a system \"http://localhost:1/no-such-file.xml\">" + + "]><foo/>"; + XmlPullParser parser = newPullParser(xml); + assertParseFailure(parser); + } + + /** + * Use a DTD to specify that {@code <foo>} only contains {@code <bar>} tags. + * Validating parsers react to this by dropping whitespace between the two + * tags. + */ + public void testDtdDoesNotInformIgnorableWhitespace() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ELEMENT foo (bar)*>\n" + + " <!ELEMENT bar ANY>\n" + + "]>" + + "<foo> \n <bar></bar> \t </foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals(" \n ", parser.getText()); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("bar", parser.getName()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals("bar", parser.getName()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals(" \t ", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testEmptyDoesNotInformIgnorableWhitespace() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ELEMENT foo EMPTY>\n" + + "]>" + + "<foo> \n </foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals(" \n ", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + /** + * Test that the parser doesn't expand the entity attributes. + */ + public void testAttributeOfTypeEntity() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ENTITY a \"android\">" + + " <!ELEMENT foo ANY>\n" + + " <!ATTLIST foo\n" + + " bar ENTITY #IMPLIED>" + + "]>" + + "<foo bar=\"a\"></foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals("a", parser.getAttributeValue(null, "bar")); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testTagStructureNotValidated() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ELEMENT foo (bar)*>\n" + + " <!ELEMENT bar ANY>\n" + + " <!ELEMENT baz ANY>\n" + + "]>" + + "<foo><bar/><bar/><baz/></foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("bar", parser.getName()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("bar", parser.getName()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("baz", parser.getName()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testAttributeDefaultValues() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ATTLIST bar\n" + + " baz (a|b|c) \"c\">" + + "]>" + + "<foo>" + + "<bar/>" + + "<bar baz=\"a\"/>" + + "</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("bar", parser.getName()); + assertEquals("c", parser.getAttributeValue(null, "baz")); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("bar", parser.getName()); + assertEquals("a", parser.getAttributeValue(null, "baz")); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testAttributeDefaultValueEntitiesExpanded() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ENTITY g \"ghi\">" + + " <!ELEMENT foo ANY>\n" + + " <!ATTLIST foo\n" + + " bar CDATA \"abc & def &g; jk\">" + + "]>" + + "<foo></foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals("abc & def ghi jk", parser.getAttributeValue(null, "bar")); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testAttributeDefaultValuesAndNamespaces() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ATTLIST foo\n" + + " bar:a CDATA \"android\">" + + "]>" + + "<foo xmlns:bar='http://bar'></foo>"; + XmlPullParser parser = newPullParser(xml); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + // In Expat, namespaces don't apply to default attributes + int index = indexOfAttributeWithName(parser, "bar:a"); + assertEquals("", parser.getAttributeNamespace(index)); + assertEquals("bar:a", parser.getAttributeName(index)); + assertEquals("android", parser.getAttributeValue(index)); + assertEquals("CDATA", parser.getAttributeType(index)); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + private int indexOfAttributeWithName(XmlPullParser parser, String name) { + for (int i = 0; i < parser.getAttributeCount(); i++) { + if (parser.getAttributeName(i).equals(name)) { + return i; + } + } + return -1; + } + + public void testAttributeEntitiesExpandedEagerly() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ELEMENT foo ANY>\n" + + " <!ATTLIST foo\n" + + " bar CDATA \"abc & def &g; jk\">" + + " <!ENTITY g \"ghi\">" + + "]>" + + "<foo></foo>"; + XmlPullParser parser = newPullParser(xml); + assertParseFailure(parser); + } + + public void testRequiredAttributesOmitted() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ELEMENT foo ANY>\n" + + " <!ATTLIST foo\n" + + " bar (a|b|c) #REQUIRED>" + + "]>" + + "<foo></foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals(null, parser.getAttributeValue(null, "bar")); + assertEquals(XmlPullParser.END_TAG, parser.next()); + } + + public void testFixedAttributesWithConflictingValues() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!ELEMENT foo ANY>\n" + + " <!ATTLIST foo\n" + + " bar (a|b|c) #FIXED \"c\">" + + "]>" + + "<foo bar=\"a\"></foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals("a", parser.getAttributeValue(null, "bar")); + assertEquals(XmlPullParser.END_TAG, parser.next()); + } + + public void testParsingNotations() throws Exception { + String xml = "<!DOCTYPE foo [\n" + + " <!NOTATION type-a PUBLIC \"application/a\"> \n" + + " <!NOTATION type-b PUBLIC \"image/b\">\n" + + " <!NOTATION type-c PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n" + + " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> \n" + + " <!ENTITY file SYSTEM \"d.xml\">\n" + + " <!ENTITY fileWithNdata SYSTEM \"e.bin\" NDATA type-b>\n" + + "]>" + + "<foo type=\"type-a\"/>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + } + + public void testCommentsInDoctype() throws Exception { + String xml = "<!DOCTYPE foo [" + + " <!-- ' -->" + + "]><foo>android</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals("android", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testDoctypeNameOnly() throws Exception { + String xml = "<!DOCTYPE foo><foo></foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals("foo", parser.getName()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testVeryLongEntities() throws Exception { + String a = repeat('a', READ_BUFFER_SIZE + 1); + String b = repeat('b', READ_BUFFER_SIZE + 1); + String c = repeat('c', READ_BUFFER_SIZE + 1); + + String xml = "<!DOCTYPE foo [\n" + + " <!ENTITY " + a + " \"d &" + b + "; e\">" + + " <!ENTITY " + b + " \"f " + c + " g\">" + + "]>" + + "<foo>h &" + a + "; i</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.TEXT, parser.next()); + assertEquals("h d f " + c + " g e i", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + public void testManuallyRegisteredEntitiesWithDoctypeParsing() throws Exception { + String xml = "<foo>&a;</foo>"; + XmlPullParser parser = newPullParser(xml); + try { + parser.defineEntityReplacementText("a", "android"); + fail(); + } catch (UnsupportedOperationException expected) { + } catch (IllegalStateException expected) { + } + } + + /** + * In honeycomb, KxmlParser's DTD handling was improved but no longer + * supports returning the full DTD text. http://b/3241492 + */ + public void testDoctypeWithNextToken() throws Exception { + String xml = "<!DOCTYPE foo [<!ENTITY bb \"bar baz\">]><foo>a&bb;c</foo>"; + XmlPullParser parser = newPullParser(xml); + assertEquals(XmlPullParser.DOCDECL, parser.nextToken()); + assertEquals(" foo [<!ENTITY bb \"bar baz\">]", parser.getText()); + assertNull(parser.getName()); + assertEquals(XmlPullParser.START_TAG, parser.nextToken()); + assertEquals(XmlPullParser.TEXT, parser.nextToken()); + assertEquals("a", parser.getText()); + assertEquals(XmlPullParser.ENTITY_REF, parser.nextToken()); + assertEquals("bb", parser.getName()); + assertEquals("bar baz", parser.getText()); + assertEquals(XmlPullParser.TEXT, parser.nextToken()); + assertEquals("c", parser.getText()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + assertEquals(XmlPullParser.END_DOCUMENT, parser.next()); + } + + private void assertParseFailure(XmlPullParser parser) throws IOException { + try { + while (parser.next() != XmlPullParser.END_DOCUMENT) { + } + fail(); + } catch (XmlPullParserException expected) { + } + } + + private String repeat(char c, int length) { + char[] chars = new char[length]; + Arrays.fill(chars, c); + return new String(chars); + } + + private XmlPullParser newPullParser(String xml) throws XmlPullParserException { + XmlPullParser result = newPullParser(); + result.setInput(new StringReader(xml)); + return result; + } + + /** + * Creates a new pull parser. + */ + abstract XmlPullParser newPullParser() throws XmlPullParserException; +} diff --git a/luni/src/test/java/libcore/xml/PullParserTest.java b/luni/src/test/java/libcore/xml/PullParserTest.java new file mode 100644 index 0000000..2862de0 --- /dev/null +++ b/luni/src/test/java/libcore/xml/PullParserTest.java @@ -0,0 +1,725 @@ +/* + * 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.IOException; +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("<input checked></input>")); + 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("<input checked=true></input>")); + 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("<foo bar='A&W'>mac&cheese</foo>")); + 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( + "<foo:a xmlns:foo='http://foo' xmlns:bar='http://bar'><bar:b/></foo:a>")); + 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( + "<foo:a xmlns:foo='http://foo' xmlns:bar='http://bar'><bar:b/></foo:a>")); + testNamespace(parser); + } + + private void testNamespace(XmlPullParser parser) throws XmlPullParserException, IOException { + 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("<foo>A</foo>")); + 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 { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader( + "<foo>� &#-2147483648;</foo>")); + assertParseFailure(parser); + } + + public void testNumericEntitiesLargerThanInt() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader( + "<foo>�</foo>")); + assertParseFailure(parser); + } + + public void testCharacterReferenceOfHexUtf16Surrogates() throws Exception { + testCharacterReferenceOfUtf16Surrogates("<foo>𐀀 𐎁 􏿰</foo>"); + } + + public void testCharacterReferenceOfDecimalUtf16Surrogates() throws Exception { + testCharacterReferenceOfUtf16Surrogates("<foo>𐀀 𐎁 􏿰</foo>"); + } + + 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("<foo></foo>")); + 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 { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo>&#;</foo>")); + assertParseFailure(parser); + } + + /** + * Carriage returns followed by line feeds are silently discarded. + */ + public void testCarriageReturnLineFeed() throws Exception { + testLineEndings("\r\n<foo\r\na='b\r\nc'\r\n>d\r\ne</foo\r\n>\r\n"); + } + + /** + * Lone carriage returns are treated like newlines. + */ + public void testLoneCarriageReturn() throws Exception { + testLineEndings("\r<foo\ra='b\rc'\r>d\re</foo\r>\r"); + } + + public void testLoneNewLine() throws Exception { + testLineEndings("\n<foo\na='b\nc'\n>d\ne</foo\n>\n"); + } + + private void testLineEndings(String xml) throws XmlPullParserException, IOException { + 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( + "<?xml version='1.0' encoding='UTF-8' standalone='no'?><foo/>")); + 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 { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader( + "<?xml version='1.0' encoding='UTF-8' standalone='no' a='b'?><foo/>")); + try { + parser.nextToken(); + fail(); + } catch (XmlPullParserException expected) { + } + } + + public void testCustomEntitiesUsingNext() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader( + "<foo a='cd&aaaaaaaaaa;ef'>wx&aaaaaaaaaa;yz</foo>")); + 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( + "<foo a='cd&aaaaaaaaaa;ef'>wx&aaaaaaaaaa;yz</foo>")); + 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( + "<foo a='&a;'>&a;</foo>")); + 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 { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo>&aaa;</foo>")); + assertParseFailure(parser); + } + + public void testMissingEntitiesWithRelaxed() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); + parser.setInput(new StringReader("<foo>&aaa;</foo>")); + 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 XmlPullParserException, IOException { + parser.setInput(new StringReader("<foo>&aaa;</foo>")); + 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("<foo bar=\"&\"></foo>")); + assertEquals(XmlPullParser.START_TAG, parser.nextToken()); + assertEquals("foo", parser.getName()); + assertEquals("&", parser.getAttributeValue(null, "bar")); + } + + public void testMissingEntitiesInAttributesUsingNext() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo b='&aaa;'></foo>")); + assertParseFailure(parser); + } + + public void testMissingEntitiesInAttributesUsingNextWithRelaxed() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo b='&aaa;'></foo>")); + 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("<foo b='&aaa;'></foo>")); + testMissingEntitiesInAttributesUsingNextToken(parser); + } + + public void testMissingEntitiesInAttributesUsingNextTokenWithRelaxed() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo b='&aaa;'></foo>")); + parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true); + testMissingEntitiesInAttributesUsingNextToken(parser); + } + + private void testMissingEntitiesInAttributesUsingNextToken(XmlPullParser parser) + throws IOException, XmlPullParserException { + 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("<foo>></foo>")); + 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("<foo a='>'></foo>")); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(">", parser.getAttributeValue(0)); + } + + public void testLessThanInText() throws Exception{ + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo><</foo>")); + assertParseFailure(parser); + } + + public void testLessThanInAttribute() throws Exception{ + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo a='<'></foo>")); + assertParseFailure(parser); + } + + public void testQuotesInAttribute() throws Exception{ + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo a='\"' b=\"'\"></foo>")); + 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("<foo>\" '</foo>")); + 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("<foo a=']]>'></foo>")); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals("]]>", parser.getAttributeValue(0)); + } + + public void testCdataDelimiterInText() throws Exception{ + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo>]]></foo>")); + assertParseFailure(parser); + } + + public void testUnexpectedEof() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo><![C")); + assertParseFailure(parser); + } + + public void testUnexpectedSequence() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo><![Cdata[bar]]></foo>")); + assertParseFailure(parser); + } + + public void testThreeDashCommentDelimiter() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo><!--a---></foo>")); + assertParseFailure(parser); + } + + public void testTwoDashesInComment() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo><!-- -- --></foo>")); + assertParseFailure(parser); + } + + public void testEmptyComment() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo><!----></foo>")); + 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("<foo>]]]]]]]]]]]]]]]]]]]]]]]</foo>")); + 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("<foo>ab<!-- comment! -->cd</foo>")); + 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("<foo>ab<!-- comment! -->cd</foo>")); + 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("<foo>ab<![CDATA[cdef]]gh&i]]>jk</foo>")); + 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("<foo>ab<![CDATA[cdef]]gh&i]]>jk</foo>")); + 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("<foo>]]></foo>")); + 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("<foo>ab<?cd efg hij?>kl</foo>")); + 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("<foo>ab<?cd efg hij?>kl</foo>")); + 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 <foo> \n </foo> \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" + + " <foo><bar a='\n" + + "' b='cde'></bar\n" + + "><!--\n" + + "\n" + + "--><baz/>fg\n" + + "</foo>")); + 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("<foo>∅</foo>")); + 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("<foo>∅</foo>")); + 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("<foo><![CDATA[]]></foo>")); + assertEquals(XmlPullParser.START_TAG, parser.next()); + assertEquals(XmlPullParser.END_TAG, parser.next()); + } + + public void testEmptyCdataUsingNextToken() throws Exception { + XmlPullParser parser = newPullParser(); + parser.setInput(new StringReader("<foo><![CDATA[]]></foo>")); + 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 = "<dagny dad=\"bob\">hello</dagny>"; + XmlPullParser parser = newPullParser(); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); + parser.setInput(new StringReader(snippet)); + validate(parser); + } + + public void testParseInputStream() throws Exception { + String snippet = "<dagny dad=\"bob\">hello</dagny>"; + 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 XmlPullParserException, IOException { + 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 testNamespaces() throws Exception { + String xml = "<one xmlns='ns:default' xmlns:n1='ns:1' a='b'>\n" + + " <n1:two c='d' n1:e='f' xmlns:n2='ns:2'>text</n1:two>\n" + + "</one>"; + + 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)); + } + + private void assertParseFailure(XmlPullParser parser) throws IOException { + try { + while (parser.next() != XmlPullParser.END_DOCUMENT) { + } + fail(); + } catch (XmlPullParserException expected) { + } + } + + /** + * Creates a new pull parser. + */ + abstract XmlPullParser newPullParser(); +} diff --git a/luni/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java b/luni/src/test/java/libcore/xml/XsltXPathConformanceTestSuite.java index 8623d58..7bf1980 100644 --- a/luni/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java +++ b/luni/src/test/java/libcore/xml/XsltXPathConformanceTestSuite.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.apache.harmony.xml; +package libcore.xml; import junit.framework.Assert; import junit.framework.AssertionFailedError; diff --git a/luni/src/test/java/org/apache/harmony/xml/PullParserTest.java b/luni/src/test/java/org/apache/harmony/xml/PullParserTest.java deleted file mode 100644 index d6d5370..0000000 --- a/luni/src/test/java/org/apache/harmony/xml/PullParserTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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 org.apache.harmony.xml; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.StringReader; -import junit.framework.TestCase; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -public abstract class PullParserTest extends TestCase { - private static final String SNIPPET = "<dagny dad=\"bob\">hello</dagny>"; - - public void testPullParser() { - try { - XmlPullParser parser = newPullParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); - - // Test reader. - parser.setInput(new StringReader(SNIPPET)); - validate(parser); - - // Test input stream. - parser.setInput(new ByteArrayInputStream(SNIPPET.getBytes()), - "UTF-8"); - validate(parser); - } catch (XmlPullParserException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - static void validate(XmlPullParser parser) - throws XmlPullParserException, IOException { - 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()); - } - - static final String XML = - "<one xmlns='ns:default' xmlns:n1='ns:1' a='b'>\n" - + " <n1:two c='d' n1:e='f' xmlns:n2='ns:2'>text</n1:two>\n" - + "</one>"; - - public void testExpatPullParserNamespaces() throws Exception { - 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)); - } - - /** - * Creates a new pull parser with namespace support. - */ - abstract XmlPullParser newPullParser(); -} diff --git a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java b/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java index 04e2c53..5bcc7ac 100644 --- a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java +++ b/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java @@ -15,22 +15,22 @@ */ package tests.api.javax.xml.parsers; +import dalvik.annotation.KnownFailure; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStream; import java.util.HashMap; import java.util.Vector; - import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - import junit.framework.TestCase; - import org.xml.sax.HandlerBase; import org.xml.sax.InputSource; import org.xml.sax.Parser; @@ -40,18 +40,12 @@ import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.DefaultHandler; - import tests.api.javax.xml.parsers.SAXParserTestSupport.MyDefaultHandler; import tests.api.javax.xml.parsers.SAXParserTestSupport.MyHandler; import tests.api.org.xml.sax.support.BrokenInputStream; import tests.api.org.xml.sax.support.MethodLogger; import tests.api.org.xml.sax.support.MockHandler; import tests.support.resource.Support_Resources; -import dalvik.annotation.KnownFailure; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; @SuppressWarnings("deprecation") @TestTargetClass(SAXParser.class) @@ -454,10 +448,8 @@ public class SAXParserTest extends TestCase { args = {org.xml.sax.InputSource.class, org.xml.sax.helpers.DefaultHandler.class} ) public void test_parseLorg_xml_sax_InputSourceLorg_xml_sax_helpers_DefaultHandler() - throws Exception { - + throws Exception { for(int i = 0; i < list_wf.length; i++) { - HashMap<String, String> hm = new SAXParserTestSupport().readFile( list_out_dh[i].getPath()); MyDefaultHandler dh = new MyDefaultHandler(); @@ -466,15 +458,13 @@ public class SAXParserTest extends TestCase { assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData())); } - for(int i = 0; i < list_nwf.length; i++) { + for (File file : list_nwf) { try { MyDefaultHandler dh = new MyDefaultHandler(); - InputSource is = new InputSource( - new FileInputStream(list_nwf[i])); + InputSource is = new InputSource(new FileInputStream(file)); parser.parse(is, dh); fail("SAXException is not thrown"); - } catch(org.xml.sax.SAXException se) { - //expected + } catch (SAXException expected) { } } @@ -482,23 +472,21 @@ public class SAXParserTest extends TestCase { MyDefaultHandler dh = new MyDefaultHandler(); parser.parse((InputSource) null, dh); fail("java.lang.IllegalArgumentException is not thrown"); - } catch(java.lang.IllegalArgumentException iae) { - //expected + } catch (IllegalArgumentException expected) { } - try { - InputSource is = new InputSource(new FileInputStream(list_wf[0])); - parser.parse(is, (DefaultHandler) null); - } catch(java.lang.IllegalArgumentException iae) { - fail("java.lang.IllegalArgumentException is thrown"); - } + InputSource is = new InputSource(new FileInputStream(list_wf[0])); + parser.parse(is, (DefaultHandler) null); + InputStream in = null; try { - InputSource is = new InputSource(new BrokenInputStream(new FileInputStream(list_wf[0]), 10)); + in = new BrokenInputStream(new FileInputStream(list_wf[0]), 10); + is = new InputSource(in); parser.parse(is, (DefaultHandler) null); fail("IOException expected"); - } catch(IOException e) { - // Expected + } catch(IOException expected) { + } finally { + in.close(); } } @@ -508,35 +496,22 @@ public class SAXParserTest extends TestCase { method = "parse", args = {org.xml.sax.InputSource.class, org.xml.sax.HandlerBase.class} ) - public void testParseInputSourceHandlerBase() { + public void testParseInputSourceHandlerBase() throws Exception { for(int i = 0; i < list_wf.length; i++) { - try { - HashMap<String, String> hm = sp.readFile( - list_out_hb[i].getPath()); - MyHandler dh = new MyHandler(); - InputSource is = new InputSource(new FileInputStream(list_wf[i])); - parser.parse(is, dh); - assertTrue(SAXParserTestSupport.equalsMaps(hm, - dh.createData())); - } catch (IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch (SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); - } + HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath()); + MyHandler dh = new MyHandler(); + InputSource is = new InputSource(new FileInputStream(list_wf[i])); + parser.parse(is, dh); + assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData())); } - for(int i = 0; i < list_nwf.length; i++) { + for (File file : list_nwf) { try { MyHandler dh = new MyHandler(); - InputSource is = new InputSource(new FileInputStream(list_nwf[i])); + InputSource is = new InputSource(new FileInputStream(file)); parser.parse(is, dh); fail("SAXException is not thrown"); - } catch(org.xml.sax.SAXException se) { - //expected - } catch (FileNotFoundException fne) { - fail("Unexpected FileNotFoundException " + fne.toString()); - } catch (IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); + } catch (SAXException expected) { } } @@ -544,67 +519,29 @@ public class SAXParserTest extends TestCase { MyHandler dh = new MyHandler(); parser.parse((InputSource) null, dh); fail("java.lang.IllegalArgumentException is not thrown"); - } catch(java.lang.IllegalArgumentException iae) { - //expected - } catch (IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch(SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); + } catch(IllegalArgumentException expected) { } - try { - InputSource is = new InputSource(new FileInputStream(list_wf[0])); - parser.parse(is, (HandlerBase) null); - } catch(java.lang.IllegalArgumentException iae) { - fail("java.lang.IllegalArgumentException is thrown"); - } catch (FileNotFoundException fne) { - fail("Unexpected FileNotFoundException " + fne.toString()); - } catch(IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch(SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); - } + InputSource is = new InputSource(new FileInputStream(list_wf[0])); + parser.parse(is, (HandlerBase) null); // Reader case - try { - InputSource is = new InputSource(new InputStreamReader( - new FileInputStream(list_wf[0]))); - parser.parse(is, (HandlerBase) null); - } catch(java.lang.IllegalArgumentException iae) { - fail("java.lang.IllegalArgumentException is thrown"); - } catch (FileNotFoundException fne) { - fail("Unexpected FileNotFoundException " + fne.toString()); - } catch(IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch(SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); - } + is = new InputSource(new InputStreamReader(new FileInputStream(list_wf[0]))); + parser.parse(is, (HandlerBase) null); // SystemID case - try { - InputSource is = new InputSource(list_wf[0].toURI().toString()); - parser.parse(is, (HandlerBase) null); - } catch(java.lang.IllegalArgumentException iae) { - fail("java.lang.IllegalArgumentException is thrown"); - } catch (FileNotFoundException fne) { - fail("Unexpected FileNotFoundException " + fne.toString()); - } catch(IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch(SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); - } + is = new InputSource(list_wf[0].toURI().toString()); + parser.parse(is, (HandlerBase) null); // Inject IOException + InputStream in = null; try { - InputStream is = new BrokenInputStream( - new FileInputStream(list_wf[0]), 10); - parser.parse(is, (HandlerBase) null, - SAXParserTestSupport.XML_SYSTEM_ID); + in = new BrokenInputStream(new FileInputStream(list_wf[0]), 10); + parser.parse(in, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID); fail("IOException expected"); - } catch(IOException e) { - // Expected - } catch (Exception e) { - throw new RuntimeException("Unexpected exception", e); + } catch(IOException expected) { + } finally { + in.close(); } } @@ -784,35 +721,22 @@ public class SAXParserTest extends TestCase { method = "parse", args = {java.io.InputStream.class, org.xml.sax.HandlerBase.class} ) - public void testParseInputStreamHandlerBase() { + public void testParseInputStreamHandlerBase() throws Exception { for(int i = 0; i < list_wf.length; i++) { - try { - HashMap<String, String> hm = sp.readFile( - list_out_hb[i].getPath()); - MyHandler dh = new MyHandler(); - InputStream is = new FileInputStream(list_wf[i]); - parser.parse(is, dh); - assertTrue(SAXParserTestSupport.equalsMaps(hm, - dh.createData())); - } catch (IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch (SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); - } + HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath()); + MyHandler dh = new MyHandler(); + InputStream is = new FileInputStream(list_wf[i]); + parser.parse(is, dh); + assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData())); } - for(int i = 0; i < list_nwf.length; i++) { + for (File file : list_nwf) { try { MyHandler dh = new MyHandler(); - InputStream is = new FileInputStream(list_nwf[i]); + InputStream is = new FileInputStream(file); parser.parse(is, dh); fail("SAXException is not thrown"); - } catch(org.xml.sax.SAXException se) { - //expected - } catch (FileNotFoundException fne) { - fail("Unexpected FileNotFoundException " + fne.toString()); - } catch (IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); + } catch (SAXException expected) { } } @@ -820,37 +744,21 @@ public class SAXParserTest extends TestCase { MyHandler dh = new MyHandler(); parser.parse((InputStream) null, dh); fail("java.lang.IllegalArgumentException is not thrown"); - } catch(java.lang.IllegalArgumentException iae) { - //expected - } catch (IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch(SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); + } catch (IllegalArgumentException expected) { } - try { - InputStream is = new FileInputStream(list_wf[0]); - parser.parse(is, (HandlerBase) null); - } catch(java.lang.IllegalArgumentException iae) { - fail("java.lang.IllegalArgumentException is thrown"); - } catch (FileNotFoundException fne) { - fail("Unexpected FileNotFoundException " + fne.toString()); - } catch(IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch(SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); - } + InputStream is = new FileInputStream(list_wf[0]); + parser.parse(is, (HandlerBase) null); // Inject IOException try { - InputStream is = new BrokenInputStream( - new FileInputStream(list_wf[0]), 10); + is = new BrokenInputStream(new FileInputStream(list_wf[0]), 10); parser.parse(is, (HandlerBase) null); fail("IOException expected"); } catch(IOException e) { // Expected - } catch (Exception e) { - throw new RuntimeException("Unexpected exception", e); + } finally { + is.close(); } } @@ -860,76 +768,43 @@ public class SAXParserTest extends TestCase { method = "parse", args = {java.io.InputStream.class, org.xml.sax.HandlerBase.class, java.lang.String.class} ) - public void testParseInputStreamHandlerBaseString() { + public void testParseInputStreamHandlerBaseString() throws Exception { for(int i = 0; i < list_wf.length; i++) { - try { - HashMap<String, String> hm = sp.readFile( - list_out_hb[i].getPath()); - MyHandler dh = new MyHandler(); - InputStream is = new FileInputStream(list_wf[i]); - parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID); - assertTrue(SAXParserTestSupport.equalsMaps(hm, - dh.createData())); - } catch (IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch (SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); - } + HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath()); + MyHandler dh = new MyHandler(); + InputStream is = new FileInputStream(list_wf[i]); + parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID); + assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData())); } - for(int i = 0; i < list_nwf.length; i++) { + for (File file : list_nwf) { try { MyHandler dh = new MyHandler(); - InputStream is = new FileInputStream(list_nwf[i]); + InputStream is = new FileInputStream(file); parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID); fail("SAXException is not thrown"); - } catch(org.xml.sax.SAXException se) { - //expected - } catch (FileNotFoundException fne) { - fail("Unexpected FileNotFoundException " + fne.toString()); - } catch (IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); + } catch (SAXException expected) { } } try { MyHandler dh = new MyHandler(); - parser.parse((InputStream) null, dh, - SAXParserTestSupport.XML_SYSTEM_ID); + parser.parse(null, dh, SAXParserTestSupport.XML_SYSTEM_ID); fail("java.lang.IllegalArgumentException is not thrown"); - } catch(java.lang.IllegalArgumentException iae) { - //expected - } catch (IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch(SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); + } catch(IllegalArgumentException expected) { } - try { - InputStream is = new FileInputStream(list_wf[0]); - parser.parse(is, (HandlerBase) null, - SAXParserTestSupport.XML_SYSTEM_ID); - } catch(java.lang.IllegalArgumentException iae) { - fail("java.lang.IllegalArgumentException is thrown"); - } catch (FileNotFoundException fne) { - fail("Unexpected FileNotFoundException " + fne.toString()); - } catch(IOException ioe) { - fail("Unexpected IOException " + ioe.toString()); - } catch(SAXException sax) { - fail("Unexpected SAXException " + sax.toString()); - } + InputStream is = new FileInputStream(list_wf[0]); + parser.parse(is, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID); // Inject IOException try { - InputStream is = new BrokenInputStream( - new FileInputStream(list_wf[0]), 10); - parser.parse(is, (HandlerBase) null, - SAXParserTestSupport.XML_SYSTEM_ID); + is = new BrokenInputStream(new FileInputStream(list_wf[0]), 10); + parser.parse(is, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID); fail("IOException expected"); - } catch(IOException e) { - // Expected - } catch (Exception e) { - throw new RuntimeException("Unexpected exception", e); + } catch(IOException expected) { + } finally { + is.close(); } } diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java b/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java index 578fb60..8136b86 100644 --- a/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java +++ b/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java @@ -47,4 +47,8 @@ public class BrokenInputStream extends InputStream { return stream.read(); } + @Override + public void close() throws IOException { + stream.close(); + } }
\ No newline at end of file diff --git a/luni/src/test/java/tests/xml/DomTest.java b/luni/src/test/java/tests/xml/DomTest.java index eb3a842..0966c5d 100644 --- a/luni/src/test/java/tests/xml/DomTest.java +++ b/luni/src/test/java/tests/xml/DomTest.java @@ -1385,6 +1385,38 @@ public class DomTest extends TestCase { assertEquals(root.getChildNodes().item(0), current); } + public void testPublicIdAndSystemId() throws Exception { + document = builder.parse(new InputSource(new StringReader( + " <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"" + + " \"http://www.w3.org/TR/html4/strict.dtd\">" + + "<html></html>"))); + doctype = document.getDoctype(); + assertEquals("html", doctype.getName()); + assertEquals("-//W3C//DTD HTML 4.01//EN", doctype.getPublicId()); + assertEquals("http://www.w3.org/TR/html4/strict.dtd", doctype.getSystemId()); + } + + public void testSystemIdOnly() throws Exception { + document = builder.parse(new InputSource(new StringReader( + " <!DOCTYPE html SYSTEM \"http://www.w3.org/TR/html4/strict.dtd\">" + + "<html></html>"))); + doctype = document.getDoctype(); + assertEquals("html", doctype.getName()); + assertNull(doctype.getPublicId()); + assertEquals("http://www.w3.org/TR/html4/strict.dtd", doctype.getSystemId()); + } + + public void testSingleQuotedPublicIdAndSystemId() throws Exception { + document = builder.parse(new InputSource(new StringReader( + " <!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'" + + " 'http://www.w3.org/TR/html4/strict.dtd'>" + + "<html></html>"))); + doctype = document.getDoctype(); + assertEquals("html", doctype.getName()); + assertEquals("-//W3C//DTD HTML 4.01//EN", doctype.getPublicId()); + assertEquals("http://www.w3.org/TR/html4/strict.dtd", doctype.getSystemId()); + } + private class RecordingHandler implements UserDataHandler { final Set<String> calls = new HashSet<String>(); public void handle(short operation, String key, Object data, Node src, Node dst) { |