1 /* 2 * Copyright (C) 2014 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.exchange.adapter; 18 19 import android.test.AndroidTestCase; 20 import android.test.suitebuilder.annotation.SmallTest; 21 import android.text.TextUtils; 22 23 import java.io.ByteArrayInputStream; 24 import java.io.InputStream; 25 import java.io.IOException; 26 import java.util.Deque; 27 import java.util.ArrayDeque; 28 import java.util.Arrays; 29 30 @SmallTest 31 public class ParserTest extends AndroidTestCase { 32 public class TestParser extends Parser { 33 private Deque<Object> mExpectedData; 34 35 public TestParser(InputStream in, Object[] expectedData) throws IOException{ 36 super(in); 37 setDebug(true); 38 mExpectedData = expectedData == null ? null 39 : new ArrayDeque<Object>(Arrays.asList(expectedData)); 40 } 41 42 @Override 43 public boolean parse() throws IOException { 44 int tag; 45 while((tag = nextTag(START_DOCUMENT)) != END_DOCUMENT) { 46 if (tag == 0x0B) { 47 final String strVal = getValue(); 48 if (mExpectedData != null) { 49 final String expectedStrVal = (String) mExpectedData.removeFirst(); 50 assertEquals(expectedStrVal, strVal); 51 } 52 } else if (tag == 0x0C) { 53 final int intVal = getValueInt(); 54 if (mExpectedData != null) { 55 final Integer expectedIntVal = (Integer) mExpectedData.removeFirst(); 56 assertEquals(expectedIntVal.intValue(), intVal); 57 } 58 } else if (tag == 0x0D) { 59 final byte[] bytes = getValueBytes(); 60 if (mExpectedData != null) { 61 final String expectedHexStr = stripString((String) mExpectedData.removeFirst()); 62 final String hexStr = byteArrayToHexString(bytes); 63 assertEquals(expectedHexStr, hexStr); 64 } 65 } 66 } 67 return true; 68 } 69 } 70 71 final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); 72 private static String byteArrayToHexString(byte[] bytes) { 73 char[] hexChars = new char[bytes.length * 2]; 74 for ( int j = 0; j < bytes.length; j++ ) { 75 int v = bytes[j] & 0xFF; 76 hexChars[j * 2] = hexArray[v >>> 4]; 77 hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 78 } 79 return new String(hexChars); 80 } 81 82 private static String stripString(String str) { 83 return TextUtils.join("", str.split(" ")); 84 } 85 86 private static byte[] hexStringToByteArray(String hexStr) { 87 final String s = TextUtils.join("", hexStr.split(" ")); 88 final int len = s.length(); 89 final byte[] data = new byte[len / 2]; 90 for (int i = 0; i < len; i += 2) { 91 data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 92 + Character.digit(s.charAt(i+1), 16)); 93 } 94 return data; 95 } 96 97 private static InputStream getTestInputStream(final String hexStr) { 98 final byte[] byteArray = hexStringToByteArray(hexStr); 99 return new ByteArrayInputStream(byteArray); 100 } 101 102 private void testParserHelper(String wbxmlStr) throws Exception { 103 testParserHelper(wbxmlStr, null); 104 } 105 106 private void testParserHelper(String wbxmlStr, Object[] expectedData) throws Exception { 107 final Parser parser = new TestParser(getTestInputStream(wbxmlStr), expectedData); 108 parser.parse(); 109 } 110 111 @SmallTest 112 public void testUnsupportedWbxmlTag() throws Exception { 113 // Test parser with unsupported Wbxml tag (EXT_2 = 0xC2) 114 final String unsupportedWbxmlTag = "03 01 6A 00 45 5F C2 05 11 22 33 44 00 01 01"; 115 try { 116 testParserHelper(unsupportedWbxmlTag); 117 fail("Expected EasParserException for unsupported tag 0xC2"); 118 } catch (Parser.EasParserException e) { 119 // expected 120 } 121 } 122 123 @SmallTest 124 public void testUnknownCodePage() throws Exception { 125 // Test parser with non existent code page 64 (0x40) 126 final String unknownCodePage = "03 01 6A 00 45 00 40 4A 03 31 00 01 01"; 127 try { 128 testParserHelper(unknownCodePage); 129 fail("Expected EasParserException for unknown code page 64"); 130 } catch (Parser.EasParserException e) { 131 // expected 132 } 133 } 134 135 @SmallTest 136 public void testUnknownTag() throws Exception { 137 // Test parser with valid code page (0x00) but non existent tag (0x3F) 138 final String unknownTag = "03 01 6A 00 45 7F 03 31 00 01 01"; 139 testParserHelper(unknownTag); 140 } 141 142 @SmallTest 143 public void testTextParsing() throws Exception { 144 // Expect text; has text data "DF" 145 final String textTagWithTextData = "03 01 6A 00 45 4B 03 44 46 00 01 01"; 146 testParserHelper(textTagWithTextData, new Object[] {"DF"}); 147 148 // Expect text; has tag with no content: <Tag/> 149 final String textTagNoContent = "03 01 6A 00 45 0B 01"; 150 testParserHelper(textTagNoContent, new Object[] {""}); 151 152 // Expect text; has tag and end tag with no value: <Tag></Tag> 153 final String emptyTextTag = "03 01 6A 00 45 4B 01 01"; 154 testParserHelper(emptyTextTag, new Object[] {""}); 155 156 // Expect text; has opaque data {0x11, 0x22, 0x33} 157 final String textTagWithOpaqueData = "03 01 6A 00 45 4B C3 03 11 22 33 01 01"; 158 try { 159 testParserHelper(textTagWithOpaqueData); 160 fail("Expected EasParserException for trying to read opaque data as text"); 161 } catch (Parser.EasParserException e) { 162 // expected 163 } 164 } 165 166 @SmallTest 167 public void testIntegerStringParsing() throws Exception { 168 // Expect int; has text data "1" 169 final String intTagWithIntData = "03 01 6A 00 45 4C 03 31 00 01 01"; 170 testParserHelper(intTagWithIntData, new Object[] {1}); 171 172 // Expect int; has tag with no content: <Tag/> 173 final String intTagNoContent = "03 01 6A 00 45 0C 01"; 174 testParserHelper(intTagNoContent, new Object[] {0}); 175 176 // Expect int; has tag and end tag with no value: <Tag></Tag> 177 final String emptyIntTag = "03 01 6A 00 45 4C 01 01"; 178 testParserHelper(emptyIntTag, new Object[] {0}); 179 180 // Expect int; has text data "DF" 181 final String intTagWithTextData = "03 01 6A 00 45 4C 03 44 46 00 01 01"; 182 try { 183 testParserHelper(intTagWithTextData); 184 fail("Expected EasParserException for nonnumeric char 'D'"); 185 } catch (Parser.EasParserException e) { 186 // expected 187 } 188 } 189 190 @SmallTest 191 public void testOpaqueDataParsing() throws Exception { 192 // Expect opaque; has opaque data {0x11, 0x22, 0x33} 193 final String opaqueTagWithOpaqueData = "03 01 6A 00 45 4D C3 03 11 22 33 01 01"; 194 testParserHelper(opaqueTagWithOpaqueData, new Object[] {"11 22 33"}); 195 196 // Expect opaque; has tag with no content: <Tag/> 197 final String opaqueTagNoContent = "03 01 6A 00 45 0D 01"; 198 testParserHelper(opaqueTagNoContent, new Object[] {""}); 199 200 // Expect opaque; has tag and end tag with no value: <Tag></Tag> 201 final String emptyOpaqueTag = "03 01 6A 00 45 4D 01 01"; 202 testParserHelper(emptyOpaqueTag, new Object[] {""}); 203 204 // Expect opaque; has text data "DF" 205 final String opaqueTagWithTextData = "03 01 6A 00 45 4D 03 44 46 00 01 01"; 206 testParserHelper(opaqueTagWithTextData, new Object[] {"44 46"}); 207 } 208 209 @SmallTest 210 public void testMalformedData() throws Exception { 211 final String malformedData = "03 01 6A 00 45 4B 03 11 22 00 00 33 00 01 01"; 212 try { 213 testParserHelper(malformedData); 214 fail("Expected EasParserException for improperly escaped text data"); 215 } catch (Parser.EasParserException e) { 216 // expected 217 } 218 } 219 220 @SmallTest 221 public void testRunOnInteger() throws Exception { 222 final String runOnIntegerEncoding = "03 01 6A 00 45 4D C3 81 82 83 84 85 06 11 22 33 01 01"; 223 try { 224 testParserHelper(runOnIntegerEncoding); 225 fail("Expected EasParserException for improperly encoded integer"); 226 } catch (Parser.EasParserException e) { 227 // expected 228 } 229 } 230 231 @SmallTest 232 public void testAttributeTag() throws Exception { 233 // Test parser with known tag with attributes 234 final String tagWithAttributes = "03 01 6A 00 45 DF 06 01 03 31 00 01 01"; 235 try { 236 testParserHelper(tagWithAttributes); 237 fail("Expected EasParserException for tag with attributes 0xDF"); 238 } catch (Parser.EasParserException e) { 239 // expected 240 } 241 } 242 } 243