blob: 51351e1835005435ed3300ae70b6221939546b76 [file] [log] [blame]
jeffhao5d1ac922011-09-29 17:41:15 -07001/*
2 * Copyright (C) 2007 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 */
16
17import junit.framework.Assert;
Jeff Hao848f70a2014-01-15 13:49:50 -080018import java.lang.reflect.Method;
jeffhao5d1ac922011-09-29 17:41:15 -070019
20/**
21 * more string tests
22 */
23public class Main {
Jeff Hao848f70a2014-01-15 13:49:50 -080024 public static void main(String args[]) throws Exception {
jeffhao5d1ac922011-09-29 17:41:15 -070025 String test = "0123456789";
26 String test1 = new String("0123456789"); // different object
27 String test2 = new String("0123456780"); // different value
28 String offset = new String("xxx0123456789yyy");
29 String sub = offset.substring(3, 13);
30 Object blah = new Object();
31
32 Assert.assertTrue(test.equals(test));
33 Assert.assertTrue(test.equals(test1));
34 Assert.assertFalse(test.equals(test2));
35
36 Assert.assertEquals(test.compareTo(test1), 0);
37 Assert.assertTrue(test1.compareTo(test2) > 0);
38 Assert.assertTrue(test2.compareTo(test1) < 0);
39
Alexei Zavjalov4554bfd2014-02-26 17:28:35 +070040 Assert.assertEquals("".compareTo(""), 0);
41 Assert.assertTrue(test.compareTo("") > 0);
42 Assert.assertTrue("".compareTo(test) < 0);
43
jeffhao5d1ac922011-09-29 17:41:15 -070044 /* compare string with a nonzero offset, in left/right side */
45 Assert.assertEquals(test.compareTo(sub), 0);
46 Assert.assertEquals(sub.compareTo(test), 0);
47 Assert.assertTrue(test.equals(sub));
48 Assert.assertTrue(sub.equals(test));
49 /* same base, one is a substring */
50 Assert.assertFalse(offset.equals(sub));
51 Assert.assertFalse(sub.equals(offset));
52 /* wrong class */
53 Assert.assertFalse(test.equals(blah));
54
55 /* null ptr - throw */
56 try {
57 test.compareTo(null);
58 Assert.fail("didn't get expected npe");
59 } catch (NullPointerException npe) {
60 System.out.println("Got expected npe");
61 }
62 /* null ptr - ok */
63 Assert.assertFalse(test.equals(null));
64
65 test = test.substring(1);
66 Assert.assertTrue(test.equals("123456789"));
67 Assert.assertFalse(test.equals(test1));
68
69 test = test.substring(1);
70 Assert.assertTrue(test.equals("23456789"));
71
72 test = test.substring(1);
73 Assert.assertTrue(test.equals("3456789"));
74
75 test = test.substring(1);
76 Assert.assertTrue(test.equals("456789"));
77
78 test = test.substring(3,5);
79 Assert.assertTrue(test.equals("78"));
80
81 test = "this/is/a/path";
82 String[] strings = test.split("/");
83 Assert.assertEquals(4, strings.length);
84
85 Assert.assertEquals("this is a path", test.replaceAll("/", " "));
86 Assert.assertEquals("this is a path", test.replace("/", " "));
Jeff Hao848f70a2014-01-15 13:49:50 -080087
Andreas Gampe166aaee2016-07-18 08:27:23 -070088 Class<?> Strings = Class.forName("com.android.org.bouncycastle.util.Strings");
Jeff Hao848f70a2014-01-15 13:49:50 -080089 Method fromUTF8ByteArray = Strings.getDeclaredMethod("fromUTF8ByteArray", byte[].class);
90 String result = (String) fromUTF8ByteArray.invoke(null, new byte[] {'O', 'K'});
91 System.out.println(result);
Vladimir Marko9c9883b2016-10-17 14:45:29 +010092
93 testCompareToAndEquals();
94 testIndexOf();
jeffhao5d1ac922011-09-29 17:41:15 -070095 }
Vladimir Marko9c9883b2016-10-17 14:45:29 +010096
97 public static void testCompareToAndEquals() {
98 String[] strings = {
99 // Special: empty string.
100 "",
101 // Category 0, ASCII strings:
102 // "0123456789abcdef".substring(0, index + 1)
103 "0",
104 "01",
105 "012",
106 "0123",
107 "01234",
108 "012345",
109 "0123456",
110 "01234567",
111 "012345678",
112 "0123456789",
113 "0123456789a",
114 "0123456789ab",
115 "0123456789abc",
116 "0123456789abcd",
117 "0123456789abcde",
118 "0123456789abcdef",
119 // Category 1, ASCII strings:
120 // "0123456789abcdef".substring(0, index) + "x"
121 "x",
122 "0x",
123 "01x",
124 "012x",
125 "0123x",
126 "01234x",
127 "012345x",
128 "0123456x",
129 "01234567x",
130 "012345678x",
131 "0123456789x",
132 "0123456789ax",
133 "0123456789abx",
134 "0123456789abcx",
135 "0123456789abcdx",
136 "0123456789abcdex",
137 // Category 2, ASCII strings,
138 // "0123456789abcdef".substring(0, index) + "x" +
139 // "0123456789abcdef".substring(index + 1)
140 "x123456789abcdef",
141 "0x23456789abcdef",
142 "01x3456789abcdef",
143 "012x456789abcdef",
144 "0123x56789abcdef",
145 "01234x6789abcdef",
146 "012345x789abcdef",
147 "0123456x89abcdef",
148 "01234567x9abcdef",
149 "012345678xabcdef",
150 "0123456789xbcdef",
151 "0123456789axcdef",
152 "0123456789abxdef",
153 "0123456789abcxef",
154 "0123456789abcdxf",
155 "0123456789abcdex",
156 // Category 3, ASCII strings:
157 // "z" + "0123456789abcdef".substring(1, index + 1)
158 "z",
159 "z1",
160 "z12",
161 "z123",
162 "z1234",
163 "z12345",
164 "z123456",
165 "z1234567",
166 "z12345678",
167 "z123456789",
168 "z123456789a",
169 "z123456789ab",
170 "z123456789abc",
171 "z123456789abcd",
172 "z123456789abcde",
173 "z123456789abcdef",
174 // Category 4, non-ASCII strings:
175 // "0123456789abcdef".substring(0, index) + "\u0440"
176 "\u0440",
177 "0\u0440",
178 "01\u0440",
179 "012\u0440",
180 "0123\u0440",
181 "01234\u0440",
182 "012345\u0440",
183 "0123456\u0440",
184 "01234567\u0440",
185 "012345678\u0440",
186 "0123456789\u0440",
187 "0123456789a\u0440",
188 "0123456789ab\u0440",
189 "0123456789abc\u0440",
190 "0123456789abcd\u0440",
191 "0123456789abcde\u0440",
192 // Category 5, non-ASCII strings:
193 // "0123456789abcdef".substring(0, index) + "\u0440" +
194 // "0123456789abcdef".substring(index + 1)
195 "\u0440123456789abcdef",
196 "0\u044023456789abcdef",
197 "01\u04403456789abcdef",
198 "012\u0440456789abcdef",
199 "0123\u044056789abcdef",
200 "01234\u04406789abcdef",
201 "012345\u0440789abcdef",
202 "0123456\u044089abcdef",
203 "01234567\u04409abcdef",
204 "012345678\u0440abcdef",
205 "0123456789\u0440bcdef",
206 "0123456789a\u0440cdef",
207 "0123456789ab\u0440def",
208 "0123456789abc\u0440ef",
209 "0123456789abcd\u0440f",
210 "0123456789abcde\u0440",
211 // Category 6, ASCII strings:
212 // "\u0443" + "0123456789abcdef".substring(1, index + 1)
213 "\u0443",
214 "\u04431",
215 "\u044312",
216 "\u0443123",
217 "\u04431234",
218 "\u044312345",
219 "\u0443123456",
220 "\u04431234567",
221 "\u044312345678",
222 "\u0443123456789",
223 "\u0443123456789a",
224 "\u0443123456789ab",
225 "\u0443123456789abc",
226 "\u0443123456789abcd",
227 "\u0443123456789abcde",
228 "\u0443123456789abcdef",
229 // Category 7, non-ASCII strings:
230 // "0123456789abcdef".substring(0, index) + "\u0482"
231 "\u0482",
232 "0\u0482",
233 "01\u0482",
234 "012\u0482",
235 "0123\u0482",
236 "01234\u0482",
237 "012345\u0482",
238 "0123456\u0482",
239 "01234567\u0482",
240 "012345678\u0482",
241 "0123456789\u0482",
242 "0123456789a\u0482",
243 "0123456789ab\u0482",
244 "0123456789abc\u0482",
245 "0123456789abcd\u0482",
246 "0123456789abcde\u0482",
247 // Category 8, non-ASCII strings:
248 // "0123456789abcdef".substring(0, index) + "\u0482" +
249 // "0123456789abcdef".substring(index + 1)
250 "\u0482123456789abcdef",
251 "0\u048223456789abcdef",
252 "01\u04823456789abcdef",
253 "012\u0482456789abcdef",
254 "0123\u048256789abcdef",
255 "01234\u04826789abcdef",
256 "012345\u0482789abcdef",
257 "0123456\u048289abcdef",
258 "01234567\u04829abcdef",
259 "012345678\u0482abcdef",
260 "0123456789\u0482bcdef",
261 "0123456789a\u0482cdef",
262 "0123456789ab\u0482def",
263 "0123456789abc\u0482ef",
264 "0123456789abcd\u0482f",
265 "0123456789abcde\u0482",
266 // Category 9, ASCII strings:
267 // "\u0489" + "0123456789abcdef".substring(1, index + 1)
268 "\u0489",
269 "\u04891",
270 "\u048912",
271 "\u0489123",
272 "\u04891234",
273 "\u048912345",
274 "\u0489123456",
275 "\u04891234567",
276 "\u048912345678",
277 "\u0489123456789",
278 "\u0489123456789a",
279 "\u0489123456789ab",
280 "\u0489123456789abc",
281 "\u0489123456789abcd",
282 "\u0489123456789abcde",
283 "\u0489123456789abcdef",
284 };
285 int length = strings.length;
286 Assert.assertEquals(1 + 16 * 10, length);
287 for (int i = 0; i != length; ++i) {
288 String lhs = strings[i];
289 for (int j = 0; j != length; ++j) {
290 String rhs = strings[j];
291 int result = $noinline$compareTo(lhs, rhs);
292 final int expected;
293 if (i == 0 || j == 0 || i == j) {
294 // One of the strings is empty or the strings are the same.
295 expected = lhs.length() - rhs.length();
296 } else {
297 int i_category = (i - 1) / 16;
298 int i_index = (i - 1) % 16;
299 int j_category = (j - 1) / 16;
300 int j_index = (j - 1) % 16;
301 int min_ij_index = (i_index < j_index) ? i_index : j_index;
302 if (i_category == j_category) {
303 switch (i_category) {
304 case 0: case 3: case 6: case 9:
305 // Differs in length.
306 expected = lhs.length() - rhs.length();
307 break;
308 case 1: case 2: case 4: case 5: case 7: case 8:
309 // Differs in charAt(min_ij_index).
310 expected = lhs.charAt(min_ij_index) - rhs.charAt(min_ij_index);
311 break;
312 default: throw new Error("Unexpected category.");
313 }
314 } else if (i_category == 3 || i_category == 6 || i_category == 9 ||
315 j_category == 3 || j_category == 6 || j_category == 9) {
316 // In these categories, charAt(0) differs from other categories' strings.
317 expected = lhs.charAt(0) - rhs.charAt(0);
318 } else if (// Category 0 string is a prefix to any longer string in
319 // remaining categories.
320 (i_category == 0 && i_index < j_index) ||
321 (j_category == 0 && j_index < i_index) ||
322 // Category 2 string is a prefix to category 3 string at the same
323 // index. Similar for categories 4 and 5 and also 7 and 8.
324 // This includes matching last strings of these pairs of categories.
325 (i_index == j_index &&
326 ((i_category == 1 && j_category == 2) ||
327 (i_category == 2 && j_category == 1) ||
328 (i_category == 4 && j_category == 5) ||
329 (i_category == 5 && j_category == 4) ||
330 (i_category == 7 && j_category == 8) ||
331 (i_category == 8 && j_category == 7)))) {
332 // Differs in length.
333 expected = lhs.length() - rhs.length();
334 } else {
335 // The remaining cases differ in charAt(min_ij_index), the characters
336 // before that are "0123456789abcdef".substring(0, min_ij_index).
337 for (int k = 0; k < min_ij_index; ++k) {
338 Assert.assertEquals("0123456789abcdef".charAt(k), lhs.charAt(k));
339 Assert.assertEquals("0123456789abcdef".charAt(k), rhs.charAt(k));
340 }
341 expected = lhs.charAt(min_ij_index) - rhs.charAt(min_ij_index);
342 Assert.assertFalse(expected == 0);
343 }
344 }
345 if (expected != result) {
346 throw new Error(
347 "Mismatch at i=" + i + ", j=" + j + ", expected=" + expected +
348 ", result=" + result);
349 }
350 boolean equalsExpected =
351 (i == j) ||
352 // Last string in categories 1 and 2.
353 (i == 32 && j == 48) || (i == 48 && j == 32) ||
354 // Last string in categories 4 and 5.
355 (i == 80 && j == 96) || (i == 96 && j == 80) ||
356 // Last string in categories 7 and 8.
357 (i == 128 && j == 144) || (i == 144 && j == 128);
358 Assert.assertEquals(equalsExpected, $noinline$equals(lhs, rhs));
359 }
360 }
361
362 try {
363 $noinline$compareTo("", null);
364 Assert.fail();
365 } catch (NullPointerException expected) {
366 }
367 try {
368 $noinline$compareTo(null, "");
369 Assert.fail();
370 } catch (NullPointerException expected) {
371 }
372
373 Assert.assertFalse($noinline$equals("", null));
374 try {
375 $noinline$equals(null, "");
376 Assert.fail();
377 } catch (NullPointerException expected) {
378 }
379 }
380
381 public static void testIndexOf() {
382 String[] prefixes = {
383 "",
384 "0",
385 "01",
386 "012",
387 "0123",
388 "01234",
389 "012345",
390 "0123456",
391 "01234567",
392 "012345678",
393 "0123456789",
394 "0123456789a",
395 "0123456789ab",
396 "0123456789abc",
397 "0123456789abcd",
398 "0123456789abcdef",
399 };
400 String[] cores = {
401 "",
402 "x",
403 "xx",
404 "xxx",
405 "xxxx",
406 "xxxxx",
407 "xxxxxx",
408 "xxxxxxx",
409 "xxxxxxxx",
410 "xzx",
411 "xxzx",
412 "xxxzx",
413 "xxxxzx",
414 "xxxxxzx",
415 "xxxxxxzx",
416 "xxxxxxxzx",
417 "xxxxxxxxzx",
418 "\u0440",
419 "\u0440\u0440",
420 "\u0440\u0440\u0440",
421 "\u0440\u0440\u0440\u0440",
422 "\u0440\u0440\u0440\u0440\u0440",
423 "\u0440\u0440\u0440\u0440\u0440\u0440",
424 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440",
425 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440\u0440",
426 "\u0440z\u0440",
427 "\u0440\u0440z\u0440",
428 "\u0440\u0440\u0440z\u0440",
429 "\u0440\u0440\u0440\u0440z\u0440",
430 "\u0440\u0440\u0440\u0440\u0440z\u0440",
431 "\u0440\u0440\u0440\u0440\u0440\u0440z\u0440",
432 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440z\u0440",
433 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440\u0440z\u0440",
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100434 "\u0000",
435 "\u0000\u0000",
436 "\u0000\u0000\u0000",
437 "\u0000\u0000\u0000\u0000",
438 "\u0000\u0000\u0000\u0000\u0000",
439 "\u0000\u0000\u0000\u0000\u0000\u0000",
440 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
441 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
442 "\u0000z\u0000",
443 "\u0000\u0000z\u0000",
444 "\u0000\u0000\u0000z\u0000",
445 "\u0000\u0000\u0000\u0000z\u0000",
446 "\u0000\u0000\u0000\u0000\u0000z\u0000",
447 "\u0000\u0000\u0000\u0000\u0000\u0000z\u0000",
448 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000z\u0000",
449 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000z\u0000",
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100450 };
451 String[] suffixes = {
452 "",
453 "y",
454 "yy",
455 "yyy",
456 "yyyy",
457 "yyyyy",
458 "yyyyyy",
459 "yyyyyyy",
460 "yyyyyyyy",
461 "\u0441",
462 "y\u0441",
463 "yy\u0441",
464 "yyy\u0441",
465 "yyyy\u0441",
466 "yyyyy\u0441",
467 "yyyyyy\u0441",
468 "yyyyyyy\u0441",
469 "yyyyyyyy\u0441",
470 };
471 for (String p : prefixes) {
472 for (String c : cores) {
473 for (String s : suffixes) {
474 String full = p + c + s;
475 int expX = (c.isEmpty() || c.charAt(0) != 'x') ? -1 : p.length();
476 int exp0440 = (c.isEmpty() || c.charAt(0) != '\u0440') ? -1 : p.length();
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100477 int exp0000 = (c.isEmpty() || c.charAt(0) != '\u0000') ? -1 : p.length();
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100478 Assert.assertEquals(expX, $noinline$indexOf(full, 'x'));
479 Assert.assertEquals(exp0440, $noinline$indexOf(full, '\u0440'));
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100480 Assert.assertEquals(exp0000, $noinline$indexOf(full, '\u0000'));
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100481 Assert.assertEquals(expX, $noinline$indexOf(full, 'x', -1));
482 Assert.assertEquals(exp0440, $noinline$indexOf(full, '\u0440', -1));
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100483 Assert.assertEquals(exp0000, $noinline$indexOf(full, '\u0000', -1));
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100484 Assert.assertEquals(-1, $noinline$indexOf(full, 'x', full.length() + 1));
485 Assert.assertEquals(-1, $noinline$indexOf(full, '\u0440', full.length() + 1));
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100486 Assert.assertEquals(-1, $noinline$indexOf(full, '\u0000', full.length() + 1));
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100487 for (int from = 0; from != full.length(); ++from) {
488 final int eX;
489 final int e0440;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100490 final int e0000;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100491 if (from <= p.length()) {
492 eX = expX;
493 e0440 = exp0440;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100494 e0000 = exp0000;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100495 } else if (from >= p.length() + c.length()) {
496 eX = -1;
497 e0440 = -1;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100498 e0000 = -1;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100499 } else if (full.charAt(from) == 'z') {
500 eX = (full.charAt(from + 1) != 'x') ? -1 : from + 1;
501 e0440 = (full.charAt(from + 1) != '\u0440') ? -1 : from + 1;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100502 e0000 = (full.charAt(from + 1) != '\u0000') ? -1 : from + 1;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100503 } else {
504 eX = (full.charAt(from) != 'x') ? -1 : from;
505 e0440 = (full.charAt(from) != '\u0440') ? -1 : from;
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100506 e0000 = (full.charAt(from) != '\u0000') ? -1 : from;
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100507 }
508 Assert.assertEquals(eX, $noinline$indexOf(full, 'x', from));
509 Assert.assertEquals(e0440, $noinline$indexOf(full, '\u0440', from));
Vladimir Markofdaf0f42016-10-13 19:29:53 +0100510 Assert.assertEquals(e0000, $noinline$indexOf(full, '\u0000', from));
Vladimir Marko9c9883b2016-10-17 14:45:29 +0100511 }
512 }
513 }
514 }
515 }
516
517 public static int $noinline$compareTo(String lhs, String rhs) {
518 if (doThrow) { throw new Error(); }
519 return lhs.compareTo(rhs);
520 }
521
522 public static boolean $noinline$equals(String lhs, String rhs) {
523 if (doThrow) { throw new Error(); }
524 return lhs.equals(rhs);
525 }
526
527 public static int $noinline$indexOf(String lhs, int ch) {
528 if (doThrow) { throw new Error(); }
529 return lhs.indexOf(ch);
530 }
531
532 public static int $noinline$indexOf(String lhs, int ch, int fromIndex) {
533 if (doThrow) { throw new Error(); }
534 return lhs.indexOf(ch, fromIndex);
535 }
536
537 public static boolean doThrow = false;
jeffhao5d1ac922011-09-29 17:41:15 -0700538}