View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang3;
18  
19  import static org.apache.commons.lang3.Supplementary.CharU20000;
20  import static org.apache.commons.lang3.Supplementary.CharU20001;
21  import static org.apache.commons.lang3.Supplementary.CharUSuppCharHigh;
22  import static org.apache.commons.lang3.Supplementary.CharUSuppCharLow;
23  import static org.junit.jupiter.api.Assertions.assertEquals;
24  import static org.junit.jupiter.api.Assertions.assertFalse;
25  import static org.junit.jupiter.api.Assertions.assertNotEquals;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  import static org.junit.jupiter.params.provider.Arguments.arguments;
28  
29  import java.nio.CharBuffer;
30  import java.util.Locale;
31  import java.util.stream.Stream;
32  
33  import org.junit.jupiter.api.Test;
34  import org.junit.jupiter.params.ParameterizedTest;
35  import org.junit.jupiter.params.provider.Arguments;
36  import org.junit.jupiter.params.provider.MethodSource;
37  
38  /**
39   * Tests {@link StringUtils} - Equals/IndexOf methods
40   */
41  class StringUtilsEqualsIndexOfTest extends AbstractLangTest {
42  
43      // The purpose of this class is to test StringUtils#equals(CharSequence, CharSequence)
44      // with a CharSequence implementation whose equals(Object) override requires that the
45      // other object be an instance of CustomCharSequence, even though, as char sequences,
46      // `seq` may equal the other object.
47      private static final class CustomCharSequence implements CharSequence {
48          private final CharSequence seq;
49  
50          CustomCharSequence(final CharSequence seq) {
51              this.seq = seq;
52          }
53  
54          @Override
55          public char charAt(final int index) {
56              return seq.charAt(index);
57          }
58  
59          @Override
60          public boolean equals(final Object obj) {
61              if (!(obj instanceof CustomCharSequence)) {
62                  return false;
63              }
64              final CustomCharSequence other = (CustomCharSequence) obj;
65              return seq.equals(other.seq);
66          }
67  
68          @Override
69          public int hashCode() {
70              return seq.hashCode();
71          }
72  
73          @Override
74          public int length() {
75              return seq.length();
76          }
77  
78          @Override
79          public CharSequence subSequence(final int start, final int end) {
80              return new CustomCharSequence(seq.subSequence(start, end));
81          }
82  
83          @Override
84          public String toString() {
85              return seq.toString();
86          }
87      }
88  
89      private static final String BAR = "bar";
90  
91      private static final String FOO = "foo";
92  
93      private static final String FOOBAR = "foobar";
94  
95      private static final String[] FOOBAR_SUB_ARRAY = {"ob", "ba"};
96  
97      static Stream<Arguments> indexOfAnyBut_withSurrogateChars() {
98          // @formatter:off
99          return Stream.of(
100             arguments(CharU20000 + CharU20001,    CharU20000, 2),
101             arguments(CharU20000 + CharU20001,    CharU20001, 0),
102             arguments(CharU20000 + CharU20001,    "abcd" + CharUSuppCharLow, 0),
103             arguments(CharU20000 + CharU20001,    "abcd" + CharUSuppCharHigh, 0),
104             arguments(CharU20000,                 CharU20000, -1),
105             arguments(CharU20000,                 CharU20001, 0),
106             arguments(CharUSuppCharHigh + "aaaa", CharUSuppCharHigh + "abcd", -1),
107             arguments(CharUSuppCharHigh + "baaa", CharUSuppCharHigh + "abcd", -1),
108             arguments(CharUSuppCharHigh + "aaaa", CharU20000 + "abcd", 0),
109             arguments("aaaa" + CharUSuppCharHigh, CharU20000 + "abcd", 4),
110             arguments(CharUSuppCharLow + "aaaa",  CharU20000 + "abcd", 0),
111             arguments("aaaa" + CharUSuppCharLow,  CharU20000 + "abcd", 4),
112             arguments(CharU20000 + "aaaa",        CharUSuppCharLow + "ab" + CharUSuppCharHigh + "cd", 0),
113             arguments(CharU20000 + "aaaa",        "abcd", 0),
114             arguments(CharU20000 + "aaaa",        "abcd" + CharUSuppCharHigh, 0),
115             arguments(CharU20000 + "aaaa",        "abcd" + CharUSuppCharLow, 0),
116             arguments("aaaa" + CharU20000,        CharU20000 + "abcd", -1)
117         );
118         // @formatter:on
119     }
120 
121     @Test
122     void testCompare_StringString() {
123         assertEquals(0, StringUtils.compare(null, null));
124         assertTrue(StringUtils.compare(null, "a") < 0);
125         assertTrue(StringUtils.compare("a", null) > 0);
126         assertEquals(0, StringUtils.compare("abc", "abc"));
127         assertTrue(StringUtils.compare("a", "b") < 0);
128         assertTrue(StringUtils.compare("b", "a") > 0);
129         assertTrue(StringUtils.compare("a", "B") > 0);
130         assertTrue(StringUtils.compare("abc", "abd") < 0);
131         assertTrue(StringUtils.compare("ab", "abc") < 0);
132         assertTrue(StringUtils.compare("ab", "ab ") < 0);
133         assertTrue(StringUtils.compare("abc", "ab ") > 0);
134     }
135 
136     @Test
137     void testCompare_StringStringBoolean() {
138         assertEquals(0, StringUtils.compare(null, null, false));
139         assertTrue(StringUtils.compare(null, "a", true) < 0);
140         assertTrue(StringUtils.compare(null, "a", false) > 0);
141         assertTrue(StringUtils.compare("a", null, true) > 0);
142         assertTrue(StringUtils.compare("a", null, false) < 0);
143         assertEquals(0, StringUtils.compare("abc", "abc", false));
144         assertTrue(StringUtils.compare("a", "b", false) < 0);
145         assertTrue(StringUtils.compare("b", "a", false) > 0);
146         assertTrue(StringUtils.compare("a", "B", false) > 0);
147         assertTrue(StringUtils.compare("abc", "abd", false) < 0);
148         assertTrue(StringUtils.compare("ab", "abc", false) < 0);
149         assertTrue(StringUtils.compare("ab", "ab ", false) < 0);
150         assertTrue(StringUtils.compare("abc", "ab ", false) > 0);
151     }
152 
153     @Test
154     void testCompareIgnoreCase_StringString() {
155         assertEquals(0, StringUtils.compareIgnoreCase(null, null));
156         assertTrue(StringUtils.compareIgnoreCase(null, "a") < 0);
157         assertTrue(StringUtils.compareIgnoreCase("a", null) > 0);
158         assertEquals(0, StringUtils.compareIgnoreCase("abc", "abc"));
159         assertEquals(0, StringUtils.compareIgnoreCase("abc", "ABC"));
160         assertTrue(StringUtils.compareIgnoreCase("a", "b") < 0);
161         assertTrue(StringUtils.compareIgnoreCase("b", "a") > 0);
162         assertTrue(StringUtils.compareIgnoreCase("a", "B") < 0);
163         assertTrue(StringUtils.compareIgnoreCase("A", "b") < 0);
164         assertTrue(StringUtils.compareIgnoreCase("abc", "ABD") < 0);
165         assertTrue(StringUtils.compareIgnoreCase("ab", "ABC") < 0);
166         assertTrue(StringUtils.compareIgnoreCase("ab", "AB ") < 0);
167         assertTrue(StringUtils.compareIgnoreCase("abc", "AB ") > 0);
168     }
169 
170     @Test
171     void testCompareIgnoreCase_StringStringBoolean() {
172         assertEquals(0, StringUtils.compareIgnoreCase(null, null, false));
173         assertTrue(StringUtils.compareIgnoreCase(null, "a", true) < 0);
174         assertTrue(StringUtils.compareIgnoreCase(null, "a", false) > 0);
175         assertTrue(StringUtils.compareIgnoreCase("a", null, true) > 0);
176         assertTrue(StringUtils.compareIgnoreCase("a", null, false) < 0);
177         assertEquals(0, StringUtils.compareIgnoreCase("abc", "abc", false));
178         assertEquals(0, StringUtils.compareIgnoreCase("abc", "ABC", false));
179         assertTrue(StringUtils.compareIgnoreCase("a", "b", false) < 0);
180         assertTrue(StringUtils.compareIgnoreCase("b", "a", false) > 0);
181         assertTrue(StringUtils.compareIgnoreCase("a", "B", false) < 0);
182         assertTrue(StringUtils.compareIgnoreCase("A", "b", false) < 0);
183         assertTrue(StringUtils.compareIgnoreCase("abc", "ABD", false) < 0);
184         assertTrue(StringUtils.compareIgnoreCase("ab", "ABC", false) < 0);
185         assertTrue(StringUtils.compareIgnoreCase("ab", "AB ", false) < 0);
186         assertTrue(StringUtils.compareIgnoreCase("abc", "AB ", false) > 0);
187     }
188 
189     @Test
190     void testCustomCharSequence() {
191         assertNotEquals(FOO, new CustomCharSequence(FOO));
192         assertNotEquals(new CustomCharSequence(FOO), FOO);
193         assertEquals(new CustomCharSequence(FOO), new CustomCharSequence(FOO));
194     }
195 
196     @Test
197     void testEquals() {
198         final CharSequence fooCs = new StringBuilder(FOO);
199         final CharSequence barCs = new StringBuilder(BAR);
200         final CharSequence foobarCs = new StringBuilder(FOOBAR);
201         assertTrue(StringUtils.equals(null, null));
202         assertTrue(StringUtils.equals(fooCs, fooCs));
203         assertTrue(StringUtils.equals(fooCs, new StringBuilder(FOO)));
204         assertTrue(StringUtils.equals(fooCs, new String(new char[] { 'f', 'o', 'o' })));
205         assertTrue(StringUtils.equals(fooCs, new CustomCharSequence(FOO)));
206         assertTrue(StringUtils.equals(new CustomCharSequence(FOO), fooCs));
207         assertFalse(StringUtils.equals(fooCs, new String(new char[] { 'f', 'O', 'O' })));
208         assertFalse(StringUtils.equals(fooCs, barCs));
209         assertFalse(StringUtils.equals(fooCs, null));
210         assertFalse(StringUtils.equals(null, fooCs));
211         assertFalse(StringUtils.equals(fooCs, foobarCs));
212         assertFalse(StringUtils.equals(foobarCs, fooCs));
213     }
214 
215     @Test
216     void testEqualsAny() {
217         assertFalse(StringUtils.equalsAny(FOO));
218         assertFalse(StringUtils.equalsAny(FOO, new String[]{}));
219 
220         assertTrue(StringUtils.equalsAny(FOO, FOO));
221         assertTrue(StringUtils.equalsAny(FOO, BAR, new String(new char[] { 'f', 'o', 'o' })));
222         assertFalse(StringUtils.equalsAny(FOO, BAR, new String(new char[] { 'f', 'O', 'O' })));
223         assertFalse(StringUtils.equalsAny(FOO, BAR));
224         assertFalse(StringUtils.equalsAny(FOO, BAR, null));
225         assertFalse(StringUtils.equalsAny(null, FOO));
226         assertFalse(StringUtils.equalsAny(FOO, FOOBAR));
227         assertFalse(StringUtils.equalsAny(FOOBAR, FOO));
228 
229         assertTrue(StringUtils.equalsAny(null, null, null));
230         assertFalse(StringUtils.equalsAny(null, FOO, BAR, FOOBAR));
231         assertFalse(StringUtils.equalsAny(FOO, null, BAR));
232         assertTrue(StringUtils.equalsAny(FOO, BAR, null, "", FOO, BAR));
233         assertFalse(StringUtils.equalsAny(FOO, FOO.toUpperCase(Locale.ROOT)));
234 
235         assertFalse(StringUtils.equalsAny(null, (CharSequence[]) null));
236         assertTrue(StringUtils.equalsAny(FOO, new CustomCharSequence("foo")));
237         assertTrue(StringUtils.equalsAny(FOO, new StringBuilder("foo")));
238         assertFalse(StringUtils.equalsAny(FOO, new CustomCharSequence("fOo")));
239         assertFalse(StringUtils.equalsAny(FOO, new StringBuilder("fOo")));
240     }
241 
242     @Test
243     void testEqualsAnyIgnoreCase() {
244         assertFalse(StringUtils.equalsAnyIgnoreCase(FOO));
245         assertFalse(StringUtils.equalsAnyIgnoreCase(FOO, new String[]{}));
246 
247         assertTrue(StringUtils.equalsAnyIgnoreCase(FOO, FOO));
248         assertTrue(StringUtils.equalsAnyIgnoreCase(FOO, FOO.toUpperCase(Locale.ROOT)));
249         assertTrue(StringUtils.equalsAnyIgnoreCase(FOO, FOO, new String(new char[]{'f', 'o', 'o'})));
250         assertTrue(StringUtils.equalsAnyIgnoreCase(FOO, BAR, new String(new char[]{'f', 'O', 'O'})));
251         assertFalse(StringUtils.equalsAnyIgnoreCase(FOO, BAR));
252         assertFalse(StringUtils.equalsAnyIgnoreCase(FOO, BAR, null));
253         assertFalse(StringUtils.equalsAnyIgnoreCase(null, FOO));
254         assertFalse(StringUtils.equalsAnyIgnoreCase(FOO, FOOBAR));
255         assertFalse(StringUtils.equalsAnyIgnoreCase(FOOBAR, FOO));
256 
257         assertTrue(StringUtils.equalsAnyIgnoreCase(null, null, null));
258         assertFalse(StringUtils.equalsAnyIgnoreCase(null, FOO, BAR, FOOBAR));
259         assertFalse(StringUtils.equalsAnyIgnoreCase(FOO, null, BAR));
260         assertTrue(StringUtils.equalsAnyIgnoreCase(FOO, BAR, null, "", FOO.toUpperCase(Locale.ROOT), BAR));
261         assertTrue(StringUtils.equalsAnyIgnoreCase(FOO, FOO.toUpperCase(Locale.ROOT)));
262 
263         assertFalse(StringUtils.equalsAnyIgnoreCase(null, (CharSequence[]) null));
264         assertTrue(StringUtils.equalsAnyIgnoreCase(FOO, new CustomCharSequence("fOo")));
265         assertTrue(StringUtils.equalsAnyIgnoreCase(FOO, new StringBuilder("fOo")));
266     }
267 
268     @Test
269     void testEqualsIgnoreCase() {
270         assertTrue(StringUtils.equalsIgnoreCase(null, null));
271         assertTrue(StringUtils.equalsIgnoreCase(FOO, FOO));
272         assertTrue(StringUtils.equalsIgnoreCase(FOO, new String(new char[] { 'f', 'o', 'o' })));
273         assertTrue(StringUtils.equalsIgnoreCase(FOO, new String(new char[] { 'f', 'O', 'O' })));
274         assertFalse(StringUtils.equalsIgnoreCase(FOO, BAR));
275         assertFalse(StringUtils.equalsIgnoreCase(FOO, null));
276         assertFalse(StringUtils.equalsIgnoreCase(null, FOO));
277         assertTrue(StringUtils.equalsIgnoreCase("", ""));
278         assertFalse(StringUtils.equalsIgnoreCase("abcd", "abcd "));
279     }
280 
281     @Test
282     void testEqualsOnStrings() {
283         assertTrue(StringUtils.equals(null, null));
284         assertTrue(StringUtils.equals(FOO, FOO));
285         assertTrue(StringUtils.equals(FOO, new String(new char[] { 'f', 'o', 'o' })));
286         assertFalse(StringUtils.equals(FOO, new String(new char[] { 'f', 'O', 'O' })));
287         assertFalse(StringUtils.equals(FOO, BAR));
288         assertFalse(StringUtils.equals(FOO, null));
289         assertFalse(StringUtils.equals(null, FOO));
290         assertFalse(StringUtils.equals(FOO, FOOBAR));
291         assertFalse(StringUtils.equals(FOOBAR, FOO));
292     }
293 
294     @Test
295     void testIndexOf_char() {
296         assertEquals(-1, StringUtils.indexOf(null, ' '));
297         assertEquals(-1, StringUtils.indexOf("", ' '));
298         assertEquals(0, StringUtils.indexOf("aabaabaa", 'a'));
299         assertEquals(2, StringUtils.indexOf("aabaabaa", 'b'));
300 
301         assertEquals(2, StringUtils.indexOf(new StringBuilder("aabaabaa"), 'b'));
302         assertEquals(StringUtils.INDEX_NOT_FOUND, StringUtils.indexOf(new StringBuilder("aabaabaa"), -1738));
303     }
304 
305     @Test
306     void testIndexOf_charInt() {
307         assertEquals(-1, StringUtils.indexOf(null, ' ', 0));
308         assertEquals(-1, StringUtils.indexOf(null, ' ', -1));
309         assertEquals(-1, StringUtils.indexOf("", ' ', 0));
310         assertEquals(-1, StringUtils.indexOf("", ' ', -1));
311         assertEquals(0, StringUtils.indexOf("aabaabaa", 'a', 0));
312         assertEquals(2, StringUtils.indexOf("aabaabaa", 'b', 0));
313         assertEquals(5, StringUtils.indexOf("aabaabaa", 'b', 3));
314         assertEquals(-1, StringUtils.indexOf("aabaabaa", 'b', 9));
315         assertEquals(2, StringUtils.indexOf("aabaabaa", 'b', -1));
316 
317         assertEquals(5, StringUtils.indexOf(new StringBuilder("aabaabaa"), 'b', 3));
318 
319         //LANG-1300 tests go here
320         final int CODE_POINT = 0x2070E;
321         StringBuilder builder = new StringBuilder();
322         builder.appendCodePoint(CODE_POINT);
323         assertEquals(0, StringUtils.indexOf(builder, CODE_POINT, 0));
324         assertEquals(0, StringUtils.indexOf(builder.toString(), CODE_POINT, 0));
325         builder.appendCodePoint(CODE_POINT);
326         assertEquals(2, StringUtils.indexOf(builder, CODE_POINT, 1));
327         assertEquals(2, StringUtils.indexOf(builder.toString(), CODE_POINT, 1));
328         // inner branch on the supplementary character block
329         final char[] tmp = { (char) 55361 };
330         builder = new StringBuilder();
331         builder.append(tmp);
332         assertEquals(-1, StringUtils.indexOf(builder, CODE_POINT, 0));
333         assertEquals(-1, StringUtils.indexOf(builder.toString(), CODE_POINT, 0));
334         builder.appendCodePoint(CODE_POINT);
335         assertEquals(1, StringUtils.indexOf(builder, CODE_POINT, 0));
336         assertEquals(1, StringUtils.indexOf(builder.toString(), CODE_POINT, 0));
337         assertEquals(-1, StringUtils.indexOf(builder, CODE_POINT, 2));
338         assertEquals(-1, StringUtils.indexOf(builder.toString(), CODE_POINT, 2));
339     }
340 
341     @Test
342     void testIndexOf_String() {
343         assertEquals(-1, StringUtils.indexOf(null, null));
344         assertEquals(-1, StringUtils.indexOf("", null));
345         assertEquals(0, StringUtils.indexOf("", ""));
346         assertEquals(0, StringUtils.indexOf("aabaabaa", "a"));
347         assertEquals(2, StringUtils.indexOf("aabaabaa", "b"));
348         assertEquals(1, StringUtils.indexOf("aabaabaa", "ab"));
349         assertEquals(0, StringUtils.indexOf("aabaabaa", ""));
350 
351         assertEquals(2, StringUtils.indexOf(new StringBuilder("aabaabaa"), "b"));
352     }
353 
354     @Test
355     void testIndexOf_StringInt() {
356         assertEquals(-1, StringUtils.indexOf(null, null, 0));
357         assertEquals(-1, StringUtils.indexOf(null, null, -1));
358         assertEquals(-1, StringUtils.indexOf(null, "", 0));
359         assertEquals(-1, StringUtils.indexOf(null, "", -1));
360         assertEquals(-1, StringUtils.indexOf("", null, 0));
361         assertEquals(-1, StringUtils.indexOf("", null, -1));
362         assertEquals(0, StringUtils.indexOf("", "", 0));
363         assertEquals(0, StringUtils.indexOf("", "", -1));
364         assertEquals(0, StringUtils.indexOf("", "", 9));
365         assertEquals(0, StringUtils.indexOf("abc", "", 0));
366         assertEquals(0, StringUtils.indexOf("abc", "", -1));
367         assertEquals(3, StringUtils.indexOf("abc", "", 9));
368         assertEquals(3, StringUtils.indexOf("abc", "", 3));
369         assertEquals(0, StringUtils.indexOf("aabaabaa", "a", 0));
370         assertEquals(2, StringUtils.indexOf("aabaabaa", "b", 0));
371         assertEquals(1, StringUtils.indexOf("aabaabaa", "ab", 0));
372         assertEquals(5, StringUtils.indexOf("aabaabaa", "b", 3));
373         assertEquals(-1, StringUtils.indexOf("aabaabaa", "b", 9));
374         assertEquals(2, StringUtils.indexOf("aabaabaa", "b", -1));
375         assertEquals(2, StringUtils.indexOf("aabaabaa", "", 2));
376 
377         // Test that startIndex works correctly, i.e. cannot match before startIndex
378         assertEquals(7, StringUtils.indexOf("12345678", "8", 5));
379         assertEquals(7, StringUtils.indexOf("12345678", "8", 6));
380         assertEquals(7, StringUtils.indexOf("12345678", "8", 7)); // 7 is last index
381         assertEquals(-1, StringUtils.indexOf("12345678", "8", 8));
382 
383         assertEquals(5, StringUtils.indexOf(new StringBuilder("aabaabaa"), "b", 3));
384     }
385 
386     @Test
387     void testIndexOfAny_StringCharArray() {
388         assertEquals(-1, StringUtils.indexOfAny(null, (char[]) null));
389         assertEquals(-1, StringUtils.indexOfAny(null, new char[0]));
390         assertEquals(-1, StringUtils.indexOfAny(null, 'a', 'b'));
391         assertEquals(-1, StringUtils.indexOfAny("", (char[]) null));
392         assertEquals(-1, StringUtils.indexOfAny("", new char[0]));
393         assertEquals(-1, StringUtils.indexOfAny("", 'a', 'b'));
394         assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", (char[]) null));
395         assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", new char[0]));
396         assertEquals(0, StringUtils.indexOfAny("zzabyycdxx", 'z', 'a'));
397         assertEquals(3, StringUtils.indexOfAny("zzabyycdxx", 'b', 'y'));
398         assertEquals(-1, StringUtils.indexOfAny("ab", 'z'));
399         // if more than one search char is present, the order of the search chars matters:
400         assertEquals(0, StringUtils.indexOfAny("abcd", 'a', 'b', 'c', 'd'));
401         assertEquals(0, StringUtils.indexOfAny("bcda", 'a', 'b', 'c', 'd'));
402         assertEquals(0, StringUtils.indexOfAny("cbda", 'a', 'b', 'c', 'd'));
403     }
404 
405     /**
406      * See https://www.oracle.com/technical-resources/articles/javase/supplementary.html
407      */
408     @Test
409     void testIndexOfAny_StringCharArrayWithSupplementaryChars() {
410         assertEquals(0, StringUtils.indexOfAny(CharU20000 + CharU20001, CharU20000.toCharArray()));
411         assertEquals(2, StringUtils.indexOfAny(CharU20000 + CharU20001, CharU20001.toCharArray()));
412         assertEquals(0, StringUtils.indexOfAny(CharU20000, CharU20000.toCharArray()));
413         assertEquals(-1, StringUtils.indexOfAny(CharU20000, CharU20001.toCharArray()));
414     }
415 
416     @Test
417     void testIndexOfAny_StringIntCharArray() {
418         // default cases
419         assertEquals(-1, StringUtils.indexOfAny(null, 0, (char[]) null));
420         assertEquals(-1, StringUtils.indexOfAny(null, 0, new char[0]));
421         assertEquals(-1, StringUtils.indexOfAny(null, 0, 'a', 'b'));
422         assertEquals(-1, StringUtils.indexOfAny("", 0, (char[]) null));
423         assertEquals(-1, StringUtils.indexOfAny("", 0, new char[0]));
424         assertEquals(-1, StringUtils.indexOfAny("", 0, 'a', 'b'));
425         assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", 0, (char[]) null));
426         assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", 0, new char[0]));
427         assertEquals(0, StringUtils.indexOfAny("zzabyycdxx", 0, 'z', 'a'));
428         assertEquals(3, StringUtils.indexOfAny("zzabyycdxx", 0, 'b', 'y'));
429         assertEquals(-1, StringUtils.indexOfAny("ab", 0, 'z'));
430         // if more than one search char is present, the order of the search chars matters:
431         assertEquals(0, StringUtils.indexOfAny("abcd", 0, 'a', 'b', 'c', 'd'));
432         assertEquals(0, StringUtils.indexOfAny("bcda", 0, 'a', 'b', 'c', 'd'));
433         assertEquals(0, StringUtils.indexOfAny("cbda", 0, 'a', 'b', 'c', 'd'));
434         // Actually use the index
435         assertEquals(-1, StringUtils.indexOfAny(null, 1, (char[]) null));
436         assertEquals(-1, StringUtils.indexOfAny(null, 1, new char[0]));
437         assertEquals(-1, StringUtils.indexOfAny(null, 1, 'a', 'b'));
438         assertEquals(-1, StringUtils.indexOfAny("", 1, (char[]) null));
439         assertEquals(-1, StringUtils.indexOfAny("", 1, new char[0]));
440         assertEquals(-1, StringUtils.indexOfAny("", 1, 'a', 'b'));
441         assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", 1, (char[]) null));
442         assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", 1, new char[0]));
443         assertEquals(1, StringUtils.indexOfAny("zzabyycdxx", 1, 'z', 'a'));
444         assertEquals(3, StringUtils.indexOfAny("zzabyycdxx", 1, 'b', 'y'));
445         assertEquals(-1, StringUtils.indexOfAny("ab", 1, 'z'));
446         // if more than one search char is present, the order of the search chars matters:
447         assertEquals(1, StringUtils.indexOfAny("abcd", 1, 'a', 'b', 'c', 'd'));
448         assertEquals(1, StringUtils.indexOfAny("bcda", 1, 'a', 'b', 'c', 'd'));
449         assertEquals(1, StringUtils.indexOfAny("cbda", 1, 'a', 'b', 'c', 'd'));
450     }
451 
452     @Test
453     void testIndexOfAny_StringString() {
454         assertEquals(-1, StringUtils.indexOfAny(null, (String) null));
455         assertEquals(-1, StringUtils.indexOfAny(null, ""));
456         assertEquals(-1, StringUtils.indexOfAny(null, "ab"));
457 
458         assertEquals(-1, StringUtils.indexOfAny("", (String) null));
459         assertEquals(-1, StringUtils.indexOfAny("", ""));
460         assertEquals(-1, StringUtils.indexOfAny("", "ab"));
461 
462         assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", (String) null));
463         assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", ""));
464         assertEquals(0, StringUtils.indexOfAny("zzabyycdxx", "za"));
465         assertEquals(3, StringUtils.indexOfAny("zzabyycdxx", "by"));
466         assertEquals(-1, StringUtils.indexOfAny("ab", "z"));
467     }
468 
469     @Test
470     void testIndexOfAny_StringStringArray() {
471         assertEquals(-1, StringUtils.indexOfAny(null, (String[]) null));
472         assertEquals(-1, StringUtils.indexOfAny(null, FOOBAR_SUB_ARRAY));
473         assertEquals(-1, StringUtils.indexOfAny(FOOBAR, (String[]) null));
474         assertEquals(2, StringUtils.indexOfAny(FOOBAR, FOOBAR_SUB_ARRAY));
475         assertEquals(-1, StringUtils.indexOfAny(FOOBAR, new String[0]));
476         assertEquals(-1, StringUtils.indexOfAny(null, new String[0]));
477         assertEquals(-1, StringUtils.indexOfAny("", new String[0]));
478         assertEquals(-1, StringUtils.indexOfAny(FOOBAR, new String[] {"llll"}));
479         assertEquals(0, StringUtils.indexOfAny(FOOBAR, new String[] {""}));
480         assertEquals(0, StringUtils.indexOfAny("", new String[] {""}));
481         assertEquals(-1, StringUtils.indexOfAny("", new String[] {"a"}));
482         assertEquals(-1, StringUtils.indexOfAny("", new String[] {null}));
483         assertEquals(-1, StringUtils.indexOfAny(FOOBAR, new String[] {null}));
484         assertEquals(-1, StringUtils.indexOfAny(null, new String[] {null}));
485     }
486 
487     /**
488      * See https://www.oracle.com/technical-resources/articles/javase/supplementary.html
489      */
490     @Test
491     void testIndexOfAny_StringStringWithSupplementaryChars() {
492         assertEquals(0, StringUtils.indexOfAny(CharU20000 + CharU20001, CharU20000));
493         assertEquals(2, StringUtils.indexOfAny(CharU20000 + CharU20001, CharU20001));
494         assertEquals(0, StringUtils.indexOfAny(CharU20000, CharU20000));
495         assertEquals(-1, StringUtils.indexOfAny(CharU20000, CharU20001));
496     }
497 
498     @Test
499     void testIndexOfAnyBut_StringCharArray() {
500         assertEquals(-1, StringUtils.indexOfAnyBut(null, (char[]) null));
501         assertEquals(-1, StringUtils.indexOfAnyBut(null));
502         assertEquals(-1, StringUtils.indexOfAnyBut(null, 'a', 'b'));
503 
504         assertEquals(-1, StringUtils.indexOfAnyBut("", (char[]) null));
505         assertEquals(-1, StringUtils.indexOfAnyBut(""));
506         assertEquals(-1, StringUtils.indexOfAnyBut("", 'a', 'b'));
507 
508         assertEquals(-1, StringUtils.indexOfAnyBut("zzabyycdxx", (char[]) null));
509         assertEquals(-1, StringUtils.indexOfAnyBut("zzabyycdxx"));
510         assertEquals(3, StringUtils.indexOfAnyBut("zzabyycdxx", 'z', 'a'));
511         assertEquals(0, StringUtils.indexOfAnyBut("zzabyycdxx", 'b', 'y'));
512         assertEquals(-1, StringUtils.indexOfAnyBut("aba", 'a', 'b'));
513         assertEquals(0, StringUtils.indexOfAnyBut("aba", 'z'));
514     }
515 
516     @ParameterizedTest
517     @MethodSource("indexOfAnyBut_withSurrogateChars")
518     void testIndexOfAnyBut_StringCharArrayWithSurrogateChars(final CharSequence seq, final String searchChars, final int expected) {
519         assertEquals(expected, StringUtils.indexOfAnyBut(seq, searchChars.toCharArray()));
520     }
521 
522     @Test
523     void testIndexOfAnyBut_StringString() {
524         assertEquals(-1, StringUtils.indexOfAnyBut(null, (String) null));
525         assertEquals(-1, StringUtils.indexOfAnyBut(null, ""));
526         assertEquals(-1, StringUtils.indexOfAnyBut(null, "ab"));
527 
528         assertEquals(-1, StringUtils.indexOfAnyBut("", (String) null));
529         assertEquals(-1, StringUtils.indexOfAnyBut("", ""));
530         assertEquals(-1, StringUtils.indexOfAnyBut("", "ab"));
531 
532         assertEquals(-1, StringUtils.indexOfAnyBut("zzabyycdxx", (String) null));
533         assertEquals(-1, StringUtils.indexOfAnyBut("zzabyycdxx", ""));
534         assertEquals(3, StringUtils.indexOfAnyBut("zzabyycdxx", "za"));
535         assertEquals(0, StringUtils.indexOfAnyBut("zzabyycdxx", "by"));
536         assertEquals(0, StringUtils.indexOfAnyBut("ab", "z"));
537     }
538 
539     @ParameterizedTest
540     @MethodSource("indexOfAnyBut_withSurrogateChars")
541     void testIndexOfAnyBut_StringStringWithSurrogateChars(final CharSequence seq, final CharSequence searchChars, final int expected) {
542         assertEquals(expected, StringUtils.indexOfAnyBut(seq, searchChars));
543     }
544 
545     @Test
546     void testIndexOfIgnoreCase_String() {
547         assertEquals(-1, StringUtils.indexOfIgnoreCase(null, null));
548         assertEquals(-1, StringUtils.indexOfIgnoreCase(null, ""));
549         assertEquals(-1, StringUtils.indexOfIgnoreCase("", null));
550         assertEquals(0, StringUtils.indexOfIgnoreCase("", ""));
551         assertEquals(0, StringUtils.indexOfIgnoreCase("aabaabaa", "a"));
552         assertEquals(0, StringUtils.indexOfIgnoreCase("aabaabaa", "A"));
553         assertEquals(2, StringUtils.indexOfIgnoreCase("aabaabaa", "b"));
554         assertEquals(2, StringUtils.indexOfIgnoreCase("aabaabaa", "B"));
555         assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "ab"));
556         assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB"));
557         assertEquals(0, StringUtils.indexOfIgnoreCase("aabaabaa", ""));
558     }
559 
560     @Test
561     void testIndexOfIgnoreCase_StringInt() {
562         assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", -1));
563         assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 0));
564         assertEquals(1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 1));
565         assertEquals(4, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 2));
566         assertEquals(4, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 3));
567         assertEquals(4, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 4));
568         assertEquals(-1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 5));
569         assertEquals(-1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 6));
570         assertEquals(-1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 7));
571         assertEquals(-1, StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 8));
572         assertEquals(1, StringUtils.indexOfIgnoreCase("aab", "AB", 1));
573         assertEquals(5, StringUtils.indexOfIgnoreCase("aabaabaa", "", 5));
574         assertEquals(-1, StringUtils.indexOfIgnoreCase("ab", "AAB", 0));
575         assertEquals(-1, StringUtils.indexOfIgnoreCase("aab", "AAB", 1));
576         assertEquals(-1, StringUtils.indexOfIgnoreCase("abc", "", 9));
577     }
578 
579     @Test
580     void testLANG1193() {
581         assertEquals(0, StringUtils.ordinalIndexOf("abc", "ab", 1));
582     }
583 
584     @Test
585     // Non-overlapping test
586     void testLANG1241_1() {
587         //                                          0  3  6
588         assertEquals(0, StringUtils.ordinalIndexOf("abaabaab", "ab", 1));
589         assertEquals(3, StringUtils.ordinalIndexOf("abaabaab", "ab", 2));
590         assertEquals(6, StringUtils.ordinalIndexOf("abaabaab", "ab", 3));
591     }
592 
593     @Test
594     // Overlapping matching test
595     void testLANG1241_2() {
596         //                                          0 2 4
597         assertEquals(0, StringUtils.ordinalIndexOf("abababa", "aba", 1));
598         assertEquals(2, StringUtils.ordinalIndexOf("abababa", "aba", 2));
599         assertEquals(4, StringUtils.ordinalIndexOf("abababa", "aba", 3));
600         assertEquals(0, StringUtils.ordinalIndexOf("abababab", "abab", 1));
601         assertEquals(2, StringUtils.ordinalIndexOf("abababab", "abab", 2));
602         assertEquals(4, StringUtils.ordinalIndexOf("abababab", "abab", 3));
603     }
604 
605     @Test
606     void testLastIndexOf_char() {
607         assertEquals(-1, StringUtils.lastIndexOf(null, ' '));
608         assertEquals(-1, StringUtils.lastIndexOf("", ' '));
609         assertEquals(7, StringUtils.lastIndexOf("aabaabaa", 'a'));
610         assertEquals(5, StringUtils.lastIndexOf("aabaabaa", 'b'));
611 
612         assertEquals(5, StringUtils.lastIndexOf(new StringBuilder("aabaabaa"), 'b'));
613     }
614 
615     @Test
616     void testLastIndexOf_charInt() {
617         assertEquals(-1, StringUtils.lastIndexOf(null, ' ', 0));
618         assertEquals(-1, StringUtils.lastIndexOf(null, ' ', -1));
619         assertEquals(-1, StringUtils.lastIndexOf("", ' ', 0));
620         assertEquals(-1, StringUtils.lastIndexOf("", ' ', -1));
621         assertEquals(7, StringUtils.lastIndexOf("aabaabaa", 'a', 8));
622         assertEquals(5, StringUtils.lastIndexOf("aabaabaa", 'b', 8));
623         assertEquals(2, StringUtils.lastIndexOf("aabaabaa", 'b', 3));
624         assertEquals(5, StringUtils.lastIndexOf("aabaabaa", 'b', 9));
625         assertEquals(-1, StringUtils.lastIndexOf("aabaabaa", 'b', -1));
626         assertEquals(0, StringUtils.lastIndexOf("aabaabaa", 'a', 0));
627 
628         assertEquals(2, StringUtils.lastIndexOf(new StringBuilder("aabaabaa"), 'b', 2));
629 
630         //LANG-1300 addition test
631         final int CODE_POINT = 0x2070E;
632         StringBuilder builder = new StringBuilder();
633         builder.appendCodePoint(CODE_POINT);
634         assertEquals(0, StringUtils.lastIndexOf(builder, CODE_POINT, 0));
635         builder.appendCodePoint(CODE_POINT);
636         assertEquals(0, StringUtils.lastIndexOf(builder, CODE_POINT, 0));
637         assertEquals(0, StringUtils.lastIndexOf(builder, CODE_POINT, 1));
638         assertEquals(2, StringUtils.lastIndexOf(builder, CODE_POINT, 2));
639 
640         builder.append("aaaaa");
641         assertEquals(2, StringUtils.lastIndexOf(builder, CODE_POINT, 4));
642         // inner branch on the supplementary character block
643         final char[] tmp = { (char) 55361 };
644         builder = new StringBuilder();
645         builder.append(tmp);
646         assertEquals(-1, StringUtils.lastIndexOf(builder, CODE_POINT, 0));
647         builder.appendCodePoint(CODE_POINT);
648         assertEquals(-1, StringUtils.lastIndexOf(builder, CODE_POINT, 0));
649         assertEquals(1, StringUtils.lastIndexOf(builder, CODE_POINT, 1));
650         assertEquals(-1, StringUtils.lastIndexOf(builder.toString(), CODE_POINT, 0));
651         assertEquals(1, StringUtils.lastIndexOf(builder.toString(), CODE_POINT, 1));
652         assertEquals(StringUtils.INDEX_NOT_FOUND, StringUtils.lastIndexOf(CharBuffer.wrap("[%{.c.0rro"), -1738, 982));
653     }
654 
655     @Test
656     void testLastIndexOf_String() {
657         assertEquals(-1, StringUtils.lastIndexOf(null, null));
658         assertEquals(-1, StringUtils.lastIndexOf("", null));
659         assertEquals(-1, StringUtils.lastIndexOf("", "a"));
660         assertEquals(0, StringUtils.lastIndexOf("", ""));
661         assertEquals(8, StringUtils.lastIndexOf("aabaabaa", ""));
662         assertEquals(7, StringUtils.lastIndexOf("aabaabaa", "a"));
663         assertEquals(5, StringUtils.lastIndexOf("aabaabaa", "b"));
664         assertEquals(4, StringUtils.lastIndexOf("aabaabaa", "ab"));
665 
666         assertEquals(4, StringUtils.lastIndexOf(new StringBuilder("aabaabaa"), "ab"));
667     }
668 
669     @Test
670     void testLastIndexOf_StringInt() {
671         assertEquals(-1, StringUtils.lastIndexOf(null, null, 0));
672         assertEquals(-1, StringUtils.lastIndexOf(null, null, -1));
673         assertEquals(-1, StringUtils.lastIndexOf(null, "", 0));
674         assertEquals(-1, StringUtils.lastIndexOf(null, "", -1));
675         assertEquals(-1, StringUtils.lastIndexOf("", null, 0));
676         assertEquals(-1, StringUtils.lastIndexOf("", null, -1));
677         assertEquals(0, StringUtils.lastIndexOf("", "", 0));
678         assertEquals(-1, StringUtils.lastIndexOf("", "", -1));
679         assertEquals(0, StringUtils.lastIndexOf("", "", 9));
680         assertEquals(0, StringUtils.lastIndexOf("abc", "", 0));
681         assertEquals(-1, StringUtils.lastIndexOf("abc", "", -1));
682         assertEquals(3, StringUtils.lastIndexOf("abc", "", 9));
683         assertEquals(7, StringUtils.lastIndexOf("aabaabaa", "a", 8));
684         assertEquals(5, StringUtils.lastIndexOf("aabaabaa", "b", 8));
685         assertEquals(4, StringUtils.lastIndexOf("aabaabaa", "ab", 8));
686         assertEquals(2, StringUtils.lastIndexOf("aabaabaa", "b", 3));
687         assertEquals(5, StringUtils.lastIndexOf("aabaabaa", "b", 9));
688         assertEquals(-1, StringUtils.lastIndexOf("aabaabaa", "b", -1));
689         assertEquals(-1, StringUtils.lastIndexOf("aabaabaa", "b", 0));
690         assertEquals(0, StringUtils.lastIndexOf("aabaabaa", "a", 0));
691         assertEquals(-1, StringUtils.lastIndexOf("aabaabaa", "a", -1));
692 
693         // Test that fromIndex works correctly, i.e. cannot match after fromIndex
694         assertEquals(7, StringUtils.lastIndexOf("12345678", "8", 9));
695         assertEquals(7, StringUtils.lastIndexOf("12345678", "8", 8));
696         assertEquals(7, StringUtils.lastIndexOf("12345678", "8", 7)); // 7 is last index
697         assertEquals(-1, StringUtils.lastIndexOf("12345678", "8", 6));
698 
699         assertEquals(-1, StringUtils.lastIndexOf("aabaabaa", "b", 1));
700         assertEquals(2, StringUtils.lastIndexOf("aabaabaa", "b", 2));
701         assertEquals(2, StringUtils.lastIndexOf("aabaabaa", "ba", 2));
702         assertEquals(2, StringUtils.lastIndexOf("aabaabaa", "ba", 3));
703 
704         assertEquals(2, StringUtils.lastIndexOf(new StringBuilder("aabaabaa"), "b", 3));
705     }
706 
707     @Test
708     void testLastIndexOfAny_StringStringArray() {
709         assertEquals(-1, StringUtils.lastIndexOfAny(null, (CharSequence) null));   // test both types of ...
710         assertEquals(-1, StringUtils.lastIndexOfAny(null, (CharSequence[]) null)); // ... varargs invocation
711         assertEquals(-1, StringUtils.lastIndexOfAny(null)); // Missing varag
712         assertEquals(-1, StringUtils.lastIndexOfAny(null, FOOBAR_SUB_ARRAY));
713         assertEquals(-1, StringUtils.lastIndexOfAny(FOOBAR, (CharSequence) null));   // test both types of ...
714         assertEquals(-1, StringUtils.lastIndexOfAny(FOOBAR, (CharSequence[]) null)); // ... varargs invocation
715         assertEquals(-1, StringUtils.lastIndexOfAny(FOOBAR)); // Missing vararg
716         assertEquals(3, StringUtils.lastIndexOfAny(FOOBAR, FOOBAR_SUB_ARRAY));
717         assertEquals(-1, StringUtils.lastIndexOfAny(FOOBAR, new String[0]));
718         assertEquals(-1, StringUtils.lastIndexOfAny(null, new String[0]));
719         assertEquals(-1, StringUtils.lastIndexOfAny("", new String[0]));
720         assertEquals(-1, StringUtils.lastIndexOfAny(FOOBAR, new String[] {"llll"}));
721         assertEquals(6, StringUtils.lastIndexOfAny(FOOBAR, new String[] {""}));
722         assertEquals(0, StringUtils.lastIndexOfAny("", new String[] {""}));
723         assertEquals(-1, StringUtils.lastIndexOfAny("", new String[] {"a"}));
724         assertEquals(-1, StringUtils.lastIndexOfAny("", new String[] {null}));
725         assertEquals(-1, StringUtils.lastIndexOfAny(FOOBAR, new String[] {null}));
726         assertEquals(-1, StringUtils.lastIndexOfAny(null, new String[] {null}));
727     }
728 
729     @Test
730     void testLastIndexOfIgnoreCase_String() {
731         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, null));
732         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", null));
733         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, ""));
734         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", "a"));
735         assertEquals(0, StringUtils.lastIndexOfIgnoreCase("", ""));
736         assertEquals(8, StringUtils.lastIndexOfIgnoreCase("aabaabaa", ""));
737         assertEquals(7, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "a"));
738         assertEquals(7, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A"));
739         assertEquals(5, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "b"));
740         assertEquals(5, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B"));
741         assertEquals(4, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "ab"));
742         assertEquals(4, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB"));
743         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("ab", "AAB"));
744         assertEquals(0, StringUtils.lastIndexOfIgnoreCase("aab", "AAB"));
745     }
746 
747     @Test
748     void testLastIndexOfIgnoreCase_StringInt() {
749         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, null, 0));
750         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, null, -1));
751         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, "", 0));
752         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase(null, "", -1));
753         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", null, 0));
754         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", null, -1));
755         assertEquals(0, StringUtils.lastIndexOfIgnoreCase("", "", 0));
756         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("", "", -1));
757         assertEquals(0, StringUtils.lastIndexOfIgnoreCase("", "", 9));
758         assertEquals(0, StringUtils.lastIndexOfIgnoreCase("abc", "", 0));
759         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("abc", "", -1));
760         assertEquals(3, StringUtils.lastIndexOfIgnoreCase("abc", "", 9));
761         assertEquals(7, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 8));
762         assertEquals(5, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 8));
763         assertEquals(4, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB", 8));
764         assertEquals(2, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 3));
765         assertEquals(5, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 9));
766         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", -1));
767         assertEquals(-1, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 0));
768         assertEquals(0, StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 0));
769         assertEquals(1, StringUtils.lastIndexOfIgnoreCase("aab", "AB", 1));
770     }
771 
772     @Test
773     void testLastOrdinalIndexOf() {
774         assertEquals(-1, StringUtils.lastOrdinalIndexOf(null, "*", 42));
775         assertEquals(-1, StringUtils.lastOrdinalIndexOf("*", null, 42));
776         assertEquals(0, StringUtils.lastOrdinalIndexOf("", "", 42));
777         assertEquals(7, StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 1));
778         assertEquals(6, StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 2));
779         assertEquals(5, StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 1));
780         assertEquals(2, StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 2));
781         assertEquals(4, StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 1));
782         assertEquals(1, StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 2));
783         assertEquals(8, StringUtils.lastOrdinalIndexOf("aabaabaa", "", 1));
784         assertEquals(8, StringUtils.lastOrdinalIndexOf("aabaabaa", "", 2));
785     }
786 
787     @Test
788     void testOrdinalIndexOf() {
789         assertEquals(-1, StringUtils.ordinalIndexOf(null, null, Integer.MIN_VALUE));
790         assertEquals(-1, StringUtils.ordinalIndexOf("", null, Integer.MIN_VALUE));
791         assertEquals(-1, StringUtils.ordinalIndexOf("", "", Integer.MIN_VALUE));
792         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "a", Integer.MIN_VALUE));
793         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "b", Integer.MIN_VALUE));
794         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "ab", Integer.MIN_VALUE));
795         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "", Integer.MIN_VALUE));
796 
797         assertEquals(-1, StringUtils.ordinalIndexOf(null, null, -1));
798         assertEquals(-1, StringUtils.ordinalIndexOf("", null, -1));
799         assertEquals(-1, StringUtils.ordinalIndexOf("", "", -1));
800         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "a", -1));
801         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "b", -1));
802         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "ab", -1));
803         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "", -1));
804 
805         assertEquals(-1, StringUtils.ordinalIndexOf(null, null, 0));
806         assertEquals(-1, StringUtils.ordinalIndexOf("", null, 0));
807         assertEquals(-1, StringUtils.ordinalIndexOf("", "", 0));
808         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "a", 0));
809         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "b", 0));
810         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "ab", 0));
811         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "", 0));
812 
813         assertEquals(-1, StringUtils.ordinalIndexOf(null, null, 1));
814         assertEquals(-1, StringUtils.ordinalIndexOf("", null, 1));
815         assertEquals(0, StringUtils.ordinalIndexOf("", "", 1));
816         assertEquals(0, StringUtils.ordinalIndexOf("aabaabaa", "a", 1));
817         assertEquals(2, StringUtils.ordinalIndexOf("aabaabaa", "b", 1));
818         assertEquals(1, StringUtils.ordinalIndexOf("aabaabaa", "ab", 1));
819         assertEquals(0, StringUtils.ordinalIndexOf("aabaabaa", "", 1));
820 
821         assertEquals(-1, StringUtils.ordinalIndexOf(null, null, 2));
822         assertEquals(-1, StringUtils.ordinalIndexOf("", null, 2));
823         assertEquals(0, StringUtils.ordinalIndexOf("", "", 2));
824         assertEquals(1, StringUtils.ordinalIndexOf("aabaabaa", "a", 2));
825         assertEquals(5, StringUtils.ordinalIndexOf("aabaabaa", "b", 2));
826         assertEquals(4, StringUtils.ordinalIndexOf("aabaabaa", "ab", 2));
827         assertEquals(0, StringUtils.ordinalIndexOf("aabaabaa", "", 2));
828 
829         assertEquals(-1, StringUtils.ordinalIndexOf(null, null, Integer.MAX_VALUE));
830         assertEquals(-1, StringUtils.ordinalIndexOf("", null, Integer.MAX_VALUE));
831         assertEquals(0, StringUtils.ordinalIndexOf("", "", Integer.MAX_VALUE));
832         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "a", Integer.MAX_VALUE));
833         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "b", Integer.MAX_VALUE));
834         assertEquals(-1, StringUtils.ordinalIndexOf("aabaabaa", "ab", Integer.MAX_VALUE));
835         assertEquals(0, StringUtils.ordinalIndexOf("aabaabaa", "", Integer.MAX_VALUE));
836 
837         assertEquals(-1, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 0));
838         assertEquals(0, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 1));
839         assertEquals(1, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 2));
840         assertEquals(2, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 3));
841         assertEquals(3, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 4));
842         assertEquals(4, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 5));
843         assertEquals(5, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 6));
844         assertEquals(6, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 7));
845         assertEquals(7, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 8));
846         assertEquals(8, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 9));
847         assertEquals(-1, StringUtils.ordinalIndexOf("aaaaaaaaa", "a", 10));
848 
849         // match at each possible position
850         assertEquals(0, StringUtils.ordinalIndexOf("aaaaaa", "aa", 1));
851         assertEquals(1, StringUtils.ordinalIndexOf("aaaaaa", "aa", 2));
852         assertEquals(2, StringUtils.ordinalIndexOf("aaaaaa", "aa", 3));
853         assertEquals(3, StringUtils.ordinalIndexOf("aaaaaa", "aa", 4));
854         assertEquals(4, StringUtils.ordinalIndexOf("aaaaaa", "aa", 5));
855         assertEquals(-1, StringUtils.ordinalIndexOf("aaaaaa", "aa", 6));
856 
857         assertEquals(0, StringUtils.ordinalIndexOf("ababab", "aba", 1));
858         assertEquals(2, StringUtils.ordinalIndexOf("ababab", "aba", 2));
859         assertEquals(-1, StringUtils.ordinalIndexOf("ababab", "aba", 3));
860 
861         assertEquals(0, StringUtils.ordinalIndexOf("abababab", "abab", 1));
862         assertEquals(2, StringUtils.ordinalIndexOf("abababab", "abab", 2));
863         assertEquals(4, StringUtils.ordinalIndexOf("abababab", "abab", 3));
864         assertEquals(-1, StringUtils.ordinalIndexOf("abababab", "abab", 4));
865     }
866 }