blob: 1d4589347a7868a6dbc87f740651714c1a65da41 [file] [log] [blame]
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -07001/*
2 * Copyright (C) 2009 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
17package com.android.unit_tests.vcard;
18
19import android.content.ContentValues;
Daisuke Miyakawaf035b472009-11-04 11:41:50 +090020import android.pim.vcard.VCardConfig;
21import android.pim.vcard.VCardParser;
22import android.pim.vcard.VCardParser_V21;
23import android.pim.vcard.VCardParser_V30;
24import android.pim.vcard.exception.VCardException;
25import android.test.AndroidTestCase;
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -070026
Daisuke Miyakawaf035b472009-11-04 11:41:50 +090027import junit.framework.TestCase;
28
29import java.io.IOException;
30import java.io.InputStream;
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -070031import java.util.ArrayList;
32import java.util.Arrays;
33import java.util.HashMap;
34import java.util.HashSet;
35import java.util.List;
36
Daisuke Miyakawaf035b472009-11-04 11:41:50 +090037public class PropertyNodesVerifier extends VNodeBuilder {
38 private final List<PropertyNodesVerifierElem> mPropertyNodesVerifierElemList;
39 private final AndroidTestCase mAndroidTestCase;
40 private int mIndex;
41
42 public PropertyNodesVerifier(AndroidTestCase testCase) {
43 mPropertyNodesVerifierElemList = new ArrayList<PropertyNodesVerifierElem>();
44 mAndroidTestCase = testCase;
45 }
46
47 public PropertyNodesVerifierElem addPropertyNodesVerifierElem() {
48 PropertyNodesVerifierElem elem = new PropertyNodesVerifierElem(mAndroidTestCase);
49 mPropertyNodesVerifierElemList.add(elem);
50 return elem;
51 }
52
53 public void verify(int resId, int vCardType)
54 throws IOException, VCardException {
55 verify(mAndroidTestCase.getContext().getResources().openRawResource(resId), vCardType);
56 }
57
Daisuke Miyakawa0e983862009-11-09 15:10:04 +090058 public void verify(int resId, int vCardType, final VCardParser vCardParser)
59 throws IOException, VCardException {
60 verify(mAndroidTestCase.getContext().getResources().openRawResource(resId),
61 vCardType, vCardParser);
62 }
63
Daisuke Miyakawaf035b472009-11-04 11:41:50 +090064 public void verify(InputStream is, int vCardType) throws IOException, VCardException {
65 final VCardParser vCardParser;
66 if (VCardConfig.isV30(vCardType)) {
67 vCardParser = new VCardParser_V30(true); // use StrictParsing
68 } else {
69 vCardParser = new VCardParser_V21();
70 }
Daisuke Miyakawa0e983862009-11-09 15:10:04 +090071 verify(is, vCardType, vCardParser);
72 }
73
74 public void verify(InputStream is, int vCardType, final VCardParser vCardParser)
75 throws IOException, VCardException {
Daisuke Miyakawaf035b472009-11-04 11:41:50 +090076 try {
77 vCardParser.parse(is, this);
78 } finally {
79 if (is != null) {
80 try {
81 is.close();
82 } catch (IOException e) {
83 }
84 }
85 }
86 }
87
88 @Override
89 public void endRecord() {
90 super.endRecord();
91 mAndroidTestCase.assertTrue(mIndex < mPropertyNodesVerifierElemList.size());
92 mAndroidTestCase.assertTrue(mIndex < vNodeList.size());
93 mPropertyNodesVerifierElemList.get(mIndex).verify(vNodeList.get(mIndex));
94 mIndex++;
95 }
96}
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -070097
98/**
99 * Utility class which verifies input VNode.
100 *
101 * This class first checks whether each propertyNode in the VNode is in the
102 * "ordered expected property list".
103 * If the node does not exist in the "ordered list", the class refers to
104 * "unorderd expected property set" and checks the node is expected somewhere.
105 */
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900106class PropertyNodesVerifierElem {
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700107 public static class TypeSet extends HashSet<String> {
108 public TypeSet(String ... array) {
109 super(Arrays.asList(array));
110 }
111 }
112
113 public static class GroupSet extends HashSet<String> {
114 public GroupSet(String ... array) {
115 super(Arrays.asList(array));
116 }
117 }
118
119 private final HashMap<String, List<PropertyNode>> mOrderedNodeMap;
120 // Intentionally use ArrayList instead of Set, assuming there may be more than one
121 // exactly same objects.
122 private final ArrayList<PropertyNode> mUnorderedNodeList;
123 private final TestCase mTestCase;
124
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900125 public PropertyNodesVerifierElem(TestCase testCase) {
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700126 mOrderedNodeMap = new HashMap<String, List<PropertyNode>>();
127 mUnorderedNodeList = new ArrayList<PropertyNode>();
128 mTestCase = testCase;
129 }
130
131 // WithOrder
132
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900133 public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue) {
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700134 return addNodeWithOrder(propName, propValue, null, null, null, null, null);
135 }
136
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900137 public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
Daisuke Miyakawa4fe2c572009-11-05 13:41:24 +0900138 ContentValues contentValues) {
139 return addNodeWithOrder(propName, propValue, null, null, contentValues, null, null);
140 }
141
142 public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700143 List<String> propValueList) {
144 return addNodeWithOrder(propName, propValue, propValueList, null, null, null, null);
145 }
146
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900147 public PropertyNodesVerifierElem addNodeWithOrder(String propName, List<String> propValueList) {
Daisuke Miyakawa4fe2c572009-11-05 13:41:24 +0900148 final String propValue = concatinateListWithSemiColon(propValueList);
149 return addNodeWithOrder(propName, propValue.toString(), propValueList,
Daisuke Miyakawad263a062009-10-27 08:07:25 +0900150 null, null, null, null);
151 }
152
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900153 public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700154 TypeSet paramMap_TYPE) {
155 return addNodeWithOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
156 }
157
Daisuke Miyakawa4fe2c572009-11-05 13:41:24 +0900158 public PropertyNodesVerifierElem addNodeWithOrder(String propName,
159 List<String> propValueList, TypeSet paramMap_TYPE) {
160 final String propValue = concatinateListWithSemiColon(propValueList);
161 return addNodeWithOrder(propName, propValue, propValueList, null, null,
162 paramMap_TYPE, null);
163 }
164
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900165 public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
Daisuke Miyakawa592988d2009-11-12 11:19:06 +0900166 ContentValues paramMap, TypeSet paramMap_TYPE) {
167 return addNodeWithOrder(propName, propValue, null, null,
168 paramMap, paramMap_TYPE, null);
169 }
170
171 public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700172 List<String> propValueList, TypeSet paramMap_TYPE) {
173 return addNodeWithOrder(propName, propValue, propValueList, null, null,
174 paramMap_TYPE, null);
175 }
176
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900177 public PropertyNodesVerifierElem addNodeWithOrder(String propName, String propValue,
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700178 List<String> propValueList, byte[] propValue_bytes,
179 ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) {
180 PropertyNode propertyNode = new PropertyNode(propName,
181 propValue, propValueList, propValue_bytes,
182 paramMap, paramMap_TYPE, propGroupSet);
183 List<PropertyNode> expectedNodeList = mOrderedNodeMap.get(propName);
184 if (expectedNodeList == null) {
185 expectedNodeList = new ArrayList<PropertyNode>();
186 mOrderedNodeMap.put(propName, expectedNodeList);
187 }
188 expectedNodeList.add(propertyNode);
189 return this;
190 }
191
192 // WithoutOrder
193
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900194 public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue) {
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700195 return addNodeWithoutOrder(propName, propValue, null, null, null, null, null);
196 }
197
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900198 public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
Daisuke Miyakawa4fe2c572009-11-05 13:41:24 +0900199 ContentValues contentValues) {
200 return addNodeWithoutOrder(propName, propValue, null, null, contentValues, null, null);
201 }
202
203 public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700204 List<String> propValueList) {
205 return addNodeWithoutOrder(propName, propValue, propValueList, null, null, null, null);
206 }
207
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900208 public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, List<String> propValueList) {
Daisuke Miyakawa4fe2c572009-11-05 13:41:24 +0900209 final String propValue = concatinateListWithSemiColon(propValueList);
210 return addNodeWithoutOrder(propName, propValue, propValueList,
Daisuke Miyakawad263a062009-10-27 08:07:25 +0900211 null, null, null, null);
212 }
213
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900214 public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700215 TypeSet paramMap_TYPE) {
216 return addNodeWithoutOrder(propName, propValue, null, null, null, paramMap_TYPE, null);
217 }
218
Daisuke Miyakawa4fe2c572009-11-05 13:41:24 +0900219 public PropertyNodesVerifierElem addNodeWithoutOrder(String propName,
220 List<String> propValueList, TypeSet paramMap_TYPE) {
221 final String propValue = concatinateListWithSemiColon(propValueList);
222 return addNodeWithoutOrder(propName, propValue, propValueList, null, null,
223 paramMap_TYPE, null);
224 }
225
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900226 public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700227 List<String> propValueList, TypeSet paramMap_TYPE) {
228 return addNodeWithoutOrder(propName, propValue, propValueList, null, null,
229 paramMap_TYPE, null);
230 }
231
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900232 public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
Daisuke Miyakawa592988d2009-11-12 11:19:06 +0900233 ContentValues paramMap, TypeSet paramMap_TYPE) {
234 return addNodeWithoutOrder(propName, propValue, null, null,
235 paramMap, paramMap_TYPE, null);
236 }
237
238 public PropertyNodesVerifierElem addNodeWithoutOrder(String propName, String propValue,
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700239 List<String> propValueList, byte[] propValue_bytes,
240 ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) {
241 mUnorderedNodeList.add(new PropertyNode(propName, propValue,
242 propValueList, propValue_bytes, paramMap, paramMap_TYPE, propGroupSet));
243 return this;
244 }
245
246 public void verify(VNode vnode) {
247 for (PropertyNode actualNode : vnode.propList) {
248 verifyNode(actualNode.propName, actualNode);
249 }
250 if (!mOrderedNodeMap.isEmpty() || !mUnorderedNodeList.isEmpty()) {
251 List<String> expectedProps = new ArrayList<String>();
252 for (List<PropertyNode> nodes : mOrderedNodeMap.values()) {
253 for (PropertyNode node : nodes) {
254 if (!expectedProps.contains(node.propName)) {
255 expectedProps.add(node.propName);
256 }
257 }
258 }
259 for (PropertyNode node : mUnorderedNodeList) {
260 if (!expectedProps.contains(node.propName)) {
261 expectedProps.add(node.propName);
262 }
263 }
264 mTestCase.fail("Expected property " + Arrays.toString(expectedProps.toArray())
265 + " was not found.");
266 }
267 }
268
269 private void verifyNode(final String propName, final PropertyNode actualNode) {
270 List<PropertyNode> expectedNodeList = mOrderedNodeMap.get(propName);
271 final int size = (expectedNodeList != null ? expectedNodeList.size() : 0);
272 if (size > 0) {
273 for (int i = 0; i < size; i++) {
274 PropertyNode expectedNode = expectedNodeList.get(i);
Daisuke Miyakawaf035b472009-11-04 11:41:50 +0900275 List<PropertyNode> expectedButDifferentValueList = new ArrayList<PropertyNode>();
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700276 if (expectedNode.propName.equals(propName)) {
277 if (expectedNode.equals(actualNode)) {
278 expectedNodeList.remove(i);
279 if (expectedNodeList.size() == 0) {
280 mOrderedNodeMap.remove(propName);
281 }
282 return;
283 } else {
284 expectedButDifferentValueList.add(expectedNode);
285 }
286 }
287
288 // "actualNode" is not in ordered expected list.
289 // Try looking over unordered expected list.
290 if (tryFoundExpectedNodeFromUnorderedList(actualNode,
291 expectedButDifferentValueList)) {
292 return;
293 }
294
295 if (!expectedButDifferentValueList.isEmpty()) {
296 // Same propName exists but with different value(s).
297 failWithExpectedNodeList(propName, actualNode,
298 expectedButDifferentValueList);
299 } else {
300 // There's no expected node with same propName.
301 mTestCase.fail("Unexpected property \"" + propName + "\" exists.");
302 }
303 }
304 } else {
305 List<PropertyNode> expectedButDifferentValueList =
306 new ArrayList<PropertyNode>();
307 if (tryFoundExpectedNodeFromUnorderedList(actualNode, expectedButDifferentValueList)) {
308 return;
309 } else {
310 if (!expectedButDifferentValueList.isEmpty()) {
311 // Same propName exists but with different value(s).
312 failWithExpectedNodeList(propName, actualNode,
313 expectedButDifferentValueList);
314 } else {
315 // There's no expected node with same propName.
316 mTestCase.fail("Unexpected property \"" + propName + "\" exists.");
317 }
318 }
319 }
320 }
321
Daisuke Miyakawa4fe2c572009-11-05 13:41:24 +0900322 private String concatinateListWithSemiColon(List<String> array) {
323 StringBuffer buffer = new StringBuffer();
324 boolean first = true;
325 for (String propValueElem : array) {
326 if (first) {
327 first = false;
328 } else {
329 buffer.append(';');
330 }
331 buffer.append(propValueElem);
332 }
333
334 return buffer.toString();
335 }
336
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700337 private boolean tryFoundExpectedNodeFromUnorderedList(PropertyNode actualNode,
338 List<PropertyNode> expectedButDifferentValueList) {
339 final String propName = actualNode.propName;
340 int unorderedListSize = mUnorderedNodeList.size();
341 for (int i = 0; i < unorderedListSize; i++) {
342 PropertyNode unorderedExpectedNode = mUnorderedNodeList.get(i);
343 if (unorderedExpectedNode.propName.equals(propName)) {
344 if (unorderedExpectedNode.equals(actualNode)) {
345 mUnorderedNodeList.remove(i);
346 return true;
347 }
348 expectedButDifferentValueList.add(unorderedExpectedNode);
349 }
350 }
351 return false;
352 }
353
354 private void failWithExpectedNodeList(String propName, PropertyNode actualNode,
355 List<PropertyNode> expectedNodeList) {
356 StringBuilder builder = new StringBuilder();
357 for (PropertyNode expectedNode : expectedNodeList) {
358 builder.append("expected: ");
359 builder.append(expectedNode.toString());
360 builder.append("\n");
361 }
362 mTestCase.fail("Property \"" + propName + "\" has wrong value.\n"
363 + builder.toString()
Daisuke Miyakawa99a0a2c2009-10-13 17:45:25 -0700364 + " actual: " + actualNode.toString());
Daisuke Miyakawaba2b21b2009-10-11 18:23:19 -0700365 }
366}