• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4  * COPYRIGHT:
5  * Copyright (c) 2004-2011, International Business Machines Corporation and
6  * others. All Rights Reserved.
7  ********************************************************************/
8 
9 //      Test parts of UVector and UStack
10 
11 #include "intltest.h"
12 
13 #include "uvectest.h"
14 #include "cstring.h"
15 #include "hash.h"
16 #include "uelement.h"
17 #include "uvector.h"
18 
19 //---------------------------------------------------------------------------
20 //
21 //  Test class boilerplate
22 //
23 //---------------------------------------------------------------------------
UVectorTest()24 UVectorTest::UVectorTest()
25 {
26 }
27 
28 
~UVectorTest()29 UVectorTest::~UVectorTest()
30 {
31 }
32 
33 
34 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)35 void UVectorTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
36 {
37     if (exec) logln("TestSuite UVectorTest: ");
38     switch (index) {
39 
40         case 0: name = "UVector_API";
41             if (exec) UVector_API();
42             break;
43         case 1: name = "UStack_API";
44             if (exec) UStack_API();
45             break;
46         case 2: name = "Hashtable_API";
47             if (exec) Hashtable_API();
48             break;
49         default: name = "";
50             break; //needed to end loop
51     }
52 }
53 
54 
55 //---------------------------------------------------------------------------
56 //
57 //   Error Checking / Reporting macros used in all of the tests.
58 //
59 //---------------------------------------------------------------------------
60 #define TEST_CHECK_STATUS(status) UPRV_BLOCK_MACRO_BEGIN {\
61     if (U_FAILURE(status)) {\
62         errln("UVectorTest failure at line %d.  status=%s\n", __LINE__, u_errorName(status));\
63         return;\
64     }\
65 } UPRV_BLOCK_MACRO_END
66 
67 #define TEST_ASSERT(expr) UPRV_BLOCK_MACRO_BEGIN {\
68     if ((expr)==false) {\
69         errln("UVectorTest failure at line %d.\n", __LINE__);\
70     }\
71 } UPRV_BLOCK_MACRO_END
72 
73 static int32_t U_CALLCONV
UVectorTest_compareInt32(UElement key1,UElement key2)74 UVectorTest_compareInt32(UElement key1, UElement key2) {
75     if (key1.integer > key2.integer) {
76         return 1;
77     }
78     else if (key1.integer < key2.integer) {
79         return -1;
80     }
81     return 0;
82 }
83 
84 U_CDECL_BEGIN
85 static int8_t U_CALLCONV
UVectorTest_compareCstrings(const UElement key1,const UElement key2)86 UVectorTest_compareCstrings(const UElement key1, const UElement key2) {
87     return !strcmp((const char *)key1.pointer, (const char *)key2.pointer);
88 }
89 U_CDECL_END
90 
91 //---------------------------------------------------------------------------
92 //
93 //      UVector_API      Check for basic functionality of UVector.
94 //
95 //---------------------------------------------------------------------------
UVector_API()96 void UVectorTest::UVector_API() {
97 
98     UErrorCode  status = U_ZERO_ERROR;
99     UVector     *a;
100 
101     a = new UVector(status);
102     TEST_CHECK_STATUS(status);
103     delete a;
104 
105     status = U_ZERO_ERROR;
106     a = new UVector(2000, status);
107     TEST_CHECK_STATUS(status);
108     delete a;
109 
110     status = U_ZERO_ERROR;
111     a = new UVector(status);
112     a->sortedInsert((int32_t)10, UVectorTest_compareInt32, status);
113     a->sortedInsert((int32_t)20, UVectorTest_compareInt32, status);
114     a->sortedInsert((int32_t)30, UVectorTest_compareInt32, status);
115     a->sortedInsert((int32_t)15, UVectorTest_compareInt32, status);
116     TEST_CHECK_STATUS(status);
117     TEST_ASSERT(a->elementAti(0) == 10);
118     TEST_ASSERT(a->elementAti(1) == 15);
119     TEST_ASSERT(a->elementAti(2) == 20);
120     TEST_ASSERT(a->elementAti(3) == 30);
121     TEST_ASSERT(a->indexOf((int32_t)3) == -1);
122     TEST_ASSERT(a->indexOf((int32_t)15) == 1);
123     TEST_ASSERT(a->indexOf((int32_t)15, 2) == -1);
124     TEST_ASSERT(a->contains((int32_t)15));
125     TEST_ASSERT(!a->contains((int32_t)5));
126     delete a;
127 
128     status = U_ZERO_ERROR;
129     UVector vec(status);
130     vec.setDeleter(uprv_deleteUObject);
131     vec.adoptElement(new UnicodeString(), status);
132     vec.adoptElement(new UnicodeString(), status);
133     assertSuccess(WHERE, status);
134     assertEquals(WHERE, 2, vec.size());
135 
136     // With an incoming error, adoptElement will not add to the vector,
137     // and will delete the object. Failure here will show as a memory leak.
138     status = U_ILLEGAL_ARGUMENT_ERROR;
139     vec.adoptElement(new UnicodeString(), status);
140     assertEquals(WHERE, U_ILLEGAL_ARGUMENT_ERROR, status);
141     assertEquals(WHERE, 2, vec.size());
142 }
143 
UStack_API()144 void UVectorTest::UStack_API() {
145     UErrorCode  status = U_ZERO_ERROR;
146     UStack     *a;
147 
148     a = new UStack(status);
149     TEST_CHECK_STATUS(status);
150     delete a;
151 
152     status = U_ZERO_ERROR;
153     a = new UStack(2000, status);
154     TEST_CHECK_STATUS(status);
155     delete a;
156 
157     status = U_ZERO_ERROR;
158     a = new UStack(NULL, NULL, 2000, status);
159     TEST_CHECK_STATUS(status);
160     delete a;
161 
162     status = U_ZERO_ERROR;
163     a = new UStack(NULL, UVectorTest_compareCstrings, status);
164     TEST_ASSERT(a->empty());
165     a->push((void*)"abc", status);
166     TEST_ASSERT(!a->empty());
167     a->push((void*)"bcde", status);
168     a->push((void*)"cde", status);
169     TEST_CHECK_STATUS(status);
170     TEST_ASSERT(strcmp("cde", (const char *)a->peek()) == 0);
171     TEST_ASSERT(a->search((void*)"cde") == 1);
172     TEST_ASSERT(a->search((void*)"bcde") == 2);
173     TEST_ASSERT(a->search((void*)"abc") == 3);
174     TEST_ASSERT(strcmp("abc", (const char *)a->firstElement()) == 0);
175     TEST_ASSERT(strcmp("cde", (const char *)a->lastElement()) == 0);
176     TEST_ASSERT(strcmp("cde", (const char *)a->pop()) == 0);
177     TEST_ASSERT(strcmp("bcde", (const char *)a->pop()) == 0);
178     TEST_ASSERT(strcmp("abc", (const char *)a->pop()) == 0);
179     delete a;
180 }
181 
182 U_CDECL_BEGIN
neverTRUE(const UElement,const UElement)183 static UBool U_CALLCONV neverTRUE(const UElement /*key1*/, const UElement /*key2*/) {
184     return false;
185 }
186 
187 U_CDECL_END
188 
Hashtable_API()189 void UVectorTest::Hashtable_API() {
190     UErrorCode status = U_ZERO_ERROR;
191     Hashtable *a = new Hashtable(status);
192     TEST_ASSERT((a->puti("a", 1, status) == 0));
193     TEST_ASSERT((a->find("a") != NULL));
194     TEST_ASSERT((a->find("b") == NULL));
195     TEST_ASSERT((a->puti("b", 2, status) == 0));
196     TEST_ASSERT((a->find("b") != NULL));
197     TEST_ASSERT((a->removei("a") == 1));
198     TEST_ASSERT((a->find("a") == NULL));
199 
200     /* verify that setValueComparator works */
201     Hashtable b(status);
202     TEST_ASSERT((!a->equals(b)));
203     TEST_ASSERT((b.puti("b", 2, status) == 0));
204     TEST_ASSERT((!a->equals(b))); // Without a value comparator, this will be false by default.
205     b.setValueComparator(uhash_compareLong);
206     TEST_ASSERT((!a->equals(b)));
207     a->setValueComparator(uhash_compareLong);
208     TEST_ASSERT((a->equals(b)));
209     TEST_ASSERT((a->equals(*a))); // This better be reflexive.
210 
211     /* verify that setKeyComparator works */
212     TEST_ASSERT((a->puti("a", 1, status) == 0));
213     TEST_ASSERT((a->find("a") != NULL));
214     a->setKeyComparator(neverTRUE);
215     TEST_ASSERT((a->find("a") == NULL));
216 
217     delete a;
218 }
219 
220