PropertyNodesVerifierElem.java revision 677ef21613a9d35053ec098444832ce4125a847e
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 */
16package com.android.vcard.tests.testutils;
17
18import android.content.ContentValues;
19import android.test.AndroidTestCase;
20
21import junit.framework.TestCase;
22
23import java.util.ArrayList;
24import java.util.Arrays;
25import java.util.HashMap;
26import java.util.HashSet;
27import 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 */
37public class PropertyNodesVerifierElem {
38    public static class TypeSet extends HashSet<String> {
39        public TypeSet(String ... array) {
40            super(Arrays.asList(array));
41        }
42    }
43
44    public static class GroupSet extends HashSet<String> {
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
55    public PropertyNodesVerifierElem(AndroidTestCase androidTestCase) {
56        mOrderedNodeMap = new HashMap<String, List<PropertyNode>>();
57        mUnorderedNodeList = new ArrayList<PropertyNode>();
58    }
59
60    // WithOrder
61
62    public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue) {
63        return addExpectedNodeWithOrder(propName, propValue, null, null, null, null, null);
64    }
65
66    public PropertyNodesVerifierElem addExpectedNodeWithOrder(
67            String propName, String propValue, ContentValues contentValues) {
68        return addExpectedNodeWithOrder(propName, propValue, null,
69                null, contentValues, null, null);
70    }
71
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
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
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
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
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
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
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
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
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
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
147    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue) {
148        return addExpectedNode(propName, propValue, null, null, null, null, null);
149    }
150
151    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue,
152            ContentValues contentValues) {
153        return addExpectedNode(propName, propValue, null, null, contentValues, null, null);
154    }
155
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
162    public PropertyNodesVerifierElem addExpectedNode(String propName, String propValue,
163            List<String> propValueList) {
164        return addExpectedNode(propName, propValue, propValueList, null, null, null, null);
165    }
166
167    public PropertyNodesVerifierElem addExpectedNode(String propName,
168            List<String> propValueList) {
169        return addExpectedNode(propName, null, propValueList,
170                null, null, null, null);
171    }
172
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
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
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
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
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
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
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
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
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
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