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//---------------------------------------------------------------------------
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) \
61    if (U_FAILURE(status)) {\
62        errln("UVectorTest failure at line %d.  status=%s\n", __LINE__, u_errorName(status));\
63        return;\
64    }
65
66#define TEST_ASSERT(expr) \
67    if ((expr)==FALSE) {\
68        errln("UVectorTest failure at line %d.\n", __LINE__);\
69    }
70
71static int8_t U_CALLCONV
72UVectorTest_compareInt32(UElement key1, UElement key2) {
73    if (key1.integer > key2.integer) {
74        return 1;
75    }
76    else if (key1.integer < key2.integer) {
77        return -1;
78    }
79    return 0;
80}
81
82U_CDECL_BEGIN
83static int8_t U_CALLCONV
84UVectorTest_compareCstrings(const UElement key1, const UElement key2) {
85    return !strcmp((const char *)key1.pointer, (const char *)key2.pointer);
86}
87U_CDECL_END
88
89//---------------------------------------------------------------------------
90//
91//      UVector_API      Check for basic functionality of UVector.
92//
93//---------------------------------------------------------------------------
94void UVectorTest::UVector_API() {
95
96    UErrorCode  status = U_ZERO_ERROR;
97    UVector     *a;
98
99    a = new UVector(status);
100    TEST_CHECK_STATUS(status);
101    delete a;
102
103    status = U_ZERO_ERROR;
104    a = new UVector(2000, status);
105    TEST_CHECK_STATUS(status);
106    delete a;
107
108    status = U_ZERO_ERROR;
109    a = new UVector(status);
110    a->sortedInsert((int32_t)10, UVectorTest_compareInt32, status);
111    a->sortedInsert((int32_t)20, UVectorTest_compareInt32, status);
112    a->sortedInsert((int32_t)30, UVectorTest_compareInt32, status);
113    a->sortedInsert((int32_t)15, UVectorTest_compareInt32, status);
114    TEST_CHECK_STATUS(status);
115    TEST_ASSERT(a->elementAti(0) == 10);
116    TEST_ASSERT(a->elementAti(1) == 15);
117    TEST_ASSERT(a->elementAti(2) == 20);
118    TEST_ASSERT(a->elementAti(3) == 30);
119    TEST_ASSERT(a->indexOf((int32_t)3) == -1);
120    TEST_ASSERT(a->indexOf((int32_t)15) == 1);
121    TEST_ASSERT(a->indexOf((int32_t)15, 2) == -1);
122    TEST_ASSERT(a->contains((int32_t)15));
123    TEST_ASSERT(!a->contains((int32_t)5));
124    delete a;
125}
126
127void UVectorTest::UStack_API() {
128    UErrorCode  status = U_ZERO_ERROR;
129    UStack     *a;
130
131    a = new UStack(status);
132    TEST_CHECK_STATUS(status);
133    delete a;
134
135    status = U_ZERO_ERROR;
136    a = new UStack(2000, status);
137    TEST_CHECK_STATUS(status);
138    delete a;
139
140    status = U_ZERO_ERROR;
141    a = new UStack(NULL, NULL, 2000, status);
142    TEST_CHECK_STATUS(status);
143    delete a;
144
145    status = U_ZERO_ERROR;
146    a = new UStack(NULL, UVectorTest_compareCstrings, status);
147    TEST_ASSERT(a->empty());
148    a->push((void*)"abc", status);
149    TEST_ASSERT(!a->empty());
150    a->push((void*)"bcde", status);
151    a->push((void*)"cde", status);
152    TEST_CHECK_STATUS(status);
153    TEST_ASSERT(strcmp("cde", (const char *)a->peek()) == 0);
154    TEST_ASSERT(a->search((void*)"cde") == 1);
155    TEST_ASSERT(a->search((void*)"bcde") == 2);
156    TEST_ASSERT(a->search((void*)"abc") == 3);
157    TEST_ASSERT(strcmp("abc", (const char *)a->firstElement()) == 0);
158    TEST_ASSERT(strcmp("cde", (const char *)a->lastElement()) == 0);
159    TEST_ASSERT(strcmp("cde", (const char *)a->pop()) == 0);
160    TEST_ASSERT(strcmp("bcde", (const char *)a->pop()) == 0);
161    TEST_ASSERT(strcmp("abc", (const char *)a->pop()) == 0);
162    delete a;
163}
164
165U_CDECL_BEGIN
166static UBool U_CALLCONV neverTRUE(const UElement /*key1*/, const UElement /*key2*/) {
167    return FALSE;
168}
169
170U_CDECL_END
171
172void UVectorTest::Hashtable_API() {
173    UErrorCode status = U_ZERO_ERROR;
174    Hashtable *a = new Hashtable(status);
175    TEST_ASSERT((a->puti("a", 1, status) == 0));
176    TEST_ASSERT((a->find("a") != NULL));
177    TEST_ASSERT((a->find("b") == NULL));
178    TEST_ASSERT((a->puti("b", 2, status) == 0));
179    TEST_ASSERT((a->find("b") != NULL));
180    TEST_ASSERT((a->removei("a") == 1));
181    TEST_ASSERT((a->find("a") == NULL));
182
183    /* verify that setValueComparator works */
184    Hashtable b(status);
185    TEST_ASSERT((!a->equals(b)));
186    TEST_ASSERT((b.puti("b", 2, status) == 0));
187    TEST_ASSERT((!a->equals(b))); // Without a value comparator, this will be FALSE by default.
188    b.setValueComparator(uhash_compareLong);
189    TEST_ASSERT((!a->equals(b)));
190    a->setValueComparator(uhash_compareLong);
191    TEST_ASSERT((a->equals(b)));
192    TEST_ASSERT((a->equals(*a))); // This better be reflexive.
193
194    /* verify that setKeyComparator works */
195    TEST_ASSERT((a->puti("a", 1, status) == 0));
196    TEST_ASSERT((a->find("a") != NULL));
197    a->setKeyComparator(neverTRUE);
198    TEST_ASSERT((a->find("a") == NULL));
199
200    delete a;
201}
202
203