1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.util; 18 19 import android.test.suitebuilder.annotation.LargeTest; 20 import android.test.suitebuilder.annotation.SmallTest; 21 import android.util.Log; 22 import android.util.Xml; 23 24 import junit.framework.TestCase; 25 26 import org.xmlpull.v1.XmlPullParser; 27 import org.xmlpull.v1.XmlSerializer; 28 29 import java.io.ByteArrayInputStream; 30 import java.io.ByteArrayOutputStream; 31 import java.nio.charset.StandardCharsets; 32 33 /** 34 * Tests for {@link FastXmlSerializer} 35 */ 36 @SmallTest 37 public class FastXmlSerializerTest extends TestCase { 38 private static final String TAG = "FastXmlSerializerTest"; 39 40 private static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH TRUE. 41 42 private static final String ROOT_TAG = "root"; 43 private static final String ATTR = "attr"; 44 testEmptyText()45 public void testEmptyText() throws Exception { 46 final ByteArrayOutputStream stream = new ByteArrayOutputStream(); 47 48 final XmlSerializer out = new FastXmlSerializer(); 49 out.setOutput(stream, "utf-8"); 50 out.startDocument(null, true); 51 out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 52 53 out.startTag(null, "string"); 54 out.attribute(null, "name", "meow"); 55 out.text(""); 56 out.endTag(null, "string"); 57 58 out.endDocument(); 59 60 assertEquals("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 61 + "<string name=\"meow\"></string>\n", stream.toString()); 62 } 63 checkPreserved(String description, String str)64 private boolean checkPreserved(String description, String str) { 65 boolean ok = true; 66 byte[] data; 67 try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) { 68 final XmlSerializer out = new FastXmlSerializer(); 69 out.setOutput(baos, StandardCharsets.UTF_16.name()); 70 out.startDocument(null, true); 71 72 out.startTag(null, ROOT_TAG); 73 out.attribute(null, ATTR, str); 74 out.text(str); 75 out.endTag(null, ROOT_TAG); 76 77 out.endDocument(); 78 baos.flush(); 79 data = baos.toByteArray(); 80 } catch (Exception e) { 81 Log.e(TAG, "Unable to serialize: " + description, e); 82 return false; 83 } 84 85 if (ENABLE_DUMP) { 86 Log.d(TAG, "Dump:"); 87 Log.d(TAG, new String(data)); 88 } 89 90 try (final ByteArrayInputStream baos = new ByteArrayInputStream(data)) { 91 XmlPullParser parser = Xml.newPullParser(); 92 parser.setInput(baos, StandardCharsets.UTF_16.name()); 93 94 int type; 95 String tag = null; 96 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { 97 if (type == XmlPullParser.START_TAG) { 98 tag = parser.getName(); 99 if (ROOT_TAG.equals(tag)) { 100 String read = parser.getAttributeValue(null, ATTR); 101 if (!str.equals(read)) { 102 Log.e(TAG, "Attribute not preserved: " + description 103 + " input=\"" + str + "\", but read=\"" + read + "\""); 104 ok = false; 105 } 106 } 107 } 108 if (type == XmlPullParser.TEXT && ROOT_TAG.equals(tag)) { 109 String read = parser.getText(); 110 if (!str.equals(parser.getText())) { 111 Log.e(TAG, "Text not preserved: " + description 112 + " input=\"" + str + "\", but read=\"" + read + "\""); 113 ok = false; 114 } 115 } 116 } 117 } catch (Exception e) { 118 Log.e(TAG, "Unable to parse: " + description, e); 119 return false; 120 } 121 return ok; 122 } 123 check(String description, String str)124 private boolean check(String description, String str) throws Exception { 125 boolean ok = false; 126 ok |= checkPreserved(description, str); 127 ok |= checkPreserved(description + " wrapped with spaces" ," " + str + " "); 128 return ok; 129 } 130 131 @LargeTest testAllCharacters()132 public void testAllCharacters() throws Exception { 133 boolean ok = true; 134 for (int i = 0; i < 0xffff; i++) { 135 if (0xd800 <= i && i <= 0xdfff) { 136 // Surrogate pair characters. 137 continue; 138 } 139 ok &= check("char: " + i, String.valueOf((char) i)); 140 } 141 // Dangling surrogate pairs. We can't preserve them. 142 assertFalse(check("+ud800", "\ud800")); 143 assertFalse(check("+udc00", "\udc00")); 144 145 for (int i = 0xd800; i < 0xdc00; i ++) { 146 for (int j = 0xdc00; j < 0xe000; j++) { 147 ok &= check("char: " + i, String.valueOf((char) i) + String.valueOf((char) j)); 148 } 149 } 150 assertTrue("Some tests failed. See logcat for details.", ok); 151 } 152 } 153