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) 2005-2013, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8/*
9* File utexttst.c
10*
11* Modification History:
12*
13*   Date          Name               Description
14*   06/13/2005    Andy Heninger      Creation
15*******************************************************************************
16*/
17
18#include "unicode/utypes.h"
19#include "unicode/utext.h"
20#include "unicode/ustring.h"
21#include "cintltst.h"
22#include "memory.h"
23#include "string.h"
24
25
26static void TestAPI(void);
27void addUTextTest(TestNode** root);
28
29
30void
31addUTextTest(TestNode** root)
32{
33  addTest(root, &TestAPI           ,    "tsutil/UTextTest/TestAPI");
34}
35
36
37#define TEST_ASSERT(x) \
38   {if ((x)==FALSE) {log_err("Test failure in file %s at line %d\n", __FILE__, __LINE__);\
39                     gFailed = TRUE;\
40   }}
41
42
43#define TEST_SUCCESS(status) \
44   {if (U_FAILURE(status)) {log_err("Test failure in file %s at line %d. Error = \"%s\"\n", \
45       __FILE__, __LINE__, u_errorName(status)); \
46       gFailed = TRUE;\
47   }}
48
49
50
51/*
52 *  TestAPI   verify that the UText API is accessible from C programs.
53 *            This is not intended to be a complete test of the API functionality.  That is
54 *            in the C++ intltest program.
55 *            This test is intended to check that everything can be accessed and built in
56 *            a pure C enviornment.
57 */
58
59
60static void TestAPI(void) {
61    UErrorCode      status = U_ZERO_ERROR;
62    UBool           gFailed = FALSE;
63    (void)gFailed;   /* Suppress set but not used warning. */
64
65    /* Open    */
66    {
67        UText           utLoc = UTEXT_INITIALIZER;
68        const char *    cString = "\x61\x62\x63\x64";
69        UChar           uString[]  = {0x41, 0x42, 0x43, 0};
70        UText          *uta;
71        UText          *utb;
72        UChar           c;
73
74        uta = utext_openUChars(NULL, uString, -1, &status);
75        TEST_SUCCESS(status);
76        c = utext_next32(uta);
77        TEST_ASSERT(c == 0x41);
78        utb = utext_close(uta);
79        TEST_ASSERT(utb == NULL);
80
81        uta = utext_openUTF8(&utLoc, cString, -1, &status);
82        TEST_SUCCESS(status);
83        TEST_ASSERT(uta == &utLoc);
84
85        uta = utext_close(&utLoc);
86        TEST_ASSERT(uta == &utLoc);
87    }
88
89    /* utext_clone()  */
90    {
91        UChar   uString[]  = {0x41, 0x42, 0x43, 0};
92        int64_t len;
93        UText   *uta;
94        UText   *utb;
95
96        status = U_ZERO_ERROR;
97        uta = utext_openUChars(NULL, uString, -1, &status);
98        TEST_SUCCESS(status);
99        utb = utext_clone(NULL, uta, FALSE, FALSE, &status);
100        TEST_SUCCESS(status);
101        TEST_ASSERT(utb != NULL);
102        TEST_ASSERT(utb != uta);
103        len = utext_nativeLength(uta);
104        TEST_ASSERT(len == u_strlen(uString));
105        utext_close(uta);
106        utext_close(utb);
107    }
108
109    /* basic access functions  */
110    {
111        UChar     uString[]  = {0x41, 0x42, 0x43, 0};
112        UText     *uta;
113        UChar32   c;
114        int64_t   len;
115        UBool     b;
116        int64_t   i;
117
118        status = U_ZERO_ERROR;
119        uta = utext_openUChars(NULL, uString, -1, &status);
120        TEST_ASSERT(uta!=NULL);
121        TEST_SUCCESS(status);
122        b = utext_isLengthExpensive(uta);
123        TEST_ASSERT(b==TRUE);
124        len = utext_nativeLength(uta);
125        TEST_ASSERT(len == u_strlen(uString));
126        b = utext_isLengthExpensive(uta);
127        TEST_ASSERT(b==FALSE);
128
129        c = utext_char32At(uta, 0);
130        TEST_ASSERT(c==uString[0]);
131
132        c = utext_current32(uta);
133        TEST_ASSERT(c==uString[0]);
134
135        c = utext_next32(uta);
136        TEST_ASSERT(c==uString[0]);
137        c = utext_current32(uta);
138        TEST_ASSERT(c==uString[1]);
139
140        c = utext_previous32(uta);
141        TEST_ASSERT(c==uString[0]);
142        c = utext_current32(uta);
143        TEST_ASSERT(c==uString[0]);
144
145        c = utext_next32From(uta, 1);
146        TEST_ASSERT(c==uString[1]);
147        c = utext_next32From(uta, u_strlen(uString));
148        TEST_ASSERT(c==U_SENTINEL);
149
150        c = utext_previous32From(uta, 2);
151        TEST_ASSERT(c==uString[1]);
152        i = utext_getNativeIndex(uta);
153        TEST_ASSERT(i == 1);
154
155        utext_setNativeIndex(uta, 0);
156        b = utext_moveIndex32(uta, 1);
157        TEST_ASSERT(b==TRUE);
158        i = utext_getNativeIndex(uta);
159        TEST_ASSERT(i==1);
160
161        b = utext_moveIndex32(uta, u_strlen(uString)-1);
162        TEST_ASSERT(b==TRUE);
163        i = utext_getNativeIndex(uta);
164        TEST_ASSERT(i==u_strlen(uString));
165
166        b = utext_moveIndex32(uta, 1);
167        TEST_ASSERT(b==FALSE);
168        i = utext_getNativeIndex(uta);
169        TEST_ASSERT(i==u_strlen(uString));
170
171        utext_setNativeIndex(uta, 0);
172        c = UTEXT_NEXT32(uta);
173        TEST_ASSERT(c==uString[0]);
174        c = utext_current32(uta);
175        TEST_ASSERT(c==uString[1]);
176
177        c = UTEXT_PREVIOUS32(uta);
178        TEST_ASSERT(c==uString[0]);
179        c = UTEXT_PREVIOUS32(uta);
180        TEST_ASSERT(c==U_SENTINEL);
181
182
183        utext_close(uta);
184    }
185
186    {
187        /*
188         * UText opened on a NULL string with zero length
189         */
190        UText    *uta;
191        UChar32   c;
192
193        status = U_ZERO_ERROR;
194        uta = utext_openUChars(NULL, NULL, 0, &status);
195        TEST_SUCCESS(status);
196        c = UTEXT_NEXT32(uta);
197        TEST_ASSERT(c == U_SENTINEL);
198        utext_close(uta);
199
200        uta = utext_openUTF8(NULL, NULL, 0, &status);
201        TEST_SUCCESS(status);
202        c = UTEXT_NEXT32(uta);
203        TEST_ASSERT(c == U_SENTINEL);
204        utext_close(uta);
205    }
206
207
208    {
209        /*
210         * extract
211         */
212        UText     *uta;
213        UChar     uString[]  = {0x41, 0x42, 0x43, 0};
214        UChar     buf[100];
215        int32_t   i;
216        /* Test pinning of input bounds */
217        UChar     uString2[]  = {0x41, 0x42, 0x43, 0x44, 0x45,
218                                 0x46, 0x47, 0x48, 0x49, 0x4A, 0};
219        UChar *   uString2Ptr = uString2 + 5;
220
221        status = U_ZERO_ERROR;
222        uta = utext_openUChars(NULL, uString, -1, &status);
223        TEST_SUCCESS(status);
224
225        status = U_ZERO_ERROR;
226        i = utext_extract(uta, 0, 100, NULL, 0, &status);
227        TEST_ASSERT(status==U_BUFFER_OVERFLOW_ERROR);
228        TEST_ASSERT(i == u_strlen(uString));
229
230        status = U_ZERO_ERROR;
231        memset(buf, 0, sizeof(buf));
232        i = utext_extract(uta, 0, 100, buf, 100, &status);
233        TEST_SUCCESS(status);
234        TEST_ASSERT(i == u_strlen(uString));
235        i = u_strcmp(uString, buf);
236        TEST_ASSERT(i == 0);
237        utext_close(uta);
238
239        /* Test pinning of input bounds */
240        status = U_ZERO_ERROR;
241        uta = utext_openUChars(NULL, uString2Ptr, -1, &status);
242        TEST_SUCCESS(status);
243
244        status = U_ZERO_ERROR;
245        memset(buf, 0, sizeof(buf));
246        i = utext_extract(uta, -3, 20, buf, 100, &status);
247        TEST_SUCCESS(status);
248        TEST_ASSERT(i == u_strlen(uString2Ptr));
249        i = u_strcmp(uString2Ptr, buf);
250        TEST_ASSERT(i == 0);
251        utext_close(uta);
252    }
253
254    {
255        /*
256         *  Copy, Replace, isWritable
257         *    Can't create an editable UText from plain C, so all we
258         *    can easily do is check that errors returned.
259         */
260        UText     *uta;
261        UChar     uString[]  = {0x41, 0x42, 0x43, 0};
262        UBool     b;
263
264        status = U_ZERO_ERROR;
265        uta = utext_openUChars(NULL, uString, -1, &status);
266        TEST_SUCCESS(status);
267
268        b = utext_isWritable(uta);
269        TEST_ASSERT(b == FALSE);
270
271        b = utext_hasMetaData(uta);
272        TEST_ASSERT(b == FALSE);
273
274        utext_replace(uta,
275                      0, 1,     /* start, limit */
276                      uString, -1,  /* replacement, replacement length */
277                      &status);
278        TEST_ASSERT(status == U_NO_WRITE_PERMISSION);
279
280
281        utext_copy(uta,
282                   0, 1,         /* start, limit      */
283                   2,            /* destination index */
284                   FALSE,        /* move flag         */
285                   &status);
286        TEST_ASSERT(status == U_NO_WRITE_PERMISSION);
287
288        utext_close(uta);
289    }
290
291
292}
293
294