Home | History | Annotate | Download | only in adapter
      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