blob: 058da1808eb941e137e08de176c9ee2d811d352a [file] [log] [blame]
Frank Tang3e05d9d2021-11-08 14:04:04 -08001// © 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//---------------------------------------------------------------------------
24UVectorTest::UVectorTest()
25{
26}
27
28
29UVectorTest::~UVectorTest()
30{
31}
32
33
34
35void 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 {\
Frank Tang1f164ee2022-11-08 12:31:27 -080068 if ((expr)==false) {\
Frank Tang3e05d9d2021-11-08 14:04:04 -080069 errln("UVectorTest failure at line %d.\n", __LINE__);\
70 }\
71} UPRV_BLOCK_MACRO_END
72
73static int32_t U_CALLCONV
74UVectorTest_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
84U_CDECL_BEGIN
85static int8_t U_CALLCONV
86UVectorTest_compareCstrings(const UElement key1, const UElement key2) {
87 return !strcmp((const char *)key1.pointer, (const char *)key2.pointer);
88}
89U_CDECL_END
90
91//---------------------------------------------------------------------------
92//
93// UVector_API Check for basic functionality of UVector.
94//
95//---------------------------------------------------------------------------
96void 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
144void 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
182U_CDECL_BEGIN
183static UBool U_CALLCONV neverTRUE(const UElement /*key1*/, const UElement /*key2*/) {
Frank Tang1f164ee2022-11-08 12:31:27 -0800184 return false;
Frank Tang3e05d9d2021-11-08 14:04:04 -0800185}
186
187U_CDECL_END
188
189void 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));
Frank Tang1f164ee2022-11-08 12:31:27 -0800204 TEST_ASSERT((!a->equals(b))); // Without a value comparator, this will be false by default.
Frank Tang3e05d9d2021-11-08 14:04:04 -0800205 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