1 /* 2 * Copyright (C) 2010 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 package com.android.vcard.tests.testutils; 17 18 import android.content.ContentValues; 19 import android.test.AndroidTestCase; 20 21 import junit.framework.TestCase; 22 23 import java.util.ArrayList; 24 import java.util.Arrays; 25 import java.util.HashMap; 26 import java.util.HashSet; 27 import java.util.List; 28 29 /** 30 * Utility class which verifies input VNode. 31 * 32 * This class first checks whether each propertyNode in the VNode is in the 33 * "ordered expected property list". 34 * If the node does not exist in the "ordered list", the class refers to 35 * "unorderd expected property set" and checks the node is expected somewhere. 36 */ 37 public class PropertyNodesVerifierElem { 38 public static class TypeSet extends HashSet<String> { TypeSet(String .... array)39 public TypeSet(String ... array) { 40 super(Arrays.asList(array)); 41 } 42 } 43 44 public static class GroupSet extends HashSet<String> { GroupSet(String .... array)45 public GroupSet(String ... array) { 46 super(Arrays.asList(array)); 47 } 48 } 49 50 private final HashMap<String, List<PropertyNode>> mOrderedNodeMap; 51 // Intentionally use ArrayList instead of Set, assuming there may be more than one 52 // exactly same objects. 53 private final ArrayList<PropertyNode> mUnorderedNodeList; 54 PropertyNodesVerifierElem(AndroidTestCase androidTestCase)55 public PropertyNodesVerifierElem(AndroidTestCase androidTestCase) { 56 mOrderedNodeMap = new HashMap<String, List<PropertyNode>>(); 57 mUnorderedNodeList = new ArrayList<PropertyNode>(); 58 } 59 60 // WithOrder 61 addExpectedNodeWithOrder(String propName, String propValue)62 public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue) { 63 return addExpectedNodeWithOrder(propName, propValue, null, null, null, null, null); 64 } 65 addExpectedNodeWithOrder( String propName, String propValue, ContentValues contentValues)66 public PropertyNodesVerifierElem addExpectedNodeWithOrder( 67 String propName, String propValue, ContentValues contentValues) { 68 return addExpectedNodeWithOrder(propName, propValue, null, 69 null, contentValues, null, null); 70 } 71 addExpectedNodeWithOrder( String propName, List<String> propValueList, ContentValues contentValues)72 public PropertyNodesVerifierElem addExpectedNodeWithOrder( 73 String propName, List<String> propValueList, ContentValues contentValues) { 74 return addExpectedNodeWithOrder(propName, null, propValueList, 75 null, contentValues, null, null); 76 } 77 addExpectedNodeWithOrder( String propName, String propValue, List<String> propValueList)78 public PropertyNodesVerifierElem addExpectedNodeWithOrder( 79 String propName, String propValue, List<String> propValueList) { 80 return addExpectedNodeWithOrder(propName, propValue, propValueList, null, 81 null, null, null); 82 } 83 addExpectedNodeWithOrder( String propName, List<String> propValueList)84 public PropertyNodesVerifierElem addExpectedNodeWithOrder( 85 String propName, List<String> propValueList) { 86 final String propValue = concatinateListWithSemiColon(propValueList); 87 return addExpectedNodeWithOrder(propName, propValue.toString(), propValueList, 88 null, null, null, null); 89 } 90 addExpectedNodeWithOrder(String propName, String propValue, TypeSet paramMap_TYPE)91 public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue, 92 TypeSet paramMap_TYPE) { 93 return addExpectedNodeWithOrder(propName, propValue, null, 94 null, null, paramMap_TYPE, null); 95 } 96 addExpectedNodeWithOrder(String propName, List<String> propValueList, TypeSet paramMap_TYPE)97 public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, 98 List<String> propValueList, TypeSet paramMap_TYPE) { 99 return addExpectedNodeWithOrder(propName, null, propValueList, null, null, 100 paramMap_TYPE, null); 101 } 102 addExpectedNodeWithOrder(String propName, List<String> propValueList, ContentValues paramMap, TypeSet paramMap_TYPE)103 public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, 104 List<String> propValueList, ContentValues paramMap, TypeSet paramMap_TYPE) { 105 return addExpectedNodeWithOrder(propName, null, propValueList, null, paramMap, 106 paramMap_TYPE, null); 107 } 108 addExpectedNodeWithOrder(String propName, String propValue, ContentValues paramMap, TypeSet paramMap_TYPE)109 public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue, 110 ContentValues paramMap, TypeSet paramMap_TYPE) { 111 return addExpectedNodeWithOrder(propName, propValue, null, null, 112 paramMap, paramMap_TYPE, null); 113 } 114 addExpectedNodeWithOrder(String propName, String propValue, List<String> propValueList, TypeSet paramMap_TYPE)115 public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue, 116 List<String> propValueList, TypeSet paramMap_TYPE) { 117 return addExpectedNodeWithOrder(propName, propValue, propValueList, null, null, 118 paramMap_TYPE, null); 119 } 120 addExpectedNodeWithOrder(String propName, String propValue, List<String> propValueList, ContentValues paramMap)121 public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue, 122 List<String> propValueList, ContentValues paramMap) { 123 return addExpectedNodeWithOrder(propName, propValue, propValueList, null, paramMap, 124 null, null); 125 } 126 addExpectedNodeWithOrder(String propName, String propValue, List<String> propValueList, byte[] propValue_bytes, ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet)127 public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue, 128 List<String> propValueList, byte[] propValue_bytes, 129 ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) { 130 if (propValue == null && propValueList != null) { 131 propValue = concatinateListWithSemiColon(propValueList); 132 } 133 final PropertyNode propertyNode = new PropertyNode(propName, 134 propValue, propValueList, propValue_bytes, 135 paramMap, paramMap_TYPE, propGroupSet); 136 List<PropertyNode> expectedNodeList = mOrderedNodeMap.get(propName); 137 if (expectedNodeList == null) { 138 expectedNodeList = new ArrayList<PropertyNode>(); 139 mOrderedNodeMap.put(propName, expectedNodeList); 140 } 141 expectedNodeList.add(propertyNode); 142 return this; 143 } 144 145 // WithoutOrder 146 addExpectedNode(String propName, String propValue)147 public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue) { 148 return addExpectedNode(propName, propValue, null, null, null, null, null); 149 } 150 addExpectedNode(String propName, String propValue, ContentValues contentValues)151 public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue, 152 ContentValues contentValues) { 153 return addExpectedNode(propName, propValue, null, null, contentValues, null, null); 154 } 155 addExpectedNode(String propName, List<String> propValueList, ContentValues contentValues)156 public PropertyNodesVerifierElem addExpectedNode(String propName, 157 List<String> propValueList, ContentValues contentValues) { 158 return addExpectedNode(propName, null, 159 propValueList, null, contentValues, null, null); 160 } 161 addExpectedNode(String propName, String propValue, List<String> propValueList)162 public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue, 163 List<String> propValueList) { 164 return addExpectedNode(propName, propValue, propValueList, null, null, null, null); 165 } 166 addExpectedNode(String propName, List<String> propValueList)167 public PropertyNodesVerifierElem addExpectedNode(String propName, 168 List<String> propValueList) { 169 return addExpectedNode(propName, null, propValueList, 170 null, null, null, null); 171 } 172 addExpectedNode(String propName, String propValue, TypeSet paramMap_TYPE)173 public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue, 174 TypeSet paramMap_TYPE) { 175 return addExpectedNode(propName, propValue, null, null, null, paramMap_TYPE, null); 176 } 177 addExpectedNode(String propName, List<String> propValueList, TypeSet paramMap_TYPE)178 public PropertyNodesVerifierElem addExpectedNode(String propName, 179 List<String> propValueList, TypeSet paramMap_TYPE) { 180 final String propValue = concatinateListWithSemiColon(propValueList); 181 return addExpectedNode(propName, propValue, propValueList, null, null, 182 paramMap_TYPE, null); 183 } 184 addExpectedNode(String propName, String propValue, List<String> propValueList, TypeSet paramMap_TYPE)185 public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue, 186 List<String> propValueList, TypeSet paramMap_TYPE) { 187 return addExpectedNode(propName, propValue, propValueList, null, null, 188 paramMap_TYPE, null); 189 } 190 addExpectedNode(String propName, String propValue, ContentValues paramMap, TypeSet paramMap_TYPE)191 public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue, 192 ContentValues paramMap, TypeSet paramMap_TYPE) { 193 return addExpectedNode(propName, propValue, null, null, 194 paramMap, paramMap_TYPE, null); 195 } 196 addExpectedNode(String propName, String propValue, List<String> propValueList, byte[] propValue_bytes, ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet)197 public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue, 198 List<String> propValueList, byte[] propValue_bytes, 199 ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) { 200 if (propValue == null && propValueList != null) { 201 propValue = concatinateListWithSemiColon(propValueList); 202 } 203 mUnorderedNodeList.add(new PropertyNode(propName, propValue, 204 propValueList, propValue_bytes, paramMap, paramMap_TYPE, propGroupSet)); 205 return this; 206 } 207 verify(VNode vnode)208 public void verify(VNode vnode) { 209 for (PropertyNode actualNode : vnode.propList) { 210 verifyNode(actualNode.propName, actualNode); 211 } 212 213 if (!mOrderedNodeMap.isEmpty() || !mUnorderedNodeList.isEmpty()) { 214 final List<String> expectedProps = new ArrayList<String>(); 215 for (List<PropertyNode> nodes : mOrderedNodeMap.values()) { 216 for (PropertyNode node : nodes) { 217 if (!expectedProps.contains(node.propName)) { 218 expectedProps.add(node.propName); 219 } 220 } 221 } 222 for (PropertyNode node : mUnorderedNodeList) { 223 if (!expectedProps.contains(node.propName)) { 224 expectedProps.add(node.propName); 225 } 226 } 227 TestCase.fail("Expected property " + Arrays.toString(expectedProps.toArray()) 228 + " was not found."); 229 } 230 } 231 verifyNode(final String propName, final PropertyNode actualNode)232 private void verifyNode(final String propName, final PropertyNode actualNode) { 233 final List<PropertyNode> expectedNodeList = mOrderedNodeMap.get(propName); 234 final int size = (expectedNodeList != null ? expectedNodeList.size() : 0); 235 if (size > 0) { 236 for (int i = 0; i < size; i++) { 237 final PropertyNode expectedNode = expectedNodeList.get(i); 238 final List<PropertyNode> expectedButDifferentValueList = 239 new ArrayList<PropertyNode>(); 240 if (expectedNode.propName.equals(propName)) { 241 if (expectedNode.equals(actualNode)) { 242 expectedNodeList.remove(i); 243 if (expectedNodeList.size() == 0) { 244 mOrderedNodeMap.remove(propName); 245 } 246 return; 247 } else { 248 expectedButDifferentValueList.add(expectedNode); 249 } 250 } 251 252 // "actualNode" is not in ordered expected list. 253 // Try looking over unordered expected list. 254 if (tryFoundExpectedNodeFromUnorderedList(actualNode, 255 expectedButDifferentValueList)) { 256 return; 257 } 258 259 if (!expectedButDifferentValueList.isEmpty()) { 260 // Same propName exists but with different value(s). 261 failWithExpectedNodeList(propName, actualNode, 262 expectedButDifferentValueList); 263 } else { 264 // There's no expected node with same propName. 265 TestCase.fail("Unexpected property \"" + propName + "\" exists."); 266 } 267 } 268 } else { 269 List<PropertyNode> expectedButDifferentValueList = 270 new ArrayList<PropertyNode>(); 271 if (tryFoundExpectedNodeFromUnorderedList(actualNode, expectedButDifferentValueList)) { 272 return; 273 } else { 274 if (!expectedButDifferentValueList.isEmpty()) { 275 // Same propName exists but with different value(s). 276 failWithExpectedNodeList(propName, actualNode, 277 expectedButDifferentValueList); 278 } else { 279 // There's no expected node with same propName. 280 TestCase.fail("Unexpected property \"" + propName + "\" exists."); 281 } 282 } 283 } 284 } 285 concatinateListWithSemiColon(List<String> array)286 private String concatinateListWithSemiColon(List<String> array) { 287 StringBuffer buffer = new StringBuffer(); 288 boolean first = true; 289 for (String propValueElem : array) { 290 if (first) { 291 first = false; 292 } else { 293 buffer.append(';'); 294 } 295 buffer.append(propValueElem); 296 } 297 298 return buffer.toString(); 299 } 300 tryFoundExpectedNodeFromUnorderedList(PropertyNode actualNode, List<PropertyNode> expectedButDifferentValueList)301 private boolean tryFoundExpectedNodeFromUnorderedList(PropertyNode actualNode, 302 List<PropertyNode> expectedButDifferentValueList) { 303 final String propName = actualNode.propName; 304 int unorderedListSize = mUnorderedNodeList.size(); 305 for (int i = 0; i < unorderedListSize; i++) { 306 PropertyNode unorderedExpectedNode = mUnorderedNodeList.get(i); 307 if (unorderedExpectedNode.propName.equals(propName)) { 308 if (unorderedExpectedNode.equals(actualNode)) { 309 mUnorderedNodeList.remove(i); 310 return true; 311 } 312 expectedButDifferentValueList.add(unorderedExpectedNode); 313 } 314 } 315 return false; 316 } 317 failWithExpectedNodeList(String propName, PropertyNode actualNode, List<PropertyNode> expectedNodeList)318 private void failWithExpectedNodeList(String propName, PropertyNode actualNode, 319 List<PropertyNode> expectedNodeList) { 320 StringBuilder builder = new StringBuilder(); 321 for (PropertyNode expectedNode : expectedNodeList) { 322 builder.append("expected: "); 323 builder.append(expectedNode.toString()); 324 builder.append("\n"); 325 } 326 TestCase.fail("Property \"" + propName + "\" has wrong value.\n" 327 + builder.toString() 328 + " actual: " + actualNode.toString()); 329 } 330 } 331