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.LangAssertions.assertIllegalArgumentException;
20  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotEquals;
24  import static org.junit.jupiter.api.Assertions.assertNotNull;
25  import static org.junit.jupiter.api.Assertions.assertNull;
26  import static org.junit.jupiter.api.Assertions.assertSame;
27  import static org.junit.jupiter.api.Assertions.assertThrows;
28  import static org.junit.jupiter.api.Assertions.assertTrue;
29  
30  import java.io.UnsupportedEncodingException;
31  import java.lang.reflect.Constructor;
32  import java.lang.reflect.Method;
33  import java.lang.reflect.Modifier;
34  import java.nio.CharBuffer;
35  import java.nio.charset.Charset;
36  import java.nio.charset.StandardCharsets;
37  import java.util.Arrays;
38  import java.util.Collections;
39  import java.util.Iterator;
40  import java.util.List;
41  import java.util.Locale;
42  import java.util.Objects;
43  import java.util.function.Supplier;
44  import java.util.regex.PatternSyntaxException;
45  
46  import org.apache.commons.lang3.function.Suppliers;
47  import org.apache.commons.lang3.mutable.MutableInt;
48  import org.apache.commons.lang3.text.WordUtils;
49  import org.junit.jupiter.api.Disabled;
50  import org.junit.jupiter.api.Test;
51  import org.junit.jupiter.params.ParameterizedTest;
52  import org.junit.jupiter.params.provider.ValueSource;
53  import org.junitpioneer.jupiter.DefaultLocale;
54  import org.junitpioneer.jupiter.ReadsDefaultLocale;
55  import org.junitpioneer.jupiter.WritesDefaultLocale;
56  
57  /**
58   * Tests for methods of {@link StringUtils}
59   * which been moved to their own test classes.
60   */
61  @SuppressWarnings("deprecation") // deliberate use of deprecated code
62  class StringUtilsTest extends AbstractLangTest {
63  
64      static final String WHITESPACE;
65      static final String NON_WHITESPACE;
66      static final String HARD_SPACE;
67      static final String TRIMMABLE;
68      static final String NON_TRIMMABLE;
69  
70      static {
71          final StringBuilder ws = new StringBuilder();
72          final StringBuilder nws = new StringBuilder();
73          final String hs = String.valueOf((char) 160);
74          final StringBuilder tr = new StringBuilder();
75          final StringBuilder ntr = new StringBuilder();
76          for (int i = 0; i < Character.MAX_VALUE; i++) {
77              if (Character.isWhitespace((char) i)) {
78                  ws.append((char) i);
79                  if (i > 32) {
80                      ntr.append((char) i);
81                  }
82              } else if (i < 40) {
83                  nws.append((char) i);
84              }
85          }
86          for (int i = 0; i <= 32; i++) {
87              tr.append((char) i);
88          }
89          WHITESPACE = ws.toString();
90          NON_WHITESPACE = nws.toString();
91          HARD_SPACE = hs;
92          TRIMMABLE = tr.toString();
93          NON_TRIMMABLE = ntr.toString();
94      }
95  
96      private static final String[] ARRAY_LIST = {"foo", "bar", "baz"};
97      private static final String[] EMPTY_ARRAY_LIST = {};
98      private static final String[] NULL_ARRAY_LIST = {null};
99      private static final Object[] NULL_TO_STRING_LIST = {
100             new Object() {
101                 @Override
102                 public String toString() {
103                     return null;
104                 }
105             }
106     };
107     private static final String[] MIXED_ARRAY_LIST = {null, "", "foo"};
108     private static final Object[] MIXED_TYPE_LIST = {"foo", Long.valueOf(2L)};
109     private static final long[] LONG_PRIM_LIST = {1, 2};
110     private static final int[] INT_PRIM_LIST = {1, 2};
111     private static final byte[] BYTE_PRIM_LIST = {1, 2};
112     private static final short[] SHORT_PRIM_LIST = {1, 2};
113     private static final char[] CHAR_PRIM_LIST = {'1', '2'};
114     private static final float[] FLOAT_PRIM_LIST = {1, 2};
115     private static final double[] DOUBLE_PRIM_LIST = {1, 2};
116     private static final List<String> MIXED_STRING_LIST = Arrays.asList(null, "", "foo");
117     private static final List<Object> MIXED_TYPE_OBJECT_LIST = Arrays.<Object>asList("foo", Long.valueOf(2L));
118     private static final List<String> STRING_LIST = Arrays.asList("foo", "bar", "baz");
119     private static final List<String> EMPTY_STRING_LIST = Collections.emptyList();
120     private static final List<String> NULL_STRING_LIST = Collections.singletonList(null);
121 
122     private static final String SEPARATOR = ",";
123     private static final char SEPARATOR_CHAR = ';';
124     private static final char COMMA_SEPARATOR_CHAR = ',';
125 
126     private static final String TEXT_LIST = "foo,bar,baz";
127     private static final String TEXT_LIST_CHAR = "foo;bar;baz";
128     private static final String TEXT_LIST_NOSEP = "foobarbaz";
129 
130     private static final String FOO_UNCAP = "foo";
131     private static final String FOO_CAP = "Foo";
132 
133     private static final String SENTENCE_UNCAP = "foo bar baz";
134     private static final String SENTENCE_CAP = "Foo Bar Baz";
135 
136     private static final boolean[] EMPTY = {};
137     private static final boolean[] ARRAY_FALSE_FALSE = {false, false};
138     private static final boolean[] ARRAY_FALSE_TRUE = {false, true};
139     private static final boolean[] ARRAY_FALSE_TRUE_FALSE = {false, true, false};
140 
141     private void innerTestSplit(final char separator, final String sepStr, final char noMatch) {
142         final String msg = "Failed on separator hex(" + Integer.toHexString(separator) +
143                 "), noMatch hex(" + Integer.toHexString(noMatch) + "), sepStr(" + sepStr + ")";
144 
145         final String str = "a" + separator + "b" + separator + separator + noMatch + "c";
146         String[] res;
147         // (str, sepStr)
148         res = StringUtils.split(str, sepStr);
149         assertEquals(3, res.length, msg);
150         assertEquals("a", res[0]);
151         assertEquals("b", res[1]);
152         assertEquals(noMatch + "c", res[2]);
153 
154         final String str2 = separator + "a" + separator;
155         res = StringUtils.split(str2, sepStr);
156         assertEquals(1, res.length, msg);
157         assertEquals("a", res[0], msg);
158 
159         res = StringUtils.split(str, sepStr, -1);
160         assertEquals(3, res.length, msg);
161         assertEquals("a", res[0], msg);
162         assertEquals("b", res[1], msg);
163         assertEquals(noMatch + "c", res[2], msg);
164 
165         res = StringUtils.split(str, sepStr, 0);
166         assertEquals(3, res.length, msg);
167         assertEquals("a", res[0], msg);
168         assertEquals("b", res[1], msg);
169         assertEquals(noMatch + "c", res[2], msg);
170 
171         res = StringUtils.split(str, sepStr, 1);
172         assertEquals(1, res.length, msg);
173         assertEquals(str, res[0], msg);
174 
175         res = StringUtils.split(str, sepStr, 2);
176         assertEquals(2, res.length, msg);
177         assertEquals("a", res[0], msg);
178         assertEquals(str.substring(2), res[1], msg);
179     }
180 
181     private void innerTestSplitPreserveAllTokens(final char separator, final String sepStr, final char noMatch) {
182         final String msg = "Failed on separator hex(" + Integer.toHexString(separator) +
183                 "), noMatch hex(" + Integer.toHexString(noMatch) + "), sepStr(" + sepStr + ")";
184 
185         final String str = "a" + separator + "b" + separator + separator + noMatch + "c";
186         String[] res;
187         // (str, sepStr)
188         res = StringUtils.splitPreserveAllTokens(str, sepStr);
189         assertEquals(4, res.length, msg);
190         assertEquals("a", res[0], msg);
191         assertEquals("b", res[1], msg);
192         assertEquals("", res[2], msg);
193         assertEquals(noMatch + "c", res[3], msg);
194 
195         final String str2 = separator + "a" + separator;
196         res = StringUtils.splitPreserveAllTokens(str2, sepStr);
197         assertEquals(3, res.length, msg);
198         assertEquals("", res[0], msg);
199         assertEquals("a", res[1], msg);
200         assertEquals("", res[2], msg);
201 
202         res = StringUtils.splitPreserveAllTokens(str, sepStr, -1);
203         assertEquals(4, res.length, msg);
204         assertEquals("a", res[0], msg);
205         assertEquals("b", res[1], msg);
206         assertEquals("", res[2], msg);
207         assertEquals(noMatch + "c", res[3], msg);
208 
209         res = StringUtils.splitPreserveAllTokens(str, sepStr, 0);
210         assertEquals(4, res.length, msg);
211         assertEquals("a", res[0], msg);
212         assertEquals("b", res[1], msg);
213         assertEquals("", res[2], msg);
214         assertEquals(noMatch + "c", res[3], msg);
215 
216         res = StringUtils.splitPreserveAllTokens(str, sepStr, 1);
217         assertEquals(1, res.length, msg);
218         assertEquals(str, res[0], msg);
219 
220         res = StringUtils.splitPreserveAllTokens(str, sepStr, 2);
221         assertEquals(2, res.length, msg);
222         assertEquals("a", res[0], msg);
223         assertEquals(str.substring(2), res[1], msg);
224     }
225 
226     /**
227      * Tests {@code appendIfMissing}.
228      */
229     @Test
230     void testAppendIfMissing() {
231         assertNull(StringUtils.appendIfMissing(null, null), "appendIfMissing(null,null)");
232         assertEquals("abc", StringUtils.appendIfMissing("abc", null), "appendIfMissing(abc,null)");
233         assertEquals("xyz", StringUtils.appendIfMissing("", "xyz"), "appendIfMissing(\"\",xyz)");
234         assertEquals("abcxyz", StringUtils.appendIfMissing("abc", "xyz"), "appendIfMissing(abc,xyz)");
235         assertEquals("abcxyz", StringUtils.appendIfMissing("abcxyz", "xyz"), "appendIfMissing(abcxyz,xyz)");
236         assertEquals("aXYZxyz", StringUtils.appendIfMissing("aXYZ", "xyz"), "appendIfMissing(aXYZ,xyz)");
237 
238         assertNull(StringUtils.appendIfMissing(null, null, (CharSequence[]) null), "appendIfMissing(null,null,null)");
239         assertEquals("abc", StringUtils.appendIfMissing("abc", null, (CharSequence[]) null), "appendIfMissing(abc,null,null)");
240         assertEquals("xyz", StringUtils.appendIfMissing("", "xyz", (CharSequence[]) null), "appendIfMissing(\"\",xyz,null))");
241         assertEquals("abcxyz", StringUtils.appendIfMissing("abc", "xyz", (CharSequence) null), "appendIfMissing(abc,xyz,{null})");
242         assertEquals("abc", StringUtils.appendIfMissing("abc", "xyz", ""), "appendIfMissing(abc,xyz,\"\")");
243         assertEquals("abcxyz", StringUtils.appendIfMissing("abc", "xyz", "mno"), "appendIfMissing(abc,xyz,mno)");
244         assertEquals("abcxyz", StringUtils.appendIfMissing("abcxyz", "xyz", "mno"), "appendIfMissing(abcxyz,xyz,mno)");
245         assertEquals("abcmno", StringUtils.appendIfMissing("abcmno", "xyz", "mno"), "appendIfMissing(abcmno,xyz,mno)");
246         assertEquals("abcXYZxyz", StringUtils.appendIfMissing("abcXYZ", "xyz", "mno"), "appendIfMissing(abcXYZ,xyz,mno)");
247         assertEquals("abcMNOxyz", StringUtils.appendIfMissing("abcMNO", "xyz", "mno"), "appendIfMissing(abcMNO,xyz,mno)");
248     }
249 
250     /**
251      * Tests {@code appendIfMissingIgnoreCase}.
252      */
253     @Test
254     void testAppendIfMissingIgnoreCase() {
255         assertNull(StringUtils.appendIfMissingIgnoreCase(null, null), "appendIfMissingIgnoreCase(null,null)");
256         assertEquals("abc", StringUtils.appendIfMissingIgnoreCase("abc", null), "appendIfMissingIgnoreCase(abc,null)");
257         assertEquals("xyz", StringUtils.appendIfMissingIgnoreCase("", "xyz"), "appendIfMissingIgnoreCase(\"\",xyz)");
258         assertEquals("abcxyz", StringUtils.appendIfMissingIgnoreCase("abc", "xyz"), "appendIfMissingIgnoreCase(abc,xyz)");
259         assertEquals("abcxyz", StringUtils.appendIfMissingIgnoreCase("abcxyz", "xyz"), "appendIfMissingIgnoreCase(abcxyz,xyz)");
260         assertEquals("abcXYZ", StringUtils.appendIfMissingIgnoreCase("abcXYZ", "xyz"), "appendIfMissingIgnoreCase(abcXYZ,xyz)");
261 
262         assertNull(StringUtils.appendIfMissingIgnoreCase(null, null, (CharSequence[]) null), "appendIfMissingIgnoreCase(null,null,null)");
263         assertEquals("abc", StringUtils.appendIfMissingIgnoreCase("abc", null, (CharSequence[]) null), "appendIfMissingIgnoreCase(abc,null,null)");
264         assertEquals("xyz", StringUtils.appendIfMissingIgnoreCase("", "xyz", (CharSequence[]) null), "appendIfMissingIgnoreCase(\"\",xyz,null)");
265         assertEquals("abcxyz", StringUtils.appendIfMissingIgnoreCase("abc", "xyz", (CharSequence) null), "appendIfMissingIgnoreCase(abc,xyz,{null})");
266         assertEquals("abc", StringUtils.appendIfMissingIgnoreCase("abc", "xyz", ""), "appendIfMissingIgnoreCase(abc,xyz,\"\")");
267         assertEquals("abcxyz", StringUtils.appendIfMissingIgnoreCase("abc", "xyz", "mno"), "appendIfMissingIgnoreCase(abc,xyz,mno)");
268         assertEquals("abcxyz", StringUtils.appendIfMissingIgnoreCase("abcxyz", "xyz", "mno"), "appendIfMissingIgnoreCase(abcxyz,xyz,mno)");
269         assertEquals("abcmno", StringUtils.appendIfMissingIgnoreCase("abcmno", "xyz", "mno"), "appendIfMissingIgnoreCase(abcmno,xyz,mno)");
270         assertEquals("abcXYZ", StringUtils.appendIfMissingIgnoreCase("abcXYZ", "xyz", "mno"), "appendIfMissingIgnoreCase(abcXYZ,xyz,mno)");
271         assertEquals("abcMNO", StringUtils.appendIfMissingIgnoreCase("abcMNO", "xyz", "mno"), "appendIfMissingIgnoreCase(abcMNO,xyz,mno)");
272     }
273 
274     @Test
275     void testCapitalize() {
276         assertNull(StringUtils.capitalize(null));
277 
278         assertEquals("", StringUtils.capitalize(""), "capitalize(empty-string) failed");
279         assertEquals("X", StringUtils.capitalize("x"), "capitalize(single-char-string) failed");
280         assertEquals(FOO_CAP, StringUtils.capitalize(FOO_CAP), "capitalize(String) failed");
281         assertEquals(FOO_CAP, StringUtils.capitalize(FOO_UNCAP), "capitalize(string) failed");
282 
283         assertEquals("\u01C8", StringUtils.capitalize("\u01C9"), "capitalize(String) is not using TitleCase");
284 
285         // Javadoc examples
286         assertNull(StringUtils.capitalize(null));
287         assertEquals("", StringUtils.capitalize(""));
288         assertEquals("Cat", StringUtils.capitalize("cat"));
289         assertEquals("CAt", StringUtils.capitalize("cAt"));
290         assertEquals("'cat'", StringUtils.capitalize("'cat'"));
291     }
292 
293     @Test
294     void testCenter_StringInt() {
295         assertNull(StringUtils.center(null, -1));
296         assertNull(StringUtils.center(null, 4));
297         assertEquals("    ", StringUtils.center("", 4));
298         assertEquals("ab", StringUtils.center("ab", 0));
299         assertEquals("ab", StringUtils.center("ab", -1));
300         assertEquals("ab", StringUtils.center("ab", 1));
301         assertEquals("    ", StringUtils.center("", 4));
302         assertEquals(" ab ", StringUtils.center("ab", 4));
303         assertEquals("abcd", StringUtils.center("abcd", 2));
304         assertEquals(" a  ", StringUtils.center("a", 4));
305         assertEquals("  a  ", StringUtils.center("a", 5));
306     }
307 
308     @Test
309     void testCenter_StringIntChar() {
310         assertNull(StringUtils.center(null, -1, ' '));
311         assertNull(StringUtils.center(null, 4, ' '));
312         assertEquals("    ", StringUtils.center("", 4, ' '));
313         assertEquals("ab", StringUtils.center("ab", 0, ' '));
314         assertEquals("ab", StringUtils.center("ab", -1, ' '));
315         assertEquals("ab", StringUtils.center("ab", 1, ' '));
316         assertEquals("    ", StringUtils.center("", 4, ' '));
317         assertEquals(" ab ", StringUtils.center("ab", 4, ' '));
318         assertEquals("abcd", StringUtils.center("abcd", 2, ' '));
319         assertEquals(" a  ", StringUtils.center("a", 4, ' '));
320         assertEquals("  a  ", StringUtils.center("a", 5, ' '));
321         assertEquals("xxaxx", StringUtils.center("a", 5, 'x'));
322     }
323 
324     @Test
325     void testCenter_StringIntString() {
326         assertNull(StringUtils.center(null, 4, null));
327         assertNull(StringUtils.center(null, -1, " "));
328         assertNull(StringUtils.center(null, 4, " "));
329         assertEquals("    ", StringUtils.center("", 4, " "));
330         assertEquals("ab", StringUtils.center("ab", 0, " "));
331         assertEquals("ab", StringUtils.center("ab", -1, " "));
332         assertEquals("ab", StringUtils.center("ab", 1, " "));
333         assertEquals("    ", StringUtils.center("", 4, " "));
334         assertEquals(" ab ", StringUtils.center("ab", 4, " "));
335         assertEquals("abcd", StringUtils.center("abcd", 2, " "));
336         assertEquals(" a  ", StringUtils.center("a", 4, " "));
337         assertEquals("yayz", StringUtils.center("a", 4, "yz"));
338         assertEquals("yzyayzy", StringUtils.center("a", 7, "yz"));
339         assertEquals("  abc  ", StringUtils.center("abc", 7, null));
340         assertEquals("  abc  ", StringUtils.center("abc", 7, ""));
341     }
342 
343     @Test
344     void testChomp() {
345 
346         final String[][] chompCases = {
347                 {FOO_UNCAP + "\r\n", FOO_UNCAP},
348                 {FOO_UNCAP + "\n", FOO_UNCAP},
349                 {FOO_UNCAP + "\r", FOO_UNCAP},
350                 {FOO_UNCAP + " \r", FOO_UNCAP + " "},
351                 {FOO_UNCAP, FOO_UNCAP},
352                 {FOO_UNCAP + "\n\n", FOO_UNCAP + "\n"},
353                 {FOO_UNCAP + "\r\n\r\n", FOO_UNCAP + "\r\n"},
354                 {"foo\nfoo", "foo\nfoo"},
355                 {"foo\n\rfoo", "foo\n\rfoo"},
356                 {"\n", ""},
357                 {"\r", ""},
358                 {"a", "a"},
359                 {"\r\n", ""},
360                 {"", ""},
361                 {null, null},
362                 {FOO_UNCAP + "\n\r", FOO_UNCAP + "\n"}
363         };
364         for (final String[] chompCase : chompCases) {
365             final String original = chompCase[0];
366             final String expectedResult = chompCase[1];
367             assertEquals(expectedResult, StringUtils.chomp(original), "chomp(String) failed");
368         }
369 
370         assertEquals("foo", StringUtils.chomp("foobar", "bar"), "chomp(String, String) failed");
371         assertEquals("foobar", StringUtils.chomp("foobar", "baz"), "chomp(String, String) failed");
372         assertEquals("foo", StringUtils.chomp("foo", "foooo"), "chomp(String, String) failed");
373         assertEquals("foobar", StringUtils.chomp("foobar", ""), "chomp(String, String) failed");
374         assertEquals("foobar", StringUtils.chomp("foobar", null), "chomp(String, String) failed");
375         assertEquals("", StringUtils.chomp("", "foo"), "chomp(String, String) failed");
376         assertEquals("", StringUtils.chomp("", null), "chomp(String, String) failed");
377         assertEquals("", StringUtils.chomp("", ""), "chomp(String, String) failed");
378         assertNull(StringUtils.chomp(null, "foo"), "chomp(String, String) failed");
379         assertNull(StringUtils.chomp(null, null), "chomp(String, String) failed");
380         assertNull(StringUtils.chomp(null, ""), "chomp(String, String) failed");
381         assertEquals("", StringUtils.chomp("foo", "foo"), "chomp(String, String) failed");
382         assertEquals(" ", StringUtils.chomp(" foo", "foo"), "chomp(String, String) failed");
383         assertEquals("foo ", StringUtils.chomp("foo ", "foo"), "chomp(String, String) failed");
384     }
385 
386     @Test
387     void testChop() {
388 
389         final String[][] chopCases = {
390                 {FOO_UNCAP + "\r\n", FOO_UNCAP},
391                 {FOO_UNCAP + "\n", FOO_UNCAP},
392                 {FOO_UNCAP + "\r", FOO_UNCAP},
393                 {FOO_UNCAP + " \r", FOO_UNCAP + " "},
394                 {"foo", "fo"},
395                 {"foo\nfoo", "foo\nfo"},
396                 {"\n", ""},
397                 {"\r", ""},
398                 {"\r\n", ""},
399                 {null, null},
400                 {"", ""},
401                 {"a", ""},
402         };
403         for (final String[] chopCase : chopCases) {
404             final String original = chopCase[0];
405             final String expectedResult = chopCase[1];
406             assertEquals(expectedResult, StringUtils.chop(original), "chop(String) failed");
407         }
408     }
409 
410     @Test
411     void testConstructor() {
412         assertNotNull(new StringUtils());
413         final Constructor<?>[] cons = StringUtils.class.getDeclaredConstructors();
414         assertEquals(1, cons.length);
415         assertTrue(Modifier.isPublic(cons[0].getModifiers()));
416         assertTrue(Modifier.isPublic(StringUtils.class.getModifiers()));
417         assertFalse(Modifier.isFinal(StringUtils.class.getModifiers()));
418     }
419 
420     @Test
421     void testDefault_String() {
422         assertEquals("", StringUtils.defaultString(null));
423         assertEquals("", StringUtils.defaultString(""));
424         assertEquals("abc", StringUtils.defaultString("abc"));
425     }
426 
427     @Test
428     void testDefault_StringString() {
429         assertEquals("NULL", StringUtils.defaultString(null, "NULL"));
430         assertEquals("", StringUtils.defaultString("", "NULL"));
431         assertEquals("abc", StringUtils.defaultString("abc", "NULL"));
432     }
433 
434     @Test
435     void testDefaultIfBlank_CharBuffers() {
436         assertEquals("NULL", StringUtils.defaultIfBlank(CharBuffer.wrap(""), CharBuffer.wrap("NULL")).toString());
437         assertEquals("NULL", StringUtils.defaultIfBlank(CharBuffer.wrap(" "), CharBuffer.wrap("NULL")).toString());
438         assertEquals("abc", StringUtils.defaultIfBlank(CharBuffer.wrap("abc"), CharBuffer.wrap("NULL")).toString());
439         assertNull(StringUtils.defaultIfBlank(CharBuffer.wrap(""), (CharBuffer) null));
440         // Tests compatibility for the API return type
441         final CharBuffer s = StringUtils.defaultIfBlank(CharBuffer.wrap("abc"), CharBuffer.wrap("NULL"));
442         assertEquals("abc", s.toString());
443     }
444 
445     @Test
446     void testDefaultIfBlank_StringBuffers() {
447         assertEquals("NULL", StringUtils.defaultIfBlank(new StringBuffer(""), new StringBuffer("NULL")).toString());
448         assertEquals("NULL", StringUtils.defaultIfBlank(new StringBuffer(" "), new StringBuffer("NULL")).toString());
449         assertEquals("abc", StringUtils.defaultIfBlank(new StringBuffer("abc"), new StringBuffer("NULL")).toString());
450         assertNull(StringUtils.defaultIfBlank(new StringBuffer(""), (StringBuffer) null));
451         // Tests compatibility for the API return type
452         final StringBuffer s = StringUtils.defaultIfBlank(new StringBuffer("abc"), new StringBuffer("NULL"));
453         assertEquals("abc", s.toString());
454     }
455 
456     @Test
457     void testDefaultIfBlank_StringBuilders() {
458         assertEquals("NULL", StringUtils.defaultIfBlank(new StringBuilder(""), new StringBuilder("NULL")).toString());
459         assertEquals("NULL", StringUtils.defaultIfBlank(new StringBuilder(" "), new StringBuilder("NULL")).toString());
460         assertEquals("abc", StringUtils.defaultIfBlank(new StringBuilder("abc"), new StringBuilder("NULL")).toString());
461         assertNull(StringUtils.defaultIfBlank(new StringBuilder(""), (StringBuilder) null));
462         // Tests compatibility for the API return type
463         final StringBuilder s = StringUtils.defaultIfBlank(new StringBuilder("abc"), new StringBuilder("NULL"));
464         assertEquals("abc", s.toString());
465     }
466 
467     @Test
468     void testDefaultIfBlank_StringString() {
469         assertEquals("NULL", StringUtils.defaultIfBlank(null, "NULL"));
470         assertEquals("NULL", StringUtils.defaultIfBlank("", "NULL"));
471         assertEquals("NULL", StringUtils.defaultIfBlank(" ", "NULL"));
472         assertEquals("abc", StringUtils.defaultIfBlank("abc", "NULL"));
473         assertNull(StringUtils.defaultIfBlank("", (String) null));
474         // Tests compatibility for the API return type
475         final String s = StringUtils.defaultIfBlank("abc", "NULL");
476         assertEquals("abc", s);
477     }
478 
479     @Test
480     void testDefaultIfEmpty_CharBuffers() {
481         assertEquals("NULL", StringUtils.defaultIfEmpty(CharBuffer.wrap(""), CharBuffer.wrap("NULL")).toString());
482         assertEquals("abc", StringUtils.defaultIfEmpty(CharBuffer.wrap("abc"), CharBuffer.wrap("NULL")).toString());
483         assertNull(StringUtils.defaultIfEmpty(CharBuffer.wrap(""), (CharBuffer) null));
484         // Tests compatibility for the API return type
485         final CharBuffer s = StringUtils.defaultIfEmpty(CharBuffer.wrap("abc"), CharBuffer.wrap("NULL"));
486         assertEquals("abc", s.toString());
487     }
488 
489     @Test
490     void testDefaultIfEmpty_StringBuffers() {
491         assertEquals("NULL", StringUtils.defaultIfEmpty(new StringBuffer(""), new StringBuffer("NULL")).toString());
492         assertEquals("abc", StringUtils.defaultIfEmpty(new StringBuffer("abc"), new StringBuffer("NULL")).toString());
493         assertNull(StringUtils.defaultIfEmpty(new StringBuffer(""), (StringBuffer) null));
494         // Tests compatibility for the API return type
495         final StringBuffer s = StringUtils.defaultIfEmpty(new StringBuffer("abc"), new StringBuffer("NULL"));
496         assertEquals("abc", s.toString());
497     }
498 
499     @Test
500     void testDefaultIfEmpty_StringBuilders() {
501         assertEquals("NULL", StringUtils.defaultIfEmpty(new StringBuilder(""), new StringBuilder("NULL")).toString());
502         assertEquals("abc", StringUtils.defaultIfEmpty(new StringBuilder("abc"), new StringBuilder("NULL")).toString());
503         assertNull(StringUtils.defaultIfEmpty(new StringBuilder(""), (StringBuilder) null));
504         // Tests compatibility for the API return type
505         final StringBuilder s = StringUtils.defaultIfEmpty(new StringBuilder("abc"), new StringBuilder("NULL"));
506         assertEquals("abc", s.toString());
507     }
508 
509     @Test
510     void testDefaultIfEmpty_StringString() {
511         assertEquals("NULL", StringUtils.defaultIfEmpty(null, "NULL"));
512         assertEquals("NULL", StringUtils.defaultIfEmpty("", "NULL"));
513         assertEquals("abc", StringUtils.defaultIfEmpty("abc", "NULL"));
514         assertNull(StringUtils.getIfEmpty("", null));
515         // Tests compatibility for the API return type
516         final String s = StringUtils.defaultIfEmpty("abc", "NULL");
517         assertEquals("abc", s);
518     }
519 
520     @Test
521     void testDeleteWhitespace_String() {
522         assertNull(StringUtils.deleteWhitespace(null));
523         assertEquals("", StringUtils.deleteWhitespace(""));
524         assertEquals("", StringUtils.deleteWhitespace("  \u000C  \t\t\u001F\n\n \u000B  "));
525         assertEquals("", StringUtils.deleteWhitespace(StringUtilsTest.WHITESPACE));
526         assertEquals(StringUtilsTest.NON_WHITESPACE, StringUtils.deleteWhitespace(StringUtilsTest.NON_WHITESPACE));
527         // Note: u-2007 and u-000A both cause problems in the source code
528         // it should ignore 2007 but delete 000A
529         assertEquals("\u00A0\u202F", StringUtils.deleteWhitespace("  \u00A0  \t\t\n\n \u202F  "));
530         assertEquals("\u00A0\u202F", StringUtils.deleteWhitespace("\u00A0\u202F"));
531         assertEquals("test", StringUtils.deleteWhitespace("\u000Bt  \t\n\u0009e\rs\n\n   \tt"));
532     }
533 
534     @Test
535     void testDifference_StringString() {
536         assertNull(StringUtils.difference(null, null));
537         assertEquals("", StringUtils.difference("", ""));
538         assertEquals("abc", StringUtils.difference("", "abc"));
539         assertEquals("", StringUtils.difference("abc", ""));
540         assertEquals("i am a robot", StringUtils.difference(null, "i am a robot"));
541         assertEquals("i am a machine", StringUtils.difference("i am a machine", null));
542         assertEquals("robot", StringUtils.difference("i am a machine", "i am a robot"));
543         assertEquals("", StringUtils.difference("abc", "abc"));
544         assertEquals("you are a robot", StringUtils.difference("i am a robot", "you are a robot"));
545     }
546 
547     @Test
548     void testDifferenceAt_StringArray() {
549         assertEquals(-1, StringUtils.indexOfDifference((String[]) null));
550         assertEquals(-1, StringUtils.indexOfDifference());
551         assertEquals(-1, StringUtils.indexOfDifference("abc"));
552         assertEquals(-1, StringUtils.indexOfDifference(null, null));
553         assertEquals(-1, StringUtils.indexOfDifference("", ""));
554         assertEquals(0, StringUtils.indexOfDifference("", null));
555         assertEquals(0, StringUtils.indexOfDifference("abc", null, null));
556         assertEquals(0, StringUtils.indexOfDifference(null, null, "abc"));
557         assertEquals(0, StringUtils.indexOfDifference("", "abc"));
558         assertEquals(0, StringUtils.indexOfDifference("abc", ""));
559         assertEquals(-1, StringUtils.indexOfDifference("abc", "abc"));
560         assertEquals(1, StringUtils.indexOfDifference("abc", "a"));
561         assertEquals(2, StringUtils.indexOfDifference("ab", "abxyz"));
562         assertEquals(2, StringUtils.indexOfDifference("abcde", "abxyz"));
563         assertEquals(0, StringUtils.indexOfDifference("abcde", "xyz"));
564         assertEquals(0, StringUtils.indexOfDifference("xyz", "abcde"));
565         assertEquals(7, StringUtils.indexOfDifference("i am a machine", "i am a robot"));
566     }
567 
568     @Test
569     void testDifferenceAt_StringString() {
570         assertEquals(-1, StringUtils.indexOfDifference(null, null));
571         assertEquals(0, StringUtils.indexOfDifference(null, "i am a robot"));
572         assertEquals(-1, StringUtils.indexOfDifference("", ""));
573         assertEquals(0, StringUtils.indexOfDifference("", "abc"));
574         assertEquals(0, StringUtils.indexOfDifference("abc", ""));
575         assertEquals(0, StringUtils.indexOfDifference("i am a machine", null));
576         assertEquals(7, StringUtils.indexOfDifference("i am a machine", "i am a robot"));
577         assertEquals(-1, StringUtils.indexOfDifference("foo", "foo"));
578         assertEquals(0, StringUtils.indexOfDifference("i am a robot", "you are a robot"));
579     }
580 
581     /**
582      * A sanity check for {@link StringUtils#EMPTY}.
583      */
584     @Test
585     void testEMPTY() {
586         assertNotNull(StringUtils.EMPTY);
587         assertEquals("", StringUtils.EMPTY);
588         assertEquals(0, StringUtils.EMPTY.length());
589     }
590 
591     @Test
592     void testEscapeSurrogatePairs() {
593         assertEquals("\uD83D\uDE30", StringEscapeUtils.escapeCsv("\uD83D\uDE30"));
594         // Examples from https://en.wikipedia.org/wiki/UTF-16
595         assertEquals("\uD800\uDC00", StringEscapeUtils.escapeCsv("\uD800\uDC00"));
596         assertEquals("\uD834\uDD1E", StringEscapeUtils.escapeCsv("\uD834\uDD1E"));
597         assertEquals("\uDBFF\uDFFD", StringEscapeUtils.escapeCsv("\uDBFF\uDFFD"));
598         assertEquals("\uDBFF\uDFFD", StringEscapeUtils.escapeHtml3("\uDBFF\uDFFD"));
599         assertEquals("\uDBFF\uDFFD", StringEscapeUtils.escapeHtml4("\uDBFF\uDFFD"));
600         assertEquals("\uDBFF\uDFFD", StringEscapeUtils.escapeXml("\uDBFF\uDFFD"));
601     }
602 
603     /**
604      * Tests LANG-858.
605      */
606     @Test
607     void testEscapeSurrogatePairsLang858() {
608         assertEquals("\\uDBFF\\uDFFD", StringEscapeUtils.escapeJava("\uDBFF\uDFFD"));       //fail LANG-858
609         assertEquals("\\uDBFF\\uDFFD", StringEscapeUtils.escapeEcmaScript("\uDBFF\uDFFD")); //fail LANG-858
610     }
611 
612     @Test
613     void testGeorgianSample() {
614         final char[] arrayI = {
615                 //Latin Small Letter dotless I
616                 (char) 0x0131,
617                 //Greek Capital Letter Theta
618                 (char) 0x03F4
619         };
620         final char[] arrayJ = {
621                 //Latin Capital Letter I with dot above
622                 (char) 0x0130,
623                 //Greek Theta Symbol
624                 (char) 0x03D1
625         };
626         for (final char i : arrayI) {
627             for (final char j : arrayJ) {
628                 final String si = String.valueOf(i);
629                 final String sj = String.valueOf(j);
630                 final boolean res1 = si.equalsIgnoreCase(sj);
631                 final CharSequence ci = new StringBuilder(si);
632                 final CharSequence cj = new StringBuilder(sj);
633                 boolean res2 = StringUtils.startsWithIgnoreCase(ci, cj);
634                 assertEquals(res1, res2, "si : " + si + " sj : " + sj);
635                 res2 = StringUtils.endsWithIgnoreCase(ci, cj);
636                 assertEquals(res1, res2, "si : " + si + " sj : " + sj);
637                 res2 = StringUtils.compareIgnoreCase(ci.toString(), cj.toString()) == 0;
638                 assertEquals(res1, res2, "si : " + si + " sj : " + sj);
639                 res2 = StringUtils.indexOfIgnoreCase(ci.toString(), cj.toString()) == 0;
640                 assertEquals(res1, res2, "si : " + si + " sj : " + sj);
641                 res2 = StringUtils.lastIndexOfIgnoreCase(ci.toString(), cj.toString()) == 0;
642                 assertEquals(res1, res2, "si : " + si + " sj : " + sj);
643             }
644         }
645     }
646 
647     @Test
648     void testGetBytes_Charset() {
649         assertEquals(ArrayUtils.EMPTY_BYTE_ARRAY, StringUtils.getBytes(null, (Charset) null));
650         assertArrayEquals(StringUtils.EMPTY.getBytes(), StringUtils.getBytes(StringUtils.EMPTY, (Charset) null));
651         assertArrayEquals(StringUtils.EMPTY.getBytes(StandardCharsets.US_ASCII),
652             StringUtils.getBytes(StringUtils.EMPTY, StandardCharsets.US_ASCII));
653     }
654 
655     @Test
656     void testGetBytes_String() throws UnsupportedEncodingException {
657         assertEquals(ArrayUtils.EMPTY_BYTE_ARRAY, StringUtils.getBytes(null, (String) null));
658         assertArrayEquals(StringUtils.EMPTY.getBytes(), StringUtils.getBytes(StringUtils.EMPTY, (String) null));
659         assertArrayEquals(StringUtils.EMPTY.getBytes(StandardCharsets.US_ASCII.name()),
660             StringUtils.getBytes(StringUtils.EMPTY, StandardCharsets.US_ASCII.name()));
661     }
662 
663     @Test
664     void testGetCommonPrefix_StringArray() {
665         assertEquals("", StringUtils.getCommonPrefix((String[]) null));
666         assertEquals("", StringUtils.getCommonPrefix());
667         assertEquals("abc", StringUtils.getCommonPrefix("abc"));
668         assertEquals("", StringUtils.getCommonPrefix(null, null));
669         assertEquals("", StringUtils.getCommonPrefix("", ""));
670         assertEquals("", StringUtils.getCommonPrefix("", null));
671         assertEquals("", StringUtils.getCommonPrefix("abc", null, null));
672         assertEquals("", StringUtils.getCommonPrefix(null, null, "abc"));
673         assertEquals("", StringUtils.getCommonPrefix("", "abc"));
674         assertEquals("", StringUtils.getCommonPrefix("abc", ""));
675         assertEquals("abc", StringUtils.getCommonPrefix("abc", "abc"));
676         assertEquals("a", StringUtils.getCommonPrefix("abc", "a"));
677         assertEquals("ab", StringUtils.getCommonPrefix("ab", "abxyz"));
678         assertEquals("ab", StringUtils.getCommonPrefix("abcde", "abxyz"));
679         assertEquals("", StringUtils.getCommonPrefix("abcde", "xyz"));
680         assertEquals("", StringUtils.getCommonPrefix("xyz", "abcde"));
681         assertEquals("i am a ", StringUtils.getCommonPrefix("i am a machine", "i am a robot"));
682     }
683 
684     @Test
685     void testGetDigits() {
686         assertNull(StringUtils.getDigits(null));
687         assertEquals("", StringUtils.getDigits(""));
688         assertEquals("", StringUtils.getDigits("abc"));
689         assertEquals("1000", StringUtils.getDigits("1000$"));
690         assertEquals("12345", StringUtils.getDigits("123password45"));
691         assertEquals("5417543010", StringUtils.getDigits("(541) 754-3010"));
692         assertEquals("\u0967\u0968\u0969", StringUtils.getDigits("\u0967\u0968\u0969"));
693     }
694 
695     @Test
696     void testGetDigitsKeycaps() {
697         assertEquals("0123456789", StringUtils.getDigits("0️⃣1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣#️⃣"));
698     }
699 
700     @Test
701     void testGetFuzzyDistance() {
702         assertEquals(0, StringUtils.getFuzzyDistance("", "", Locale.ENGLISH));
703         assertEquals(0, StringUtils.getFuzzyDistance("Workshop", "b", Locale.ENGLISH));
704         assertEquals(1, StringUtils.getFuzzyDistance("Room", "o", Locale.ENGLISH));
705         assertEquals(1, StringUtils.getFuzzyDistance("Workshop", "w", Locale.ENGLISH));
706         assertEquals(2, StringUtils.getFuzzyDistance("Workshop", "ws", Locale.ENGLISH));
707         assertEquals(4, StringUtils.getFuzzyDistance("Workshop", "wo", Locale.ENGLISH));
708         assertEquals(3, StringUtils.getFuzzyDistance("Apache Software Foundation", "asf", Locale.ENGLISH));
709     }
710 
711     @Test
712     void testGetFuzzyDistance_NullNullNull() {
713         assertIllegalArgumentException(() -> StringUtils.getFuzzyDistance(null, null, null));
714     }
715 
716     @Test
717     void testGetFuzzyDistance_NullStringLocale() {
718         assertIllegalArgumentException(() -> StringUtils.getFuzzyDistance(null, "clear", Locale.ENGLISH));
719     }
720 
721     @Test
722     void testGetFuzzyDistance_StringNullLoclae() {
723         assertIllegalArgumentException(() -> StringUtils.getFuzzyDistance(" ", null, Locale.ENGLISH));
724     }
725 
726     @Test
727     void testGetFuzzyDistance_StringStringNull() {
728         assertIllegalArgumentException(() -> StringUtils.getFuzzyDistance(" ", "clear", null));
729     }
730 
731     @Test
732     void testGetIfBlank_StringStringSupplier() {
733         assertEquals("NULL", StringUtils.getIfBlank(null, () -> "NULL"));
734         assertEquals("NULL", StringUtils.getIfBlank("",  () -> "NULL"));
735         assertEquals("NULL", StringUtils.getIfBlank(" ", () -> "NULL"));
736         assertEquals("abc", StringUtils.getIfBlank("abc", () -> "NULL"));
737         assertNull(StringUtils.getIfBlank("", Suppliers.nul()));
738         assertNull(StringUtils.defaultIfBlank("", (String) null));
739         // Tests compatibility for the API return type
740         final String s = StringUtils.getIfBlank("abc", () -> "NULL");
741         assertEquals("abc", s);
742         //Checking that default value supplied only on demand
743         final MutableInt numberOfCalls = new MutableInt(0);
744         final Supplier<String> countingDefaultSupplier = () -> {
745             numberOfCalls.increment();
746             return "NULL";
747         };
748         StringUtils.getIfBlank("abc", countingDefaultSupplier);
749         assertEquals(0, numberOfCalls.get());
750         StringUtils.getIfBlank("", countingDefaultSupplier);
751         assertEquals(1, numberOfCalls.get());
752         StringUtils.getIfBlank(" ", countingDefaultSupplier);
753         assertEquals(2, numberOfCalls.get());
754         StringUtils.getIfBlank(null, countingDefaultSupplier);
755         assertEquals(3, numberOfCalls.get());
756     }
757 
758     @Test
759     void testGetIfEmpty_StringStringSupplier() {
760         assertEquals("NULL", StringUtils.getIfEmpty((String) null, () -> "NULL"));
761         assertEquals("NULL", StringUtils.getIfEmpty("", () -> "NULL"));
762         assertEquals("abc", StringUtils.getIfEmpty("abc", () -> "NULL"));
763         assertNull(StringUtils.getIfEmpty("", Suppliers.nul()));
764         assertNull(StringUtils.defaultIfEmpty("", (String) null));
765         // Tests compatibility for the API return type
766         final String s = StringUtils.getIfEmpty("abc", () -> "NULL");
767         assertEquals("abc", s);
768         //Checking that default value supplied only on demand
769         final MutableInt numberOfCalls = new MutableInt(0);
770         final Supplier<String> countingDefaultSupplier = () -> {
771             numberOfCalls.increment();
772             return "NULL";
773         };
774         StringUtils.getIfEmpty("abc", countingDefaultSupplier);
775         assertEquals(0, numberOfCalls.get());
776         StringUtils.getIfEmpty("", countingDefaultSupplier);
777         assertEquals(1, numberOfCalls.get());
778         StringUtils.getIfEmpty(null, countingDefaultSupplier);
779         assertEquals(2, numberOfCalls.get());
780     }
781 
782     @Test
783     void testGetJaroWinklerDistance_NullNull() {
784         assertIllegalArgumentException(() -> StringUtils.getJaroWinklerDistance(null, null));
785     }
786 
787     @Test
788     void testGetJaroWinklerDistance_NullString() {
789         assertIllegalArgumentException(() -> StringUtils.getJaroWinklerDistance(null, "clear"));
790     }
791 
792     @Test
793     void testGetJaroWinklerDistance_StringNull() {
794         assertIllegalArgumentException(() -> StringUtils.getJaroWinklerDistance(" ", null));
795     }
796 
797     @Test
798     void testGetJaroWinklerDistance_StringString() {
799         assertEquals(0.93d, StringUtils.getJaroWinklerDistance("frog", "fog"));
800         assertEquals(0.0d, StringUtils.getJaroWinklerDistance("fly", "ant"));
801         assertEquals(0.44d, StringUtils.getJaroWinklerDistance("elephant", "hippo"));
802         assertEquals(0.84d, StringUtils.getJaroWinklerDistance("dwayne", "duane"));
803         assertEquals(0.93d, StringUtils.getJaroWinklerDistance("ABC Corporation", "ABC Corp"));
804         assertEquals(0.95d, StringUtils.getJaroWinklerDistance("D N H Enterprises Inc", "D & H Enterprises, Inc."));
805         assertEquals(0.92d, StringUtils.getJaroWinklerDistance("My Gym Children's Fitness Center", "My Gym. Childrens Fitness"));
806         assertEquals(0.88d, StringUtils.getJaroWinklerDistance("PENNSYLVANIA", "PENNCISYLVNIA"));
807         assertEquals(0.63d, StringUtils.getJaroWinklerDistance("Haus Ingeborg", "Ingeborg Esser"));
808     }
809 
810     @Test
811     void testGetLevenshteinDistance_NullString() {
812         assertIllegalArgumentException(() -> StringUtils.getLevenshteinDistance("a", null));
813     }
814 
815     @Test
816     void testGetLevenshteinDistance_NullStringInt() {
817         assertIllegalArgumentException(() -> StringUtils.getLevenshteinDistance(null, "a", 0));
818     }
819 
820     @Test
821     void testGetLevenshteinDistance_StringNull() {
822         assertIllegalArgumentException(() -> StringUtils.getLevenshteinDistance(null, "a"));
823     }
824 
825     @Test
826     void testGetLevenshteinDistance_StringNullInt() {
827         assertIllegalArgumentException(() -> StringUtils.getLevenshteinDistance("a", null, 0));
828     }
829 
830     @Test
831     void testGetLevenshteinDistance_StringString() {
832         assertEquals(0, StringUtils.getLevenshteinDistance("", ""));
833         assertEquals(1, StringUtils.getLevenshteinDistance("", "a"));
834         assertEquals(7, StringUtils.getLevenshteinDistance("aaapppp", ""));
835         assertEquals(1, StringUtils.getLevenshteinDistance("frog", "fog"));
836         assertEquals(3, StringUtils.getLevenshteinDistance("fly", "ant"));
837         assertEquals(7, StringUtils.getLevenshteinDistance("elephant", "hippo"));
838         assertEquals(7, StringUtils.getLevenshteinDistance("hippo", "elephant"));
839         assertEquals(8, StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz"));
840         assertEquals(8, StringUtils.getLevenshteinDistance("zzzzzzzz", "hippo"));
841         assertEquals(1, StringUtils.getLevenshteinDistance("hello", "hallo"));
842     }
843 
844     @Test
845     void testGetLevenshteinDistance_StringStringInt() {
846         // empty strings
847         assertEquals(0, StringUtils.getLevenshteinDistance("", "", 0));
848         assertEquals(7, StringUtils.getLevenshteinDistance("aaapppp", "", 8));
849         assertEquals(7, StringUtils.getLevenshteinDistance("aaapppp", "", 7));
850         assertEquals(-1, StringUtils.getLevenshteinDistance("aaapppp", "", 6));
851 
852         // unequal strings, zero threshold
853         assertEquals(-1, StringUtils.getLevenshteinDistance("b", "a", 0));
854         assertEquals(-1, StringUtils.getLevenshteinDistance("a", "b", 0));
855 
856         // equal strings
857         assertEquals(0, StringUtils.getLevenshteinDistance("aa", "aa", 0));
858         assertEquals(0, StringUtils.getLevenshteinDistance("aa", "aa", 2));
859 
860         // same length
861         assertEquals(-1, StringUtils.getLevenshteinDistance("aaa", "bbb", 2));
862         assertEquals(3, StringUtils.getLevenshteinDistance("aaa", "bbb", 3));
863 
864         // big stripe
865         assertEquals(6, StringUtils.getLevenshteinDistance("aaaaaa", "b", 10));
866 
867         // distance less than threshold
868         assertEquals(7, StringUtils.getLevenshteinDistance("aaapppp", "b", 8));
869         assertEquals(3, StringUtils.getLevenshteinDistance("a", "bbb", 4));
870 
871         // distance equal to threshold
872         assertEquals(7, StringUtils.getLevenshteinDistance("aaapppp", "b", 7));
873         assertEquals(3, StringUtils.getLevenshteinDistance("a", "bbb", 3));
874 
875         // distance greater than threshold
876         assertEquals(-1, StringUtils.getLevenshteinDistance("a", "bbb", 2));
877         assertEquals(-1, StringUtils.getLevenshteinDistance("bbb", "a", 2));
878         assertEquals(-1, StringUtils.getLevenshteinDistance("aaapppp", "b", 6));
879 
880         // stripe runs off array, strings not similar
881         assertEquals(-1, StringUtils.getLevenshteinDistance("a", "bbb", 1));
882         assertEquals(-1, StringUtils.getLevenshteinDistance("bbb", "a", 1));
883 
884         // stripe runs off array, strings are similar
885         assertEquals(-1, StringUtils.getLevenshteinDistance("12345", "1234567", 1));
886         assertEquals(-1, StringUtils.getLevenshteinDistance("1234567", "12345", 1));
887 
888         // old getLevenshteinDistance test cases
889         assertEquals(1, StringUtils.getLevenshteinDistance("frog", "fog", 1));
890         assertEquals(3, StringUtils.getLevenshteinDistance("fly", "ant", 3));
891         assertEquals(7, StringUtils.getLevenshteinDistance("elephant", "hippo", 7));
892         assertEquals(-1, StringUtils.getLevenshteinDistance("elephant", "hippo", 6));
893         assertEquals(7, StringUtils.getLevenshteinDistance("hippo", "elephant", 7));
894         assertEquals(-1, StringUtils.getLevenshteinDistance("hippo", "elephant", 6));
895         assertEquals(8, StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz", 8));
896         assertEquals(8, StringUtils.getLevenshteinDistance("zzzzzzzz", "hippo", 8));
897         assertEquals(1, StringUtils.getLevenshteinDistance("hello", "hallo", 1));
898 
899         assertEquals(1, StringUtils.getLevenshteinDistance("frog", "fog", Integer.MAX_VALUE));
900         assertEquals(3, StringUtils.getLevenshteinDistance("fly", "ant", Integer.MAX_VALUE));
901         assertEquals(7, StringUtils.getLevenshteinDistance("elephant", "hippo", Integer.MAX_VALUE));
902         assertEquals(7, StringUtils.getLevenshteinDistance("hippo", "elephant", Integer.MAX_VALUE));
903         assertEquals(8, StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz", Integer.MAX_VALUE));
904         assertEquals(8, StringUtils.getLevenshteinDistance("zzzzzzzz", "hippo", Integer.MAX_VALUE));
905         assertEquals(1, StringUtils.getLevenshteinDistance("hello", "hallo", Integer.MAX_VALUE));
906     }
907 
908     @Test
909     void testGetLevenshteinDistance_StringStringNegativeInt() {
910         assertIllegalArgumentException(() -> StringUtils.getLevenshteinDistance("a", "a", -1));
911     }
912 
913     /**
914      * Test for {@link StringUtils#isAllLowerCase(CharSequence)}.
915      */
916     @Test
917     void testIsAllLowerCase() {
918         assertFalse(StringUtils.isAllLowerCase(null));
919         assertFalse(StringUtils.isAllLowerCase(StringUtils.EMPTY));
920         assertFalse(StringUtils.isAllLowerCase("  "));
921         assertTrue(StringUtils.isAllLowerCase("abc"));
922         assertFalse(StringUtils.isAllLowerCase("abc "));
923         assertFalse(StringUtils.isAllLowerCase("abc\n"));
924         assertFalse(StringUtils.isAllLowerCase("abC"));
925         assertFalse(StringUtils.isAllLowerCase("ab c"));
926         assertFalse(StringUtils.isAllLowerCase("ab1c"));
927         assertFalse(StringUtils.isAllLowerCase("ab/c"));
928     }
929 
930     /**
931      * Test for {@link StringUtils#isAllUpperCase(CharSequence)}.
932      */
933     @Test
934     void testIsAllUpperCase() {
935         assertFalse(StringUtils.isAllUpperCase(null));
936         assertFalse(StringUtils.isAllUpperCase(StringUtils.EMPTY));
937         assertFalse(StringUtils.isAllUpperCase("  "));
938         assertTrue(StringUtils.isAllUpperCase("ABC"));
939         assertFalse(StringUtils.isAllUpperCase("ABC "));
940         assertFalse(StringUtils.isAllUpperCase("ABC\n"));
941         assertFalse(StringUtils.isAllUpperCase("aBC"));
942         assertFalse(StringUtils.isAllUpperCase("A C"));
943         assertFalse(StringUtils.isAllUpperCase("A1C"));
944         assertFalse(StringUtils.isAllUpperCase("A/C"));
945     }
946 
947     /**
948      * Test for {@link StringUtils#isMixedCase(CharSequence)}.
949      */
950     @Test
951     void testIsMixedCase() {
952         assertFalse(StringUtils.isMixedCase(null));
953         assertFalse(StringUtils.isMixedCase(StringUtils.EMPTY));
954         assertFalse(StringUtils.isMixedCase(" "));
955         assertFalse(StringUtils.isMixedCase("A"));
956         assertFalse(StringUtils.isMixedCase("a"));
957         assertFalse(StringUtils.isMixedCase("/"));
958         assertFalse(StringUtils.isMixedCase("A/"));
959         assertFalse(StringUtils.isMixedCase("/b"));
960         assertFalse(StringUtils.isMixedCase("abc"));
961         assertFalse(StringUtils.isMixedCase("ABC"));
962         assertTrue(StringUtils.isMixedCase("aBc"));
963         assertTrue(StringUtils.isMixedCase("aBc "));
964         assertTrue(StringUtils.isMixedCase("A c"));
965         assertTrue(StringUtils.isMixedCase("aBc\n"));
966         assertTrue(StringUtils.isMixedCase("A1c"));
967         assertTrue(StringUtils.isMixedCase("a/C"));
968     }
969 
970     @Test
971     void testJoin_ArrayCharSeparator() {
972         assertNull(StringUtils.join((Object[]) null, ','));
973         assertEquals(TEXT_LIST_CHAR, StringUtils.join(ARRAY_LIST, SEPARATOR_CHAR));
974         assertEquals("", StringUtils.join(EMPTY_ARRAY_LIST, SEPARATOR_CHAR));
975         assertEquals(";;foo", StringUtils.join(MIXED_ARRAY_LIST, SEPARATOR_CHAR));
976         assertEquals("foo;2", StringUtils.join(MIXED_TYPE_LIST, SEPARATOR_CHAR));
977 
978         assertNull(StringUtils.join((Object[]) null, ',', 0, 1));
979         assertEquals("/", StringUtils.join(MIXED_ARRAY_LIST, '/', 0, MIXED_ARRAY_LIST.length - 1));
980         assertEquals("foo", StringUtils.join(MIXED_TYPE_LIST, '/', 0, 1));
981         assertEquals("null", StringUtils.join(NULL_TO_STRING_LIST, '/', 0, 1));
982         assertEquals("foo/2", StringUtils.join(MIXED_TYPE_LIST, '/', 0, 2));
983         assertEquals("2", StringUtils.join(MIXED_TYPE_LIST, '/', 1, 2));
984         assertEquals("", StringUtils.join(MIXED_TYPE_LIST, '/', 2, 1));
985     }
986 
987     @Test
988     void testJoin_ArrayOfBooleans() {
989         assertNull(StringUtils.join((boolean[]) null, COMMA_SEPARATOR_CHAR));
990         assertEquals("false;false", StringUtils.join(ARRAY_FALSE_FALSE, SEPARATOR_CHAR));
991         assertEquals("", StringUtils.join(EMPTY, SEPARATOR_CHAR));
992         assertEquals("false,true,false", StringUtils.join(ARRAY_FALSE_TRUE_FALSE, COMMA_SEPARATOR_CHAR));
993         assertEquals("true", StringUtils.join(ARRAY_FALSE_TRUE, SEPARATOR_CHAR, 1, 2));
994         assertNull(StringUtils.join((boolean[]) null, SEPARATOR_CHAR, 0, 1));
995         assertEquals(StringUtils.EMPTY, StringUtils.join(ARRAY_FALSE_FALSE, SEPARATOR_CHAR, 0, 0));
996         assertEquals(StringUtils.EMPTY, StringUtils.join(ARRAY_FALSE_TRUE_FALSE, SEPARATOR_CHAR, 1, 0));
997     }
998 
999     @Test
1000     void testJoin_ArrayOfBytes() {
1001         assertNull(StringUtils.join((byte[]) null, ','));
1002         assertEquals("1;2", StringUtils.join(BYTE_PRIM_LIST, SEPARATOR_CHAR));
1003         assertEquals("2", StringUtils.join(BYTE_PRIM_LIST, SEPARATOR_CHAR, 1, 2));
1004         assertNull(StringUtils.join((byte[]) null, SEPARATOR_CHAR, 0, 1));
1005         assertEquals(StringUtils.EMPTY, StringUtils.join(BYTE_PRIM_LIST, SEPARATOR_CHAR, 0, 0));
1006         assertEquals(StringUtils.EMPTY, StringUtils.join(BYTE_PRIM_LIST, SEPARATOR_CHAR, 1, 0));
1007     }
1008 
1009     @Test
1010     void testJoin_ArrayOfChars() {
1011         assertNull(StringUtils.join((char[]) null, ','));
1012         assertEquals("1;2", StringUtils.join(CHAR_PRIM_LIST, SEPARATOR_CHAR));
1013         assertEquals("2", StringUtils.join(CHAR_PRIM_LIST, SEPARATOR_CHAR, 1, 2));
1014         assertNull(StringUtils.join((char[]) null, SEPARATOR_CHAR, 0, 1));
1015         assertEquals(StringUtils.EMPTY, StringUtils.join(CHAR_PRIM_LIST, SEPARATOR_CHAR, 0, 0));
1016         assertEquals(StringUtils.EMPTY, StringUtils.join(CHAR_PRIM_LIST, SEPARATOR_CHAR, 1, 0));
1017     }
1018 
1019     @Test
1020     void testJoin_ArrayOfDoubles() {
1021         assertNull(StringUtils.join((double[]) null, ','));
1022         assertEquals("1.0;2.0", StringUtils.join(DOUBLE_PRIM_LIST, SEPARATOR_CHAR));
1023         assertEquals("2.0", StringUtils.join(DOUBLE_PRIM_LIST, SEPARATOR_CHAR, 1, 2));
1024         assertNull(StringUtils.join((double[]) null, SEPARATOR_CHAR, 0, 1));
1025         assertEquals(StringUtils.EMPTY, StringUtils.join(DOUBLE_PRIM_LIST, SEPARATOR_CHAR, 0, 0));
1026         assertEquals(StringUtils.EMPTY, StringUtils.join(DOUBLE_PRIM_LIST, SEPARATOR_CHAR, 1, 0));
1027     }
1028 
1029     @Test
1030     void testJoin_ArrayOfFloats() {
1031         assertNull(StringUtils.join((float[]) null, ','));
1032         assertEquals("1.0;2.0", StringUtils.join(FLOAT_PRIM_LIST, SEPARATOR_CHAR));
1033         assertEquals("2.0", StringUtils.join(FLOAT_PRIM_LIST, SEPARATOR_CHAR, 1, 2));
1034         assertNull(StringUtils.join((float[]) null, SEPARATOR_CHAR, 0, 1));
1035         assertEquals(StringUtils.EMPTY, StringUtils.join(FLOAT_PRIM_LIST, SEPARATOR_CHAR, 0, 0));
1036         assertEquals(StringUtils.EMPTY, StringUtils.join(FLOAT_PRIM_LIST, SEPARATOR_CHAR, 1, 0));
1037     }
1038 
1039     @Test
1040     void testJoin_ArrayOfInts() {
1041         assertNull(StringUtils.join((int[]) null, ','));
1042         assertEquals("1;2", StringUtils.join(INT_PRIM_LIST, SEPARATOR_CHAR));
1043         assertEquals("2", StringUtils.join(INT_PRIM_LIST, SEPARATOR_CHAR, 1, 2));
1044         assertNull(StringUtils.join((int[]) null, SEPARATOR_CHAR, 0, 1));
1045         assertEquals(StringUtils.EMPTY, StringUtils.join(INT_PRIM_LIST, SEPARATOR_CHAR, 0, 0));
1046         assertEquals(StringUtils.EMPTY, StringUtils.join(INT_PRIM_LIST, SEPARATOR_CHAR, 1, 0));
1047     }
1048 
1049     @Test
1050     void testJoin_ArrayOfLongs() {
1051         assertNull(StringUtils.join((long[]) null, ','));
1052         assertEquals("1;2", StringUtils.join(LONG_PRIM_LIST, SEPARATOR_CHAR));
1053         assertEquals("2", StringUtils.join(LONG_PRIM_LIST, SEPARATOR_CHAR, 1, 2));
1054         assertNull(StringUtils.join((long[]) null, SEPARATOR_CHAR, 0, 1));
1055         assertEquals(StringUtils.EMPTY, StringUtils.join(LONG_PRIM_LIST, SEPARATOR_CHAR, 0, 0));
1056         assertEquals(StringUtils.EMPTY, StringUtils.join(LONG_PRIM_LIST, SEPARATOR_CHAR, 1, 0));
1057     }
1058 
1059     @Test
1060     void testJoin_ArrayOfShorts() {
1061         assertNull(StringUtils.join((short[]) null, ','));
1062         assertEquals("1;2", StringUtils.join(SHORT_PRIM_LIST, SEPARATOR_CHAR));
1063         assertEquals("2", StringUtils.join(SHORT_PRIM_LIST, SEPARATOR_CHAR, 1, 2));
1064         assertNull(StringUtils.join((short[]) null, SEPARATOR_CHAR, 0, 1));
1065         assertEquals(StringUtils.EMPTY, StringUtils.join(SHORT_PRIM_LIST, SEPARATOR_CHAR, 0, 0));
1066         assertEquals(StringUtils.EMPTY, StringUtils.join(SHORT_PRIM_LIST, SEPARATOR_CHAR, 1, 0));
1067     }
1068 
1069     @Test
1070     void testJoin_ArrayString_EmptyDelimiter() {
1071         assertNull(StringUtils.join((Object[]) null, null));
1072         assertEquals(TEXT_LIST_NOSEP, StringUtils.join(ARRAY_LIST, null));
1073         assertEquals(TEXT_LIST_NOSEP, StringUtils.join(ARRAY_LIST, ""));
1074 
1075         assertEquals("", StringUtils.join(NULL_ARRAY_LIST, null));
1076 
1077         assertEquals("", StringUtils.join(EMPTY_ARRAY_LIST, null));
1078         assertEquals("", StringUtils.join(EMPTY_ARRAY_LIST, ""));
1079 
1080         assertEquals("", StringUtils.join(MIXED_ARRAY_LIST, "", 0, MIXED_ARRAY_LIST.length - 1));
1081     }
1082 
1083     @ParameterizedTest
1084     @ValueSource(strings = {",", ";", Supplementary.CharU20000, Supplementary.CharU20001})
1085     void testJoin_ArrayString_NonEmptyDelimiter(final String delimiter) {
1086         assertEquals("", StringUtils.join(EMPTY_ARRAY_LIST, delimiter));
1087 
1088         assertEquals(String.join(delimiter, ARRAY_LIST), StringUtils.join(ARRAY_LIST, delimiter));
1089         assertEquals(delimiter + delimiter + "foo", StringUtils.join(MIXED_ARRAY_LIST, delimiter));
1090         assertEquals(String.join(delimiter, "foo", "2"), StringUtils.join(MIXED_TYPE_LIST, delimiter));
1091 
1092         assertEquals(delimiter, StringUtils.join(MIXED_ARRAY_LIST, delimiter, 0, MIXED_ARRAY_LIST.length - 1));
1093         assertEquals("foo", StringUtils.join(MIXED_TYPE_LIST, delimiter, 0, 1));
1094         assertEquals(String.join(delimiter, "foo", "2"), StringUtils.join(MIXED_TYPE_LIST, delimiter, 0, 2));
1095         assertEquals("2", StringUtils.join(MIXED_TYPE_LIST, delimiter, 1, 2));
1096         assertEquals("", StringUtils.join(MIXED_TYPE_LIST, delimiter, 2, 1));
1097     }
1098 
1099     @Test
1100     void testJoin_IterableChar() {
1101         assertNull(StringUtils.join((Iterable<?>) null, ','));
1102         assertEquals(TEXT_LIST_CHAR, StringUtils.join(Arrays.asList(ARRAY_LIST), SEPARATOR_CHAR));
1103         assertEquals("", StringUtils.join(Arrays.asList(NULL_ARRAY_LIST), SEPARATOR_CHAR));
1104         assertEquals("", StringUtils.join(Arrays.asList(EMPTY_ARRAY_LIST), SEPARATOR_CHAR));
1105         assertEquals("foo", StringUtils.join(Collections.singleton("foo"), 'x'));
1106     }
1107 
1108     @Test
1109     void testJoin_IterableString() {
1110         assertNull(StringUtils.join((Iterable<?>) null, null));
1111         assertEquals(TEXT_LIST_NOSEP, StringUtils.join(Arrays.asList(ARRAY_LIST), null));
1112         assertEquals(TEXT_LIST_NOSEP, StringUtils.join(Arrays.asList(ARRAY_LIST), ""));
1113         assertEquals("foo", StringUtils.join(Collections.singleton("foo"), "x"));
1114         assertEquals("foo", StringUtils.join(Collections.singleton("foo"), null));
1115 
1116         assertEquals("", StringUtils.join(Arrays.asList(NULL_ARRAY_LIST), null));
1117 
1118         assertEquals("", StringUtils.join(Arrays.asList(EMPTY_ARRAY_LIST), null));
1119         assertEquals("", StringUtils.join(Arrays.asList(EMPTY_ARRAY_LIST), ""));
1120         assertEquals("", StringUtils.join(Arrays.asList(EMPTY_ARRAY_LIST), SEPARATOR));
1121 
1122         assertEquals(TEXT_LIST, StringUtils.join(Arrays.asList(ARRAY_LIST), SEPARATOR));
1123     }
1124 
1125     @Test
1126     void testJoin_IteratorChar() {
1127         assertNull(StringUtils.join((Iterator<?>) null, ','));
1128         assertEquals(TEXT_LIST_CHAR, StringUtils.join(Arrays.asList(ARRAY_LIST).iterator(), SEPARATOR_CHAR));
1129         assertEquals("", StringUtils.join(Arrays.asList(NULL_ARRAY_LIST).iterator(), SEPARATOR_CHAR));
1130         assertEquals("", StringUtils.join(Arrays.asList(EMPTY_ARRAY_LIST).iterator(), SEPARATOR_CHAR));
1131         assertEquals("foo", StringUtils.join(Collections.singleton("foo").iterator(), 'x'));
1132         assertEquals("null", StringUtils.join(Arrays.asList(NULL_TO_STRING_LIST).iterator(), SEPARATOR_CHAR));
1133     }
1134 
1135     @Test
1136     void testJoin_IteratorString() {
1137         assertNull(StringUtils.join((Iterator<?>) null, null));
1138         assertEquals(TEXT_LIST_NOSEP, StringUtils.join(Arrays.asList(ARRAY_LIST).iterator(), null));
1139         assertEquals(TEXT_LIST_NOSEP, StringUtils.join(Arrays.asList(ARRAY_LIST).iterator(), ""));
1140         assertEquals("foo", StringUtils.join(Collections.singleton("foo").iterator(), "x"));
1141         assertEquals("foo", StringUtils.join(Collections.singleton("foo").iterator(), null));
1142 
1143         assertEquals("", StringUtils.join(Arrays.asList(NULL_ARRAY_LIST).iterator(), null));
1144 
1145         assertEquals("", StringUtils.join(Arrays.asList(EMPTY_ARRAY_LIST).iterator(), null));
1146         assertEquals("", StringUtils.join(Arrays.asList(EMPTY_ARRAY_LIST).iterator(), ""));
1147         assertEquals("", StringUtils.join(Arrays.asList(EMPTY_ARRAY_LIST).iterator(), SEPARATOR));
1148 
1149         assertEquals(TEXT_LIST, StringUtils.join(Arrays.asList(ARRAY_LIST).iterator(), SEPARATOR));
1150 
1151         assertEquals("null", StringUtils.join(Arrays.asList(NULL_TO_STRING_LIST).iterator(), SEPARATOR));
1152     }
1153 
1154     @Test
1155     void testJoin_List_CharDelimiter() {
1156         assertEquals("/", StringUtils.join(MIXED_STRING_LIST, '/', 0, MIXED_STRING_LIST.size() - 1));
1157         assertEquals("foo", StringUtils.join(MIXED_TYPE_OBJECT_LIST, '/', 0, 1));
1158         assertEquals("foo/2", StringUtils.join(MIXED_TYPE_OBJECT_LIST, '/', 0, 2));
1159         assertEquals("2", StringUtils.join(MIXED_TYPE_OBJECT_LIST, '/', 1, 2));
1160         assertEquals("", StringUtils.join(MIXED_TYPE_OBJECT_LIST, '/', 2, 1));
1161         assertNull(null, StringUtils.join((List<?>) null, '/', 0, 1));
1162     }
1163 
1164     @Test
1165     void testJoin_List_EmptyDelimiter() {
1166         assertNull(StringUtils.join((List<String>) null, null));
1167         assertEquals(TEXT_LIST_NOSEP, StringUtils.join(STRING_LIST, null));
1168         assertEquals(TEXT_LIST_NOSEP, StringUtils.join(STRING_LIST, ""));
1169 
1170         assertEquals("", StringUtils.join(NULL_STRING_LIST, null));
1171 
1172         assertEquals("", StringUtils.join(EMPTY_STRING_LIST, null));
1173         assertEquals("", StringUtils.join(EMPTY_STRING_LIST, ""));
1174 
1175         assertEquals("", StringUtils.join(MIXED_STRING_LIST, "", 0, MIXED_STRING_LIST.size() - 1));
1176     }
1177 
1178     @ParameterizedTest
1179     @ValueSource(strings = {",", ";", Supplementary.CharU20000, Supplementary.CharU20001})
1180     void testJoin_List_NonEmptyDelimiter(final String delimiter) {
1181         assertEquals("", StringUtils.join(EMPTY_STRING_LIST, delimiter));
1182 
1183         assertEquals(String.join(delimiter, STRING_LIST), StringUtils.join(STRING_LIST, delimiter));
1184         assertEquals(delimiter + delimiter + "foo", StringUtils.join(MIXED_STRING_LIST, delimiter));
1185         assertEquals(String.join(delimiter, "foo", "2"), StringUtils.join(MIXED_TYPE_OBJECT_LIST, delimiter));
1186 
1187         assertEquals(delimiter, StringUtils.join(MIXED_STRING_LIST, delimiter, 0, MIXED_STRING_LIST.size() - 1));
1188         assertEquals("foo", StringUtils.join(MIXED_TYPE_OBJECT_LIST, delimiter, 0, 1));
1189         assertEquals(String.join(delimiter, "foo", "2"), StringUtils.join(MIXED_TYPE_OBJECT_LIST, delimiter, 0, 2));
1190         assertEquals("2", StringUtils.join(MIXED_TYPE_OBJECT_LIST, delimiter, 1, 2));
1191         assertEquals("", StringUtils.join(MIXED_TYPE_OBJECT_LIST, delimiter, 2, 1));
1192         assertNull(null, StringUtils.join((List<?>) null, delimiter, 0, 1));
1193     }
1194 
1195     @Test
1196     void testJoin_Objectarray() {
1197 //        assertNull(StringUtils.join(null)); // generates warning
1198         assertNull(StringUtils.join((Object[]) null)); // equivalent explicit cast
1199         // test additional varargs calls
1200         assertEquals("", StringUtils.join()); // empty array
1201         assertEquals("", StringUtils.join((Object) null)); // => new Object[]{null}
1202 
1203         assertEquals("", StringUtils.join(EMPTY_ARRAY_LIST));
1204         assertEquals("", StringUtils.join(NULL_ARRAY_LIST));
1205         assertEquals("null", StringUtils.join(NULL_TO_STRING_LIST));
1206         assertEquals("abc", StringUtils.join("a", "b", "c"));
1207         assertEquals("a", StringUtils.join(null, "a", ""));
1208         assertEquals("foo", StringUtils.join(MIXED_ARRAY_LIST));
1209         assertEquals("foo2", StringUtils.join(MIXED_TYPE_LIST));
1210     }
1211 
1212     @Test
1213     void testJoin_Objects() {
1214         assertEquals("abc", StringUtils.join("a", "b", "c"));
1215         assertEquals("a", StringUtils.join(null, "", "a"));
1216         assertNull(StringUtils.join((Object[]) null));
1217     }
1218 
1219     @ParameterizedTest
1220     @ValueSource(strings = {",", ";", Supplementary.CharU20000, Supplementary.CharU20001})
1221     void testJoinWith(final String delimiter) {
1222         assertEquals("", StringUtils.joinWith(delimiter)); // empty array
1223         assertEquals("", StringUtils.joinWith(delimiter, (Object[]) NULL_ARRAY_LIST));
1224         assertEquals("null", StringUtils.joinWith(delimiter, NULL_TO_STRING_LIST)); // toString method prints 'null'
1225 
1226         assertEquals(String.join(delimiter, "a", "b", "c"), StringUtils.joinWith(delimiter, "a", "b", "c"));
1227         assertEquals(String.join(delimiter, "", "a", ""), StringUtils.joinWith(delimiter, null, "a", ""));
1228         assertEquals(String.join(delimiter, "", "a", ""), StringUtils.joinWith(delimiter, "", "a", ""));
1229 
1230         assertEquals("ab", StringUtils.joinWith(null, "a", "b"));
1231     }
1232 
1233     @Test
1234     void testJoinWithThrowsException() {
1235         assertIllegalArgumentException(() -> StringUtils.joinWith(",", (Object[]) null));
1236     }
1237 
1238     @Disabled
1239     @Test
1240     void testLang1593() {
1241         final int[] arr = {1, 2, 3, 4, 5, 6, 7};
1242         final String expected = StringUtils.join(arr, '-');
1243         final String actual = StringUtils.join(arr, "-");
1244         assertEquals(expected, actual);
1245     }
1246 
1247     @Test
1248     void testLang623() {
1249         assertEquals("t", StringUtils.replaceChars("\u00DE", '\u00DE', 't'));
1250         assertEquals("t", StringUtils.replaceChars("\u00FE", '\u00FE', 't'));
1251     }
1252 
1253     @Test
1254     void testLANG666() {
1255         assertEquals("12", StringUtils.stripEnd("120.00", ".0"));
1256         assertEquals("121", StringUtils.stripEnd("121.00", ".0"));
1257     }
1258 
1259     @Test
1260     void testLeftPad_StringInt() {
1261         assertNull(StringUtils.leftPad(null, 5));
1262         assertEquals("     ", StringUtils.leftPad("", 5));
1263         assertEquals("  abc", StringUtils.leftPad("abc", 5));
1264         assertEquals("abc", StringUtils.leftPad("abc", 2));
1265     }
1266 
1267     @Test
1268     void testLeftPad_StringIntChar() {
1269         assertNull(StringUtils.leftPad(null, 5, ' '));
1270         assertEquals("     ", StringUtils.leftPad("", 5, ' '));
1271         assertEquals("  abc", StringUtils.leftPad("abc", 5, ' '));
1272         assertEquals("xxabc", StringUtils.leftPad("abc", 5, 'x'));
1273         assertEquals("\uffff\uffffabc", StringUtils.leftPad("abc", 5, '\uffff'));
1274         assertEquals("abc", StringUtils.leftPad("abc", 2, ' '));
1275         final String str = StringUtils.leftPad("aaa", 10000, 'a');  // bigger than pad length
1276         assertEquals(10000, str.length());
1277         assertTrue(StringUtils.containsOnly(str, 'a'));
1278     }
1279 
1280     @Test
1281     void testLeftPad_StringIntString() {
1282         assertNull(StringUtils.leftPad(null, 5, "-+"));
1283         assertNull(StringUtils.leftPad(null, 5, null));
1284         assertEquals("     ", StringUtils.leftPad("", 5, " "));
1285         assertEquals("-+-+abc", StringUtils.leftPad("abc", 7, "-+"));
1286         assertEquals("-+~abc", StringUtils.leftPad("abc", 6, "-+~"));
1287         assertEquals("-+abc", StringUtils.leftPad("abc", 5, "-+~"));
1288         assertEquals("abc", StringUtils.leftPad("abc", 2, " "));
1289         assertEquals("abc", StringUtils.leftPad("abc", -1, " "));
1290         assertEquals("  abc", StringUtils.leftPad("abc", 5, null));
1291         assertEquals("  abc", StringUtils.leftPad("abc", 5, ""));
1292     }
1293 
1294     @Test
1295     void testLength_CharBuffer() {
1296         assertEquals(0, StringUtils.length(CharBuffer.wrap("")));
1297         assertEquals(1, StringUtils.length(CharBuffer.wrap("A")));
1298         assertEquals(1, StringUtils.length(CharBuffer.wrap(" ")));
1299         assertEquals(8, StringUtils.length(CharBuffer.wrap("ABCDEFGH")));
1300     }
1301 
1302     @Test
1303     void testLengthString() {
1304         assertEquals(0, StringUtils.length(null));
1305         assertEquals(0, StringUtils.length(""));
1306         assertEquals(0, StringUtils.length(StringUtils.EMPTY));
1307         assertEquals(1, StringUtils.length("A"));
1308         assertEquals(1, StringUtils.length(" "));
1309         assertEquals(8, StringUtils.length("ABCDEFGH"));
1310     }
1311 
1312     @Test
1313     void testLengthStringBuffer() {
1314         assertEquals(0, StringUtils.length(new StringBuffer("")));
1315         assertEquals(0, StringUtils.length(new StringBuffer(StringUtils.EMPTY)));
1316         assertEquals(1, StringUtils.length(new StringBuffer("A")));
1317         assertEquals(1, StringUtils.length(new StringBuffer(" ")));
1318         assertEquals(8, StringUtils.length(new StringBuffer("ABCDEFGH")));
1319     }
1320 
1321     @Test
1322     void testLengthStringBuilder() {
1323         assertEquals(0, StringUtils.length(new StringBuilder("")));
1324         assertEquals(0, StringUtils.length(new StringBuilder(StringUtils.EMPTY)));
1325         assertEquals(1, StringUtils.length(new StringBuilder("A")));
1326         assertEquals(1, StringUtils.length(new StringBuilder(" ")));
1327         assertEquals(8, StringUtils.length(new StringBuilder("ABCDEFGH")));
1328     }
1329 
1330     @Test
1331     void testLowerCase() {
1332         assertNull(StringUtils.lowerCase(null));
1333         assertNull(StringUtils.lowerCase(null, Locale.ENGLISH));
1334         assertEquals("foo test thing", StringUtils.lowerCase("fOo test THING"), "lowerCase(String) failed");
1335         assertEquals("", StringUtils.lowerCase(""), "lowerCase(empty-string) failed");
1336         assertEquals("foo test thing", StringUtils.lowerCase("fOo test THING", Locale.ENGLISH),
1337                 "lowerCase(String, Locale) failed");
1338         assertEquals("", StringUtils.lowerCase("", Locale.ENGLISH), "lowerCase(empty-string, Locale) failed");
1339     }
1340 
1341     @Test
1342     void testNormalizeSpace() {
1343         // Java says a non-breaking whitespace is not a whitespace.
1344         assertFalse(Character.isWhitespace('\u00A0'));
1345         //
1346         assertNull(StringUtils.normalizeSpace(null));
1347         assertEquals("", StringUtils.normalizeSpace(""));
1348         assertEquals("", StringUtils.normalizeSpace(" "));
1349         assertEquals("", StringUtils.normalizeSpace("\t"));
1350         assertEquals("", StringUtils.normalizeSpace("\n"));
1351         assertEquals("", StringUtils.normalizeSpace("\u0009"));
1352         assertEquals("", StringUtils.normalizeSpace("\u000B"));
1353         assertEquals("", StringUtils.normalizeSpace("\u000C"));
1354         assertEquals("", StringUtils.normalizeSpace("\u001C"));
1355         assertEquals("", StringUtils.normalizeSpace("\u001D"));
1356         assertEquals("", StringUtils.normalizeSpace("\u001E"));
1357         assertEquals("", StringUtils.normalizeSpace("\u001F"));
1358         assertEquals("", StringUtils.normalizeSpace("\f"));
1359         assertEquals("", StringUtils.normalizeSpace("\r"));
1360         assertEquals("a", StringUtils.normalizeSpace("  a  "));
1361         assertEquals("a b c", StringUtils.normalizeSpace("  a  b   c  "));
1362         assertEquals("a b c", StringUtils.normalizeSpace("a\t\f\r  b\u000B   c\n"));
1363         assertEquals("a   b c", StringUtils.normalizeSpace("a\t\f\r  " + HARD_SPACE + HARD_SPACE + "b\u000B   c\n"));
1364         assertEquals("b", StringUtils.normalizeSpace("\u0000b"));
1365         assertEquals("b", StringUtils.normalizeSpace("b\u0000"));
1366     }
1367 
1368     @Test
1369     void testOverlay_StringStringIntInt() {
1370         assertNull(StringUtils.overlay(null, null, 2, 4));
1371         assertNull(StringUtils.overlay(null, null, -2, -4));
1372 
1373         assertEquals("", StringUtils.overlay("", null, 0, 0));
1374         assertEquals("", StringUtils.overlay("", "", 0, 0));
1375         assertEquals("zzzz", StringUtils.overlay("", "zzzz", 0, 0));
1376         assertEquals("zzzz", StringUtils.overlay("", "zzzz", 2, 4));
1377         assertEquals("zzzz", StringUtils.overlay("", "zzzz", -2, -4));
1378 
1379         assertEquals("abef", StringUtils.overlay("abcdef", null, 2, 4));
1380         assertEquals("abef", StringUtils.overlay("abcdef", null, 4, 2));
1381         assertEquals("abef", StringUtils.overlay("abcdef", "", 2, 4));
1382         assertEquals("abef", StringUtils.overlay("abcdef", "", 4, 2));
1383         assertEquals("abzzzzef", StringUtils.overlay("abcdef", "zzzz", 2, 4));
1384         assertEquals("abzzzzef", StringUtils.overlay("abcdef", "zzzz", 4, 2));
1385 
1386         assertEquals("zzzzef", StringUtils.overlay("abcdef", "zzzz", -1, 4));
1387         assertEquals("zzzzef", StringUtils.overlay("abcdef", "zzzz", 4, -1));
1388         assertEquals("zzzzabcdef", StringUtils.overlay("abcdef", "zzzz", -2, -1));
1389         assertEquals("zzzzabcdef", StringUtils.overlay("abcdef", "zzzz", -1, -2));
1390         assertEquals("abcdzzzz", StringUtils.overlay("abcdef", "zzzz", 4, 10));
1391         assertEquals("abcdzzzz", StringUtils.overlay("abcdef", "zzzz", 10, 4));
1392         assertEquals("abcdefzzzz", StringUtils.overlay("abcdef", "zzzz", 8, 10));
1393         assertEquals("abcdefzzzz", StringUtils.overlay("abcdef", "zzzz", 10, 8));
1394     }
1395 
1396     /**
1397      * Tests {@code prependIfMissing}.
1398      */
1399     @Test
1400     void testPrependIfMissing() {
1401         assertNull(StringUtils.prependIfMissing(null, null), "prependIfMissing(null,null)");
1402         assertEquals("abc", StringUtils.prependIfMissing("abc", null), "prependIfMissing(abc,null)");
1403         assertEquals("xyz", StringUtils.prependIfMissing("", "xyz"), "prependIfMissing(\"\",xyz)");
1404         assertEquals("xyzabc", StringUtils.prependIfMissing("abc", "xyz"), "prependIfMissing(abc,xyz)");
1405         assertEquals("xyzabc", StringUtils.prependIfMissing("xyzabc", "xyz"), "prependIfMissing(xyzabc,xyz)");
1406         assertEquals("xyzXYZabc", StringUtils.prependIfMissing("XYZabc", "xyz"), "prependIfMissing(XYZabc,xyz)");
1407 
1408         assertNull(StringUtils.prependIfMissing(null, null, (CharSequence[]) null), "prependIfMissing(null,null null)");
1409         assertEquals("abc", StringUtils.prependIfMissing("abc", null, (CharSequence[]) null), "prependIfMissing(abc,null,null)");
1410         assertEquals("xyz", StringUtils.prependIfMissing("", "xyz", (CharSequence[]) null), "prependIfMissing(\"\",xyz,null)");
1411         assertEquals("xyzabc", StringUtils.prependIfMissing("abc", "xyz", (CharSequence) null), "prependIfMissing(abc,xyz,{null})");
1412         assertEquals("abc", StringUtils.prependIfMissing("abc", "xyz", ""), "prependIfMissing(abc,xyz,\"\")");
1413         assertEquals("xyzabc", StringUtils.prependIfMissing("abc", "xyz", "mno"), "prependIfMissing(abc,xyz,mno)");
1414         assertEquals("xyzabc", StringUtils.prependIfMissing("xyzabc", "xyz", "mno"), "prependIfMissing(xyzabc,xyz,mno)");
1415         assertEquals("mnoabc", StringUtils.prependIfMissing("mnoabc", "xyz", "mno"), "prependIfMissing(mnoabc,xyz,mno)");
1416         assertEquals("xyzXYZabc", StringUtils.prependIfMissing("XYZabc", "xyz", "mno"), "prependIfMissing(XYZabc,xyz,mno)");
1417         assertEquals("xyzMNOabc", StringUtils.prependIfMissing("MNOabc", "xyz", "mno"), "prependIfMissing(MNOabc,xyz,mno)");
1418     }
1419 
1420     /**
1421      * Tests {@code prependIfMissingIgnoreCase}.
1422      */
1423     @Test
1424     void testPrependIfMissingIgnoreCase() {
1425         assertNull(StringUtils.prependIfMissingIgnoreCase(null, null), "prependIfMissingIgnoreCase(null,null)");
1426         assertEquals("abc", StringUtils.prependIfMissingIgnoreCase("abc", null), "prependIfMissingIgnoreCase(abc,null)");
1427         assertEquals("xyz", StringUtils.prependIfMissingIgnoreCase("", "xyz"), "prependIfMissingIgnoreCase(\"\",xyz)");
1428         assertEquals("xyzabc", StringUtils.prependIfMissingIgnoreCase("abc", "xyz"), "prependIfMissingIgnoreCase(abc,xyz)");
1429         assertEquals("xyzabc", StringUtils.prependIfMissingIgnoreCase("xyzabc", "xyz"), "prependIfMissingIgnoreCase(xyzabc,xyz)");
1430         assertEquals("XYZabc", StringUtils.prependIfMissingIgnoreCase("XYZabc", "xyz"), "prependIfMissingIgnoreCase(XYZabc,xyz)");
1431 
1432         assertNull(StringUtils.prependIfMissingIgnoreCase(null, null, (CharSequence[]) null), "prependIfMissingIgnoreCase(null,null null)");
1433         assertEquals("abc", StringUtils.prependIfMissingIgnoreCase("abc", null, (CharSequence[]) null), "prependIfMissingIgnoreCase(abc,null,null)");
1434         assertEquals("xyz", StringUtils.prependIfMissingIgnoreCase("", "xyz", (CharSequence[]) null), "prependIfMissingIgnoreCase(\"\",xyz,null)");
1435         assertEquals("xyzabc", StringUtils.prependIfMissingIgnoreCase("abc", "xyz", (CharSequence) null), "prependIfMissingIgnoreCase(abc,xyz,{null})");
1436         assertEquals("abc", StringUtils.prependIfMissingIgnoreCase("abc", "xyz", ""), "prependIfMissingIgnoreCase(abc,xyz,\"\")");
1437         assertEquals("xyzabc", StringUtils.prependIfMissingIgnoreCase("abc", "xyz", "mno"), "prependIfMissingIgnoreCase(abc,xyz,mno)");
1438         assertEquals("xyzabc", StringUtils.prependIfMissingIgnoreCase("xyzabc", "xyz", "mno"), "prependIfMissingIgnoreCase(xyzabc,xyz,mno)");
1439         assertEquals("mnoabc", StringUtils.prependIfMissingIgnoreCase("mnoabc", "xyz", "mno"), "prependIfMissingIgnoreCase(mnoabc,xyz,mno)");
1440         assertEquals("XYZabc", StringUtils.prependIfMissingIgnoreCase("XYZabc", "xyz", "mno"), "prependIfMissingIgnoreCase(XYZabc,xyz,mno)");
1441         assertEquals("MNOabc", StringUtils.prependIfMissingIgnoreCase("MNOabc", "xyz", "mno"), "prependIfMissingIgnoreCase(MNOabc,xyz,mno)");
1442     }
1443 
1444     @Test
1445     void testReCapitalize() {
1446         // reflection type of tests: Sentences.
1447         assertEquals(SENTENCE_UNCAP, StringUtils.uncapitalize(StringUtils.capitalize(SENTENCE_UNCAP)),
1448                 "uncapitalize(capitalize(String)) failed");
1449         assertEquals(SENTENCE_CAP, StringUtils.capitalize(StringUtils.uncapitalize(SENTENCE_CAP)),
1450                 "capitalize(uncapitalize(String)) failed");
1451 
1452         // reflection type of tests: One word.
1453         assertEquals(FOO_UNCAP, StringUtils.uncapitalize(StringUtils.capitalize(FOO_UNCAP)),
1454                 "uncapitalize(capitalize(String)) failed");
1455         assertEquals(FOO_CAP, StringUtils.capitalize(StringUtils.uncapitalize(FOO_CAP)),
1456                 "capitalize(uncapitalize(String)) failed");
1457     }
1458 
1459     @Test
1460     void testRemove_char() {
1461         // StringUtils.remove(null, *)       = null
1462         assertNull(StringUtils.remove(null, null));
1463         assertNull(StringUtils.remove(null, 'a'));
1464 
1465         // StringUtils.remove("", *)          = ""
1466         assertEquals("", StringUtils.remove("", null));
1467         assertEquals("", StringUtils.remove("", 'a'));
1468 
1469         // StringUtils.remove("queued", 'u') = "qeed"
1470         assertEquals("qeed", StringUtils.remove("queued", 'u'));
1471 
1472         // StringUtils.remove("queued", 'z') = "queued"
1473         assertEquals("queued", StringUtils.remove("queued", 'z'));
1474     }
1475 
1476     @Test
1477     void testRemove_String() {
1478         // StringUtils.remove(null, *)        = null
1479         assertNull(StringUtils.remove(null, null));
1480         assertNull(StringUtils.remove(null, ""));
1481         assertNull(StringUtils.remove(null, "a"));
1482 
1483         // StringUtils.remove("", *)          = ""
1484         assertEquals("", StringUtils.remove("", null));
1485         assertEquals("", StringUtils.remove("", ""));
1486         assertEquals("", StringUtils.remove("", "a"));
1487 
1488         // StringUtils.remove(*, null)        = *
1489         assertNull(StringUtils.remove(null, null));
1490         assertEquals("", StringUtils.remove("", null));
1491         assertEquals("a", StringUtils.remove("a", null));
1492 
1493         // StringUtils.remove(*, "")          = *
1494         assertNull(StringUtils.remove(null, ""));
1495         assertEquals("", StringUtils.remove("", ""));
1496         assertEquals("a", StringUtils.remove("a", ""));
1497 
1498         // StringUtils.remove("queued", "ue") = "qd"
1499         assertEquals("qd", StringUtils.remove("queued", "ue"));
1500 
1501         // StringUtils.remove("queued", "zz") = "queued"
1502         assertEquals("queued", StringUtils.remove("queued", "zz"));
1503     }
1504 
1505     @Test
1506     void testRemoveAll_StringString() {
1507         assertNull(StringUtils.removeAll(null, ""));
1508         assertEquals("any", StringUtils.removeAll("any", null));
1509 
1510         assertEquals("any", StringUtils.removeAll("any", ""));
1511         assertEquals("", StringUtils.removeAll("any", ".*"));
1512         assertEquals("", StringUtils.removeAll("any", ".+"));
1513         assertEquals("", StringUtils.removeAll("any", ".?"));
1514 
1515         assertEquals("A\nB", StringUtils.removeAll("A<__>\n<__>B", "<.*>"));
1516         assertEquals("AB", StringUtils.removeAll("A<__>\n<__>B", "(?s)<.*>"));
1517         assertEquals("ABC123", StringUtils.removeAll("ABCabc123abc", "[a-z]"));
1518 
1519         assertThrows(PatternSyntaxException.class, () -> StringUtils.removeAll("any", "{badRegexSyntax}"),
1520                 "StringUtils.removeAll expecting PatternSyntaxException");
1521     }
1522 
1523     @Test
1524     void testRemoveEnd() {
1525         // StringUtils.removeEnd("", *)        = ""
1526         assertNull(StringUtils.removeEnd(null, null));
1527         assertNull(StringUtils.removeEnd(null, ""));
1528         assertNull(StringUtils.removeEnd(null, "a"));
1529 
1530         // StringUtils.removeEnd(*, null)      = *
1531         assertEquals(StringUtils.removeEnd("", null), "");
1532         assertEquals(StringUtils.removeEnd("", ""), "");
1533         assertEquals(StringUtils.removeEnd("", "a"), "");
1534 
1535         // All others:
1536         assertEquals(StringUtils.removeEnd("www.domain.com.", ".com"), "www.domain.com.");
1537         assertEquals(StringUtils.removeEnd("www.domain.com", ".com"), "www.domain");
1538         assertEquals(StringUtils.removeEnd("www.domain", ".com"), "www.domain");
1539         assertEquals(StringUtils.removeEnd("domain.com", ""), "domain.com");
1540         assertEquals(StringUtils.removeEnd("domain.com", null), "domain.com");
1541     }
1542 
1543     @Test
1544     void testRemoveEndIgnoreCase() {
1545         // StringUtils.removeEndIgnoreCase("", *)        = ""
1546         assertNull(StringUtils.removeEndIgnoreCase(null, null), "removeEndIgnoreCase(null, null)");
1547         assertNull(StringUtils.removeEndIgnoreCase(null, ""), "removeEndIgnoreCase(null, \"\")");
1548         assertNull(StringUtils.removeEndIgnoreCase(null, "a"), "removeEndIgnoreCase(null, \"a\")");
1549 
1550         // StringUtils.removeEnd(*, null)      = *
1551         assertEquals(StringUtils.removeEndIgnoreCase("", null), "", "removeEndIgnoreCase(\"\", null)");
1552         assertEquals(StringUtils.removeEndIgnoreCase("", ""), "", "removeEndIgnoreCase(\"\", \"\")");
1553         assertEquals(StringUtils.removeEndIgnoreCase("", "a"), "", "removeEndIgnoreCase(\"\", \"a\")");
1554 
1555         // All others:
1556         assertEquals(StringUtils.removeEndIgnoreCase("www.domain.com.", ".com"), "www.domain.com.", "removeEndIgnoreCase(\"www.domain.com.\", \".com\")");
1557         assertEquals(StringUtils.removeEndIgnoreCase("www.domain.com", ".com"), "www.domain", "removeEndIgnoreCase(\"www.domain.com\", \".com\")");
1558         assertEquals(StringUtils.removeEndIgnoreCase("www.domain", ".com"), "www.domain", "removeEndIgnoreCase(\"www.domain\", \".com\")");
1559         assertEquals(StringUtils.removeEndIgnoreCase("domain.com", ""), "domain.com", "removeEndIgnoreCase(\"domain.com\", \"\")");
1560         assertEquals(StringUtils.removeEndIgnoreCase("domain.com", null), "domain.com", "removeEndIgnoreCase(\"domain.com\", null)");
1561 
1562         // Case-insensitive:
1563         assertEquals(StringUtils.removeEndIgnoreCase("www.domain.com", ".COM"), "www.domain", "removeEndIgnoreCase(\"www.domain.com\", \".COM\")");
1564         assertEquals(StringUtils.removeEndIgnoreCase("www.domain.COM", ".com"), "www.domain", "removeEndIgnoreCase(\"www.domain.COM\", \".com\")");
1565     }
1566 
1567     @Test
1568     void testRemoveFirst_StringString() {
1569         assertNull(StringUtils.removeFirst(null, ""));
1570         assertEquals("any", StringUtils.removeFirst("any", null));
1571 
1572         assertEquals("any", StringUtils.removeFirst("any", ""));
1573         assertEquals("", StringUtils.removeFirst("any", ".*"));
1574         assertEquals("", StringUtils.removeFirst("any", ".+"));
1575         assertEquals("bc", StringUtils.removeFirst("abc", ".?"));
1576 
1577         assertEquals("A\n<__>B", StringUtils.removeFirst("A<__>\n<__>B", "<.*>"));
1578         assertEquals("AB", StringUtils.removeFirst("A<__>\n<__>B", "(?s)<.*>"));
1579         assertEquals("ABCbc123", StringUtils.removeFirst("ABCabc123", "[a-z]"));
1580         assertEquals("ABC123abc", StringUtils.removeFirst("ABCabc123abc", "[a-z]+"));
1581 
1582         assertThrows(PatternSyntaxException.class, () -> StringUtils.removeFirst("any", "{badRegexSyntax}"),
1583                 "StringUtils.removeFirst expecting PatternSyntaxException");
1584     }
1585 
1586     @Test
1587     void testRemoveIgnoreCase_String() {
1588         // StringUtils.removeIgnoreCase(null, *) = null
1589         assertNull(StringUtils.removeIgnoreCase(null, null));
1590         assertNull(StringUtils.removeIgnoreCase(null, ""));
1591         assertNull(StringUtils.removeIgnoreCase(null, "a"));
1592 
1593         // StringUtils.removeIgnoreCase("", *) = ""
1594         assertEquals("", StringUtils.removeIgnoreCase("", null));
1595         assertEquals("", StringUtils.removeIgnoreCase("", ""));
1596         assertEquals("", StringUtils.removeIgnoreCase("", "a"));
1597 
1598         // StringUtils.removeIgnoreCase(*, null) = *
1599         assertNull(StringUtils.removeIgnoreCase(null, null));
1600         assertEquals("", StringUtils.removeIgnoreCase("", null));
1601         assertEquals("a", StringUtils.removeIgnoreCase("a", null));
1602 
1603         // StringUtils.removeIgnoreCase(*, "") = *
1604         assertNull(StringUtils.removeIgnoreCase(null, ""));
1605         assertEquals("", StringUtils.removeIgnoreCase("", ""));
1606         assertEquals("a", StringUtils.removeIgnoreCase("a", ""));
1607 
1608         // StringUtils.removeIgnoreCase("queued", "ue") = "qd"
1609         assertEquals("qd", StringUtils.removeIgnoreCase("queued", "ue"));
1610 
1611         // StringUtils.removeIgnoreCase("queued", "zz") = "queued"
1612         assertEquals("queued", StringUtils.removeIgnoreCase("queued", "zz"));
1613 
1614         // IgnoreCase
1615         // StringUtils.removeIgnoreCase("quEUed", "UE") = "qd"
1616         assertEquals("qd", StringUtils.removeIgnoreCase("quEUed", "UE"));
1617 
1618         // StringUtils.removeIgnoreCase("queued", "zZ") = "queued"
1619         assertEquals("queued", StringUtils.removeIgnoreCase("queued", "zZ"));
1620 
1621         // StringUtils.removeIgnoreCase("\u0130x", "x") = "\u0130"
1622         assertEquals("\u0130", StringUtils.removeIgnoreCase("\u0130x", "x"));
1623 
1624         // LANG-1453
1625         StringUtils.removeIgnoreCase("İa", "a");
1626     }
1627 
1628     @Test
1629     void testRemovePattern_StringString() {
1630         assertNull(StringUtils.removePattern(null, ""));
1631         assertEquals("any", StringUtils.removePattern("any", null));
1632 
1633         assertEquals("", StringUtils.removePattern("", ""));
1634         assertEquals("", StringUtils.removePattern("", ".*"));
1635         assertEquals("", StringUtils.removePattern("", ".+"));
1636 
1637         assertEquals("AB", StringUtils.removePattern("A<__>\n<__>B", "<.*>"));
1638         assertEquals("AB", StringUtils.removePattern("A<__>\\n<__>B", "<.*>"));
1639         assertEquals("", StringUtils.removePattern("<A>x\\ny</A>", "<A>.*</A>"));
1640         assertEquals("", StringUtils.removePattern("<A>\nxy\n</A>", "<A>.*</A>"));
1641 
1642         assertEquals("ABC123", StringUtils.removePattern("ABCabc123", "[a-z]"));
1643     }
1644 
1645     @Test
1646     void testRemoveStartChar() {
1647         // StringUtils.removeStart("", *)        = ""
1648         assertNull(StringUtils.removeStart(null, '\0'));
1649         assertNull(StringUtils.removeStart(null, 'a'));
1650 
1651         // StringUtils.removeStart(*, null)      = *
1652         assertEquals(StringUtils.removeStart("", '\0'), "");
1653         assertEquals(StringUtils.removeStart("", 'a'), "");
1654 
1655         // All others:
1656         assertEquals(StringUtils.removeStart("/path", '/'), "path");
1657         assertEquals(StringUtils.removeStart("path", '/'), "path");
1658         assertEquals(StringUtils.removeStart("path", '\0'), "path");
1659     }
1660 
1661     @Test
1662     void testRemoveStartIgnoreCase() {
1663         // StringUtils.removeStart("", *)        = ""
1664         assertNull(StringUtils.removeStartIgnoreCase(null, null), "removeStartIgnoreCase(null, null)");
1665         assertNull(StringUtils.removeStartIgnoreCase(null, ""), "removeStartIgnoreCase(null, \"\")");
1666         assertNull(StringUtils.removeStartIgnoreCase(null, "a"), "removeStartIgnoreCase(null, \"a\")");
1667 
1668         // StringUtils.removeStart(*, null)      = *
1669         assertEquals(StringUtils.removeStartIgnoreCase("", null), "", "removeStartIgnoreCase(\"\", null)");
1670         assertEquals(StringUtils.removeStartIgnoreCase("", ""), "", "removeStartIgnoreCase(\"\", \"\")");
1671         assertEquals(StringUtils.removeStartIgnoreCase("", "a"), "", "removeStartIgnoreCase(\"\", \"a\")");
1672 
1673         // All others:
1674         assertEquals(StringUtils.removeStartIgnoreCase("www.domain.com", "www."), "domain.com", "removeStartIgnoreCase(\"www.domain.com\", \"www.\")");
1675         assertEquals(StringUtils.removeStartIgnoreCase("domain.com", "www."), "domain.com", "removeStartIgnoreCase(\"domain.com\", \"www.\")");
1676         assertEquals(StringUtils.removeStartIgnoreCase("domain.com", ""), "domain.com", "removeStartIgnoreCase(\"domain.com\", \"\")");
1677         assertEquals(StringUtils.removeStartIgnoreCase("domain.com", null), "domain.com", "removeStartIgnoreCase(\"domain.com\", null)");
1678 
1679         // Case-insensitive:
1680         assertEquals(StringUtils.removeStartIgnoreCase("www.domain.com", "WWW."), "domain.com", "removeStartIgnoreCase(\"www.domain.com\", \"WWW.\")");
1681     }
1682 
1683     @Test
1684     void testRemoveStartString() {
1685         // StringUtils.removeStart("", *)        = ""
1686         assertNull(StringUtils.removeStart(null, null));
1687         assertNull(StringUtils.removeStart(null, ""));
1688         assertNull(StringUtils.removeStart(null, "a"));
1689 
1690         // StringUtils.removeStart(*, null)      = *
1691         assertEquals(StringUtils.removeStart("", null), "");
1692         assertEquals(StringUtils.removeStart("", ""), "");
1693         assertEquals(StringUtils.removeStart("", "a"), "");
1694 
1695         // All others:
1696         assertEquals(StringUtils.removeStart("www.domain.com", "www."), "domain.com");
1697         assertEquals(StringUtils.removeStart("domain.com", "www."), "domain.com");
1698         assertEquals(StringUtils.removeStart("domain.com", ""), "domain.com");
1699         assertEquals(StringUtils.removeStart("domain.com", null), "domain.com");
1700     }
1701 
1702     @Test
1703     void testRepeat_CharInt() {
1704         assertEquals("zzz", StringUtils.repeat('z', 3));
1705         assertEquals("", StringUtils.repeat('z', 0));
1706         assertEquals("", StringUtils.repeat('z', -2));
1707     }
1708 
1709     @Test
1710     void testRepeat_StringInt() {
1711         assertNull(StringUtils.repeat(null, 2));
1712         assertEquals("", StringUtils.repeat("ab", 0));
1713         assertEquals("", StringUtils.repeat("", 3));
1714         assertEquals("aaa", StringUtils.repeat("a", 3));
1715         assertEquals("", StringUtils.repeat("a", -2));
1716         assertEquals("ababab", StringUtils.repeat("ab", 3));
1717         assertEquals("abcabcabc", StringUtils.repeat("abc", 3));
1718         final String str = StringUtils.repeat("a", 10000);  // bigger than pad limit
1719         assertEquals(10000, str.length());
1720         assertTrue(StringUtils.containsOnly(str, 'a'));
1721     }
1722 
1723     @Test
1724     void testRepeat_StringStringInt() {
1725         assertNull(StringUtils.repeat(null, null, 2));
1726         assertNull(StringUtils.repeat(null, "x", 2));
1727         assertEquals("", StringUtils.repeat("", null, 2));
1728 
1729         assertEquals("", StringUtils.repeat("ab", "", 0));
1730         assertEquals("", StringUtils.repeat("", "", 2));
1731 
1732         assertEquals("xx", StringUtils.repeat("", "x", 3));
1733 
1734         assertEquals("?, ?, ?", StringUtils.repeat("?", ", ", 3));
1735     }
1736 
1737     /**
1738      * Test method for 'StringUtils.replaceEach(String, String[], String[])'
1739      */
1740     @Test
1741     void testReplace_StringStringArrayStringArray() {
1742         //JAVADOC TESTS START
1743         assertNull(StringUtils.replaceEach(null, new String[]{"a"}, new String[]{"b"}));
1744         assertEquals(StringUtils.replaceEach("", new String[]{"a"}, new String[]{"b"}), "");
1745         assertEquals(StringUtils.replaceEach("aba", null, null), "aba");
1746         assertEquals(StringUtils.replaceEach("aba", new String[0], null), "aba");
1747         assertEquals(StringUtils.replaceEach("aba", null, new String[0]), "aba");
1748         assertEquals(StringUtils.replaceEach("aba", new String[]{"a"}, null), "aba");
1749 
1750         assertEquals(StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}), "b");
1751         assertEquals(StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}), "aba");
1752         assertEquals(StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}), "wcte");
1753         assertEquals(StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}), "dcte");
1754         //JAVADOC TESTS END
1755 
1756         assertEquals("bcc", StringUtils.replaceEach("abc", new String[]{"a", "b"}, new String[]{"b", "c"}));
1757         assertEquals("q651.506bera", StringUtils.replaceEach("d216.102oren",
1758                 new String[]{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
1759                         "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D",
1760                         "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
1761                         "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9"},
1762                 new String[]{"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "a",
1763                         "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "N", "O", "P", "Q",
1764                         "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "A", "B", "C", "D", "E", "F", "G",
1765                         "H", "I", "J", "K", "L", "M", "5", "6", "7", "8", "9", "1", "2", "3", "4"}));
1766 
1767         // Test null safety inside arrays - LANG-552
1768         assertEquals(StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{null}), "aba");
1769         assertEquals(StringUtils.replaceEach("aba", new String[]{"a", "b"}, new String[]{"c", null}), "cbc");
1770 
1771         assertIllegalArgumentException(() -> StringUtils.replaceEach("abba", new String[] { "a" }, new String[] { "b", "a" }),
1772                 "StringUtils.replaceEach(String, String[], String[]) expecting IllegalArgumentException");
1773     }
1774 
1775     /**
1776      * Test method for 'StringUtils.replaceEachRepeatedly(String, String[], String[])'
1777      */
1778     @Test
1779     void testReplace_StringStringArrayStringArrayBoolean() {
1780         //JAVADOC TESTS START
1781         assertNull(StringUtils.replaceEachRepeatedly(null, new String[]{"a"}, new String[]{"b"}));
1782         assertEquals("", StringUtils.replaceEachRepeatedly("", new String[]{"a"}, new String[]{"b"}));
1783         assertEquals("aba", StringUtils.replaceEachRepeatedly("aba", null, null));
1784         assertEquals("aba", StringUtils.replaceEachRepeatedly("aba", new String[0], null));
1785         assertEquals("aba", StringUtils.replaceEachRepeatedly("aba", null, new String[0]));
1786         assertEquals("aba", StringUtils.replaceEachRepeatedly("aba", new String[0], null));
1787 
1788         assertEquals("b", StringUtils.replaceEachRepeatedly("aba", new String[]{"a"}, new String[]{""}));
1789         assertEquals("aba", StringUtils.replaceEachRepeatedly("aba", new String[]{null}, new String[]{"a"}));
1790         assertEquals("wcte", StringUtils.replaceEachRepeatedly("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}));
1791         assertEquals("tcte", StringUtils.replaceEachRepeatedly("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}));
1792 
1793         // Test recursive replacement - LANG-1528 & LANG-1753
1794         assertEquals("blaan", StringUtils.replaceEachRepeatedly("blllaan", new String[]{"llaan"}, new String[]{"laan"}));
1795         assertEquals("blaan", StringUtils.replaceEachRepeatedly("bllllaan", new String[]{"llaan"}, new String[]{"laan"}));
1796 
1797         // Test default TTL for smaller search lists. 32 characters reduced to 16, then 8, 4, 2, 1.
1798         assertEquals("a", StringUtils.replaceEachRepeatedly("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
1799                 new String[]{"aa"}, new String[]{"a"}));
1800 
1801         // Test default TTL exceeded. 33 characters reduced to 17, then 9, 5, 3, 2 (still found).
1802         assertThrows(IllegalStateException.class,
1803                 () -> StringUtils.replaceEachRepeatedly("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", new String[] { "aa" }, new String[] { "a" }),
1804                 "Cannot be resolved within the default time-to-live limit");
1805         // Test larger TTL for larger search lists. Replace repeatedly until there are no more possible replacements.
1806         assertEquals("000000000", StringUtils.replaceEachRepeatedly("aA0aA0aA0",
1807                 new String[]{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
1808                         "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D",
1809                         "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
1810                         "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9"},
1811                 new String[]{"b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
1812                         "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E",
1813                         "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
1814                         "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}));
1815 
1816         // Test long infinite cycle: a -> b -> ... -> 9 -> 0 -> a -> b -> ...
1817         assertThrows(IllegalStateException.class,
1818                 () -> StringUtils.replaceEachRepeatedly("a",
1819                     new String[]{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
1820                             "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D",
1821                             "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
1822                             "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"},
1823                     new String[]{"b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
1824                             "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E",
1825                             "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
1826                             "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "a"}),
1827                 "Should be a circular reference");
1828 
1829         assertThrows(IllegalStateException.class,
1830                 () -> StringUtils.replaceEachRepeatedly("%{key1}",
1831                     new String[] {"%{key1}", "%{key2}", "%{key3}"},
1832                     new String[] {"Key1 %{key2}", "Key2 %{key3}", "Key3 %{key1}"}),
1833                 "Should be a circular reference");
1834 
1835         assertThrows(IllegalStateException.class,
1836                 () -> StringUtils.replaceEachRepeatedly("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}),
1837                 "Should be a circular reference");
1838 
1839         //JAVADOC TESTS END
1840     }
1841 
1842     @Test
1843     void testReplace_StringStringString() {
1844         assertNull(StringUtils.replace(null, null, null));
1845         assertNull(StringUtils.replace(null, null, "any"));
1846         assertNull(StringUtils.replace(null, "any", null));
1847         assertNull(StringUtils.replace(null, "any", "any"));
1848 
1849         assertEquals("", StringUtils.replace("", null, null));
1850         assertEquals("", StringUtils.replace("", null, "any"));
1851         assertEquals("", StringUtils.replace("", "any", null));
1852         assertEquals("", StringUtils.replace("", "any", "any"));
1853 
1854         assertEquals("FOO", StringUtils.replace("FOO", "", "any"));
1855         assertEquals("FOO", StringUtils.replace("FOO", null, "any"));
1856         assertEquals("FOO", StringUtils.replace("FOO", "F", null));
1857         assertEquals("FOO", StringUtils.replace("FOO", null, null));
1858 
1859         assertEquals("", StringUtils.replace("foofoofoo", "foo", ""));
1860         assertEquals("barbarbar", StringUtils.replace("foofoofoo", "foo", "bar"));
1861         assertEquals("farfarfar", StringUtils.replace("foofoofoo", "oo", "ar"));
1862     }
1863 
1864     @Test
1865     void testReplace_StringStringStringInt() {
1866         assertNull(StringUtils.replace(null, null, null, 2));
1867         assertNull(StringUtils.replace(null, null, "any", 2));
1868         assertNull(StringUtils.replace(null, "any", null, 2));
1869         assertNull(StringUtils.replace(null, "any", "any", 2));
1870 
1871         assertEquals("", StringUtils.replace("", null, null, 2));
1872         assertEquals("", StringUtils.replace("", null, "any", 2));
1873         assertEquals("", StringUtils.replace("", "any", null, 2));
1874         assertEquals("", StringUtils.replace("", "any", "any", 2));
1875 
1876         final String str = new String(new char[]{'o', 'o', 'f', 'o', 'o'});
1877         assertSame(str, StringUtils.replace(str, "x", "", -1));
1878 
1879         assertEquals("f", StringUtils.replace("oofoo", "o", "", -1));
1880         assertEquals("oofoo", StringUtils.replace("oofoo", "o", "", 0));
1881         assertEquals("ofoo", StringUtils.replace("oofoo", "o", "", 1));
1882         assertEquals("foo", StringUtils.replace("oofoo", "o", "", 2));
1883         assertEquals("fo", StringUtils.replace("oofoo", "o", "", 3));
1884         assertEquals("f", StringUtils.replace("oofoo", "o", "", 4));
1885 
1886         assertEquals("f", StringUtils.replace("oofoo", "o", "", -5));
1887         assertEquals("f", StringUtils.replace("oofoo", "o", "", 1000));
1888     }
1889 
1890     @Test
1891     void testReplaceAll_StringStringString() {
1892         assertNull(StringUtils.replaceAll(null, "", ""));
1893 
1894         assertEquals("any", StringUtils.replaceAll("any", null, ""));
1895         assertEquals("any", StringUtils.replaceAll("any", "", null));
1896 
1897         assertEquals("zzz", StringUtils.replaceAll("", "", "zzz"));
1898         assertEquals("zzz", StringUtils.replaceAll("", ".*", "zzz"));
1899         assertEquals("", StringUtils.replaceAll("", ".+", "zzz"));
1900         assertEquals("ZZaZZbZZcZZ", StringUtils.replaceAll("abc", "", "ZZ"));
1901 
1902         assertEquals("z\nz", StringUtils.replaceAll("<__>\n<__>", "<.*>", "z"));
1903         assertEquals("z", StringUtils.replaceAll("<__>\n<__>", "(?s)<.*>", "z"));
1904 
1905         assertEquals("ABC___123", StringUtils.replaceAll("ABCabc123", "[a-z]", "_"));
1906         assertEquals("ABC_123", StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "_"));
1907         assertEquals("ABC123", StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", ""));
1908         assertEquals("Lorem_ipsum_dolor_sit",
1909                      StringUtils.replaceAll("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2"));
1910 
1911         assertThrows(PatternSyntaxException.class, () -> StringUtils.replaceAll("any", "{badRegexSyntax}", ""),
1912                 "StringUtils.replaceAll expecting PatternSyntaxException");
1913     }
1914 
1915     @Test
1916     void testReplaceChars_StringCharChar() {
1917         assertNull(StringUtils.replaceChars(null, 'b', 'z'));
1918         assertEquals("", StringUtils.replaceChars("", 'b', 'z'));
1919         assertEquals("azcza", StringUtils.replaceChars("abcba", 'b', 'z'));
1920         assertEquals("abcba", StringUtils.replaceChars("abcba", 'x', 'z'));
1921     }
1922 
1923     @Test
1924     void testReplaceChars_StringStringString() {
1925         assertNull(StringUtils.replaceChars(null, null, null));
1926         assertNull(StringUtils.replaceChars(null, "", null));
1927         assertNull(StringUtils.replaceChars(null, "a", null));
1928         assertNull(StringUtils.replaceChars(null, null, ""));
1929         assertNull(StringUtils.replaceChars(null, null, "x"));
1930 
1931         assertEquals("", StringUtils.replaceChars("", null, null));
1932         assertEquals("", StringUtils.replaceChars("", "", null));
1933         assertEquals("", StringUtils.replaceChars("", "a", null));
1934         assertEquals("", StringUtils.replaceChars("", null, ""));
1935         assertEquals("", StringUtils.replaceChars("", null, "x"));
1936 
1937         assertEquals("abc", StringUtils.replaceChars("abc", null, null));
1938         assertEquals("abc", StringUtils.replaceChars("abc", null, ""));
1939         assertEquals("abc", StringUtils.replaceChars("abc", null, "x"));
1940 
1941         assertEquals("abc", StringUtils.replaceChars("abc", "", null));
1942         assertEquals("abc", StringUtils.replaceChars("abc", "", ""));
1943         assertEquals("abc", StringUtils.replaceChars("abc", "", "x"));
1944 
1945         assertEquals("ac", StringUtils.replaceChars("abc", "b", null));
1946         assertEquals("ac", StringUtils.replaceChars("abc", "b", ""));
1947         assertEquals("axc", StringUtils.replaceChars("abc", "b", "x"));
1948 
1949         assertEquals("ayzya", StringUtils.replaceChars("abcba", "bc", "yz"));
1950         assertEquals("ayya", StringUtils.replaceChars("abcba", "bc", "y"));
1951         assertEquals("ayzya", StringUtils.replaceChars("abcba", "bc", "yzx"));
1952 
1953         assertEquals("abcba", StringUtils.replaceChars("abcba", "z", "w"));
1954         assertSame("abcba", StringUtils.replaceChars("abcba", "z", "w"));
1955 
1956         // Javadoc examples:
1957         assertEquals("jelly", StringUtils.replaceChars("hello", "ho", "jy"));
1958         assertEquals("ayzya", StringUtils.replaceChars("abcba", "bc", "yz"));
1959         assertEquals("ayya", StringUtils.replaceChars("abcba", "bc", "y"));
1960         assertEquals("ayzya", StringUtils.replaceChars("abcba", "bc", "yzx"));
1961 
1962         // From https://issues.apache.org/bugzilla/show_bug.cgi?id=25454
1963         assertEquals("bcc", StringUtils.replaceChars("abc", "ab", "bc"));
1964         assertEquals("q651.506bera", StringUtils.replaceChars("d216.102oren",
1965                 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789",
1966                 "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM567891234"));
1967     }
1968 
1969     @Test
1970     void testReplaceFirst_StringStringString() {
1971         assertNull(StringUtils.replaceFirst(null, "", ""));
1972 
1973         assertEquals("any", StringUtils.replaceFirst("any", null, ""));
1974         assertEquals("any", StringUtils.replaceFirst("any", "", null));
1975 
1976         assertEquals("zzz", StringUtils.replaceFirst("", "", "zzz"));
1977         assertEquals("zzz", StringUtils.replaceFirst("", ".*", "zzz"));
1978         assertEquals("", StringUtils.replaceFirst("", ".+", "zzz"));
1979         assertEquals("ZZabc", StringUtils.replaceFirst("abc", "", "ZZ"));
1980 
1981         assertEquals("z\n<__>", StringUtils.replaceFirst("<__>\n<__>", "<.*>", "z"));
1982         assertEquals("z", StringUtils.replaceFirst("<__>\n<__>", "(?s)<.*>", "z"));
1983 
1984         assertEquals("ABC_bc123", StringUtils.replaceFirst("ABCabc123", "[a-z]", "_"));
1985         assertEquals("ABC_123abc", StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "_"));
1986         assertEquals("ABC123abc", StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", ""));
1987         assertEquals("Lorem_ipsum  dolor   sit",
1988                      StringUtils.replaceFirst("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2"));
1989 
1990         assertThrows(PatternSyntaxException.class, () -> StringUtils.replaceFirst("any", "{badRegexSyntax}", ""),
1991                 "StringUtils.replaceFirst expecting PatternSyntaxException");
1992     }
1993 
1994     @Test
1995     void testReplaceIgnoreCase_StringStringString() {
1996         assertNull(StringUtils.replaceIgnoreCase(null, null, null));
1997         assertNull(StringUtils.replaceIgnoreCase(null, null, "any"));
1998         assertNull(StringUtils.replaceIgnoreCase(null, "any", null));
1999         assertNull(StringUtils.replaceIgnoreCase(null, "any", "any"));
2000 
2001         assertEquals("", StringUtils.replaceIgnoreCase("", null, null));
2002         assertEquals("", StringUtils.replaceIgnoreCase("", null, "any"));
2003         assertEquals("", StringUtils.replaceIgnoreCase("", "any", null));
2004         assertEquals("", StringUtils.replaceIgnoreCase("", "any", "any"));
2005 
2006         assertEquals("FOO", StringUtils.replaceIgnoreCase("FOO", "", "any"));
2007         assertEquals("FOO", StringUtils.replaceIgnoreCase("FOO", null, "any"));
2008         assertEquals("FOO", StringUtils.replaceIgnoreCase("FOO", "F", null));
2009         assertEquals("FOO", StringUtils.replaceIgnoreCase("FOO", null, null));
2010 
2011         assertEquals("", StringUtils.replaceIgnoreCase("foofoofoo", "foo", ""));
2012         assertEquals("barbarbar", StringUtils.replaceIgnoreCase("foofoofoo", "foo", "bar"));
2013         assertEquals("farfarfar", StringUtils.replaceIgnoreCase("foofoofoo", "oo", "ar"));
2014 
2015         // IgnoreCase
2016         assertEquals("", StringUtils.replaceIgnoreCase("foofoofoo", "FOO", ""));
2017         assertEquals("barbarbar", StringUtils.replaceIgnoreCase("fooFOOfoo", "foo", "bar"));
2018         assertEquals("farfarfar", StringUtils.replaceIgnoreCase("foofOOfoo", "OO", "ar"));
2019     }
2020 
2021     @Test
2022     void testReplaceIgnoreCase_StringStringStringInt() {
2023         assertNull(StringUtils.replaceIgnoreCase(null, null, null, 2));
2024         assertNull(StringUtils.replaceIgnoreCase(null, null, "any", 2));
2025         assertNull(StringUtils.replaceIgnoreCase(null, "any", null, 2));
2026         assertNull(StringUtils.replaceIgnoreCase(null, "any", "any", 2));
2027 
2028         assertEquals("", StringUtils.replaceIgnoreCase("", null, null, 2));
2029         assertEquals("", StringUtils.replaceIgnoreCase("", null, "any", 2));
2030         assertEquals("", StringUtils.replaceIgnoreCase("", "any", null, 2));
2031         assertEquals("", StringUtils.replaceIgnoreCase("", "any", "any", 2));
2032 
2033         final String str = new String(new char[] { 'o', 'o', 'f', 'o', 'o' });
2034         assertSame(str, StringUtils.replaceIgnoreCase(str, "x", "", -1));
2035 
2036         assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "o", "", -1));
2037         assertEquals("oofoo", StringUtils.replaceIgnoreCase("oofoo", "o", "", 0));
2038         assertEquals("ofoo", StringUtils.replaceIgnoreCase("oofoo", "o", "", 1));
2039         assertEquals("foo", StringUtils.replaceIgnoreCase("oofoo", "o", "", 2));
2040         assertEquals("fo", StringUtils.replaceIgnoreCase("oofoo", "o", "", 3));
2041         assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "o", "", 4));
2042 
2043         assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "o", "", -5));
2044         assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "o", "", 1000));
2045 
2046         // IgnoreCase
2047         assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "O", "", -1));
2048         assertEquals("oofoo", StringUtils.replaceIgnoreCase("oofoo", "O", "", 0));
2049         assertEquals("ofoo", StringUtils.replaceIgnoreCase("oofoo", "O", "", 1));
2050         assertEquals("foo", StringUtils.replaceIgnoreCase("oofoo", "O", "", 2));
2051         assertEquals("fo", StringUtils.replaceIgnoreCase("oofoo", "O", "", 3));
2052         assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "O", "", 4));
2053 
2054         assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "O", "", -5));
2055         assertEquals("f", StringUtils.replaceIgnoreCase("oofoo", "O", "", 1000));
2056     }
2057 
2058     @Test
2059     void testReplaceOnce_StringStringString() {
2060         assertNull(StringUtils.replaceOnce(null, null, null));
2061         assertNull(StringUtils.replaceOnce(null, null, "any"));
2062         assertNull(StringUtils.replaceOnce(null, "any", null));
2063         assertNull(StringUtils.replaceOnce(null, "any", "any"));
2064 
2065         assertEquals("", StringUtils.replaceOnce("", null, null));
2066         assertEquals("", StringUtils.replaceOnce("", null, "any"));
2067         assertEquals("", StringUtils.replaceOnce("", "any", null));
2068         assertEquals("", StringUtils.replaceOnce("", "any", "any"));
2069 
2070         assertEquals("FOO", StringUtils.replaceOnce("FOO", "", "any"));
2071         assertEquals("FOO", StringUtils.replaceOnce("FOO", null, "any"));
2072         assertEquals("FOO", StringUtils.replaceOnce("FOO", "F", null));
2073         assertEquals("FOO", StringUtils.replaceOnce("FOO", null, null));
2074 
2075         assertEquals("foofoo", StringUtils.replaceOnce("foofoofoo", "foo", ""));
2076     }
2077 
2078     @Test
2079     void testReplaceOnceIgnoreCase_StringStringString() {
2080         assertNull(StringUtils.replaceOnceIgnoreCase(null, null, null));
2081         assertNull(StringUtils.replaceOnceIgnoreCase(null, null, "any"));
2082         assertNull(StringUtils.replaceOnceIgnoreCase(null, "any", null));
2083         assertNull(StringUtils.replaceOnceIgnoreCase(null, "any", "any"));
2084 
2085         assertEquals("", StringUtils.replaceOnceIgnoreCase("", null, null));
2086         assertEquals("", StringUtils.replaceOnceIgnoreCase("", null, "any"));
2087         assertEquals("", StringUtils.replaceOnceIgnoreCase("", "any", null));
2088         assertEquals("", StringUtils.replaceOnceIgnoreCase("", "any", "any"));
2089 
2090         assertEquals("FOO", StringUtils.replaceOnceIgnoreCase("FOO", "", "any"));
2091         assertEquals("FOO", StringUtils.replaceOnceIgnoreCase("FOO", null, "any"));
2092         assertEquals("FOO", StringUtils.replaceOnceIgnoreCase("FOO", "F", null));
2093         assertEquals("FOO", StringUtils.replaceOnceIgnoreCase("FOO", null, null));
2094 
2095         assertEquals("foofoo", StringUtils.replaceOnceIgnoreCase("foofoofoo", "foo", ""));
2096 
2097         // Ignore Case
2098         assertEquals("Foofoo", StringUtils.replaceOnceIgnoreCase("FoOFoofoo", "foo", ""));
2099     }
2100 
2101     @Test
2102     void testReplacePattern_StringStringString() {
2103         assertNull(StringUtils.replacePattern(null, "", ""));
2104         assertEquals("any", StringUtils.replacePattern("any", null, ""));
2105         assertEquals("any", StringUtils.replacePattern("any", "", null));
2106 
2107         assertEquals("zzz", StringUtils.replacePattern("", "", "zzz"));
2108         assertEquals("zzz", StringUtils.replacePattern("", ".*", "zzz"));
2109         assertEquals("", StringUtils.replacePattern("", ".+", "zzz"));
2110 
2111         assertEquals("z", StringUtils.replacePattern("<__>\n<__>", "<.*>", "z"));
2112         assertEquals("z", StringUtils.replacePattern("<__>\\n<__>", "<.*>", "z"));
2113         assertEquals("X", StringUtils.replacePattern("<A>\nxy\n</A>", "<A>.*</A>", "X"));
2114 
2115         assertEquals("ABC___123", StringUtils.replacePattern("ABCabc123", "[a-z]", "_"));
2116         assertEquals("ABC_123", StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "_"));
2117         assertEquals("ABC123", StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", ""));
2118         assertEquals("Lorem_ipsum_dolor_sit",
2119                      StringUtils.replacePattern("Lorem ipsum  dolor   sit", "( +)([a-z]+)", "_$2"));
2120     }
2121 
2122     @Test
2123     void testReverse_String() {
2124         assertNull(StringUtils.reverse(null));
2125         assertEquals("", StringUtils.reverse(""));
2126         assertEquals("sdrawkcab", StringUtils.reverse("backwards"));
2127     }
2128 
2129     @Test
2130     void testReverseDelimited_StringChar() {
2131         assertNull(StringUtils.reverseDelimited(null, '.'));
2132         assertEquals("", StringUtils.reverseDelimited("", '.'));
2133         assertEquals("c.b.a", StringUtils.reverseDelimited("a.b.c", '.'));
2134         assertEquals("a b c", StringUtils.reverseDelimited("a b c", '.'));
2135         assertEquals("", StringUtils.reverseDelimited("", '.'));
2136     }
2137 
2138     @Test
2139     void testRightPad_StringInt() {
2140         assertNull(StringUtils.rightPad(null, 5));
2141         assertEquals("     ", StringUtils.rightPad("", 5));
2142         assertEquals("abc  ", StringUtils.rightPad("abc", 5));
2143         assertEquals("abc", StringUtils.rightPad("abc", 2));
2144         assertEquals("abc", StringUtils.rightPad("abc", -1));
2145     }
2146 
2147     @Test
2148     void testRightPad_StringIntChar() {
2149         assertNull(StringUtils.rightPad(null, 5, ' '));
2150         assertEquals("     ", StringUtils.rightPad("", 5, ' '));
2151         assertEquals("abc  ", StringUtils.rightPad("abc", 5, ' '));
2152         assertEquals("abc", StringUtils.rightPad("abc", 2, ' '));
2153         assertEquals("abc", StringUtils.rightPad("abc", -1, ' '));
2154         assertEquals("abcxx", StringUtils.rightPad("abc", 5, 'x'));
2155         final String str = StringUtils.rightPad("aaa", 10000, 'a');  // bigger than pad length
2156         assertEquals(10000, str.length());
2157         assertTrue(StringUtils.containsOnly(str, 'a'));
2158     }
2159 
2160     @Test
2161     void testRightPad_StringIntString() {
2162         assertNull(StringUtils.rightPad(null, 5, "-+"));
2163         assertEquals("     ", StringUtils.rightPad("", 5, " "));
2164         assertNull(StringUtils.rightPad(null, 8, null));
2165         assertEquals("abc-+-+", StringUtils.rightPad("abc", 7, "-+"));
2166         assertEquals("abc-+~", StringUtils.rightPad("abc", 6, "-+~"));
2167         assertEquals("abc-+", StringUtils.rightPad("abc", 5, "-+~"));
2168         assertEquals("abc", StringUtils.rightPad("abc", 2, " "));
2169         assertEquals("abc", StringUtils.rightPad("abc", -1, " "));
2170         assertEquals("abc  ", StringUtils.rightPad("abc", 5, null));
2171         assertEquals("abc  ", StringUtils.rightPad("abc", 5, ""));
2172     }
2173 
2174     @Test
2175     void testRotate_StringInt() {
2176         assertNull(StringUtils.rotate(null, 1));
2177         assertEquals("", StringUtils.rotate("", 1));
2178         assertEquals("abcdefg", StringUtils.rotate("abcdefg", 0));
2179         assertEquals("fgabcde", StringUtils.rotate("abcdefg", 2));
2180         assertEquals("cdefgab", StringUtils.rotate("abcdefg", -2));
2181         assertEquals("abcdefg", StringUtils.rotate("abcdefg", 7));
2182         assertEquals("abcdefg", StringUtils.rotate("abcdefg", -7));
2183         assertEquals("fgabcde", StringUtils.rotate("abcdefg", 9));
2184         assertEquals("cdefgab", StringUtils.rotate("abcdefg", -9));
2185         assertEquals("efgabcd", StringUtils.rotate("abcdefg", 17));
2186         assertEquals("defgabc", StringUtils.rotate("abcdefg", -17));
2187     }
2188 
2189     @Test
2190     void testSplit_String() {
2191         assertNull(StringUtils.split(null));
2192         assertEquals(0, StringUtils.split("").length);
2193 
2194         String str = "a b  .c";
2195         String[] res = StringUtils.split(str);
2196         assertEquals(3, res.length);
2197         assertEquals("a", res[0]);
2198         assertEquals("b", res[1]);
2199         assertEquals(".c", res[2]);
2200 
2201         str = " a ";
2202         res = StringUtils.split(str);
2203         assertEquals(1, res.length);
2204         assertEquals("a", res[0]);
2205 
2206         str = "a" + WHITESPACE + "b" + NON_WHITESPACE + "c";
2207         res = StringUtils.split(str);
2208         assertEquals(2, res.length);
2209         assertEquals("a", res[0]);
2210         assertEquals("b" + NON_WHITESPACE + "c", res[1]);
2211     }
2212 
2213     @Test
2214     void testSplit_StringChar() {
2215         assertNull(StringUtils.split(null, '.'));
2216         assertEquals(0, StringUtils.split("", '.').length);
2217 
2218         String str = "a.b.. c";
2219         String[] res = StringUtils.split(str, '.');
2220         assertEquals(3, res.length);
2221         assertEquals("a", res[0]);
2222         assertEquals("b", res[1]);
2223         assertEquals(" c", res[2]);
2224 
2225         str = ".a.";
2226         res = StringUtils.split(str, '.');
2227         assertEquals(1, res.length);
2228         assertEquals("a", res[0]);
2229 
2230         str = "a b c";
2231         res = StringUtils.split(str, ' ');
2232         assertEquals(3, res.length);
2233         assertEquals("a", res[0]);
2234         assertEquals("b", res[1]);
2235         assertEquals("c", res[2]);
2236     }
2237 
2238     @Test
2239     void testSplit_StringString_StringStringInt() {
2240         assertNull(StringUtils.split(null, "."));
2241         assertNull(StringUtils.split(null, ".", 3));
2242 
2243         assertEquals(0, StringUtils.split("", ".").length);
2244         assertEquals(0, StringUtils.split("", ".", 3).length);
2245 
2246         innerTestSplit('.', ".", ' ');
2247         innerTestSplit('.', ".", ',');
2248         innerTestSplit('.', ".,", 'x');
2249         for (int i = 0; i < WHITESPACE.length(); i++) {
2250             for (int j = 0; j < NON_WHITESPACE.length(); j++) {
2251                 innerTestSplit(WHITESPACE.charAt(i), null, NON_WHITESPACE.charAt(j));
2252                 innerTestSplit(WHITESPACE.charAt(i), String.valueOf(WHITESPACE.charAt(i)), NON_WHITESPACE.charAt(j));
2253             }
2254         }
2255 
2256         String[] results;
2257         final String[] expectedResults = {"ab", "de fg"};
2258         results = StringUtils.split("ab   de fg", null, 2);
2259         assertEquals(expectedResults.length, results.length);
2260         for (int i = 0; i < expectedResults.length; i++) {
2261             assertEquals(expectedResults[i], results[i]);
2262         }
2263 
2264         final String[] expectedResults2 = {"ab", "cd:ef"};
2265         results = StringUtils.split("ab:cd:ef", ":", 2);
2266         assertEquals(expectedResults2.length, results.length);
2267         for (int i = 0; i < expectedResults2.length; i++) {
2268             assertEquals(expectedResults2[i], results[i]);
2269         }
2270     }
2271 
2272     @Test
2273     void testSplitByCharacterType() {
2274         assertNull(StringUtils.splitByCharacterType(null));
2275         assertEquals(0, StringUtils.splitByCharacterType("").length);
2276 
2277         assertTrue(Objects.deepEquals(new String[]{"ab", " ", "de", " ",
2278                 "fg"}, StringUtils.splitByCharacterType("ab de fg")));
2279 
2280         assertTrue(Objects.deepEquals(new String[]{"ab", "   ", "de", " ",
2281                 "fg"}, StringUtils.splitByCharacterType("ab   de fg")));
2282 
2283         assertTrue(Objects.deepEquals(new String[]{"ab", ":", "cd", ":",
2284                 "ef"}, StringUtils.splitByCharacterType("ab:cd:ef")));
2285 
2286         assertTrue(Objects.deepEquals(new String[]{"number", "5"},
2287                 StringUtils.splitByCharacterType("number5")));
2288 
2289         assertTrue(Objects.deepEquals(new String[]{"foo", "B", "ar"},
2290                 StringUtils.splitByCharacterType("fooBar")));
2291 
2292         assertTrue(Objects.deepEquals(new String[]{"foo", "200", "B", "ar"},
2293                 StringUtils.splitByCharacterType("foo200Bar")));
2294 
2295         assertTrue(Objects.deepEquals(new String[]{"ASFR", "ules"},
2296                 StringUtils.splitByCharacterType("ASFRules")));
2297     }
2298 
2299     @Test
2300     void testSplitByCharacterTypeCamelCase() {
2301         assertNull(StringUtils.splitByCharacterTypeCamelCase(null));
2302         assertEquals(0, StringUtils.splitByCharacterTypeCamelCase("").length);
2303 
2304         assertTrue(Objects.deepEquals(new String[]{"ab", " ", "de", " ",
2305                 "fg"}, StringUtils.splitByCharacterTypeCamelCase("ab de fg")));
2306 
2307         assertTrue(Objects.deepEquals(new String[]{"ab", "   ", "de", " ",
2308                 "fg"}, StringUtils.splitByCharacterTypeCamelCase("ab   de fg")));
2309 
2310         assertTrue(Objects.deepEquals(new String[]{"ab", ":", "cd", ":",
2311                 "ef"}, StringUtils.splitByCharacterTypeCamelCase("ab:cd:ef")));
2312 
2313         assertTrue(Objects.deepEquals(new String[]{"number", "5"},
2314                 StringUtils.splitByCharacterTypeCamelCase("number5")));
2315 
2316         assertTrue(Objects.deepEquals(new String[]{"foo", "Bar"},
2317                 StringUtils.splitByCharacterTypeCamelCase("fooBar")));
2318 
2319         assertTrue(Objects.deepEquals(new String[]{"foo", "200", "Bar"},
2320                 StringUtils.splitByCharacterTypeCamelCase("foo200Bar")));
2321 
2322         assertTrue(Objects.deepEquals(new String[]{"ASF", "Rules"},
2323                 StringUtils.splitByCharacterTypeCamelCase("ASFRules")));
2324     }
2325 
2326     @Test
2327     void testSplitByWholeSeparatorPreserveAllTokens_StringString() {
2328         assertArrayEquals(null, StringUtils.splitByWholeSeparatorPreserveAllTokens(null, "."));
2329 
2330         assertEquals(0, StringUtils.splitByWholeSeparatorPreserveAllTokens("", ".").length);
2331 
2332         // test whitespace
2333         String input = "ab   de fg";
2334         String[] expected = {"ab", "", "", "de", "fg"};
2335 
2336         String[] actual = StringUtils.splitByWholeSeparatorPreserveAllTokens(input, null);
2337         assertEquals(expected.length, actual.length);
2338         for (int i = 0; i < actual.length; i += 1) {
2339             assertEquals(expected[i], actual[i]);
2340         }
2341 
2342         // test delimiter singlechar
2343         input = "1::2:::3::::4";
2344         expected = new String[]{"1", "", "2", "", "", "3", "", "", "", "4"};
2345 
2346         actual = StringUtils.splitByWholeSeparatorPreserveAllTokens(input, ":");
2347         assertEquals(expected.length, actual.length);
2348         for (int i = 0; i < actual.length; i += 1) {
2349             assertEquals(expected[i], actual[i]);
2350         }
2351 
2352         // test delimiter multichar
2353         input = "1::2:::3::::4";
2354         expected = new String[]{"1", "2", ":3", "", "4"};
2355 
2356         actual = StringUtils.splitByWholeSeparatorPreserveAllTokens(input, "::");
2357         assertEquals(expected.length, actual.length);
2358         for (int i = 0; i < actual.length; i += 1) {
2359             assertEquals(expected[i], actual[i]);
2360         }
2361     }
2362 
2363     @Test
2364     void testSplitByWholeSeparatorPreserveAllTokens_StringStringInt() {
2365         assertArrayEquals(null, StringUtils.splitByWholeSeparatorPreserveAllTokens(null, ".", -1));
2366 
2367         assertEquals(0, StringUtils.splitByWholeSeparatorPreserveAllTokens("", ".", -1).length);
2368 
2369         // test whitespace
2370         String input = "ab   de fg";
2371         String[] expected = {"ab", "", "", "de", "fg"};
2372 
2373         String[] actual = StringUtils.splitByWholeSeparatorPreserveAllTokens(input, null, -1);
2374         assertEquals(expected.length, actual.length);
2375         for (int i = 0; i < actual.length; i += 1) {
2376             assertEquals(expected[i], actual[i]);
2377         }
2378 
2379         // test delimiter singlechar
2380         input = "1::2:::3::::4";
2381         expected = new String[]{"1", "", "2", "", "", "3", "", "", "", "4"};
2382 
2383         actual = StringUtils.splitByWholeSeparatorPreserveAllTokens(input, ":", -1);
2384         assertEquals(expected.length, actual.length);
2385         for (int i = 0; i < actual.length; i += 1) {
2386             assertEquals(expected[i], actual[i]);
2387         }
2388 
2389         // test delimiter multichar
2390         input = "1::2:::3::::4";
2391         expected = new String[]{"1", "2", ":3", "", "4"};
2392 
2393         actual = StringUtils.splitByWholeSeparatorPreserveAllTokens(input, "::", -1);
2394         assertEquals(expected.length, actual.length);
2395         for (int i = 0; i < actual.length; i += 1) {
2396             assertEquals(expected[i], actual[i]);
2397         }
2398 
2399         // test delimiter char with max
2400         input = "1::2::3:4";
2401         expected = new String[]{"1", "", "2", ":3:4"};
2402 
2403         actual = StringUtils.splitByWholeSeparatorPreserveAllTokens(input, ":", 4);
2404         assertEquals(expected.length, actual.length);
2405         for (int i = 0; i < actual.length; i += 1) {
2406             assertEquals(expected[i], actual[i]);
2407         }
2408     }
2409 
2410     @Test
2411     void testSplitByWholeString_StringStringBoolean() {
2412         assertArrayEquals(null, StringUtils.splitByWholeSeparator(null, "."));
2413 
2414         assertEquals(0, StringUtils.splitByWholeSeparator("", ".").length);
2415 
2416         final String stringToSplitOnNulls = "ab   de fg";
2417         final String[] splitOnNullExpectedResults = {"ab", "de", "fg"};
2418 
2419         final String[] splitOnNullResults = StringUtils.splitByWholeSeparator(stringToSplitOnNulls, null);
2420         assertEquals(splitOnNullExpectedResults.length, splitOnNullResults.length);
2421         for (int i = 0; i < splitOnNullExpectedResults.length; i += 1) {
2422             assertEquals(splitOnNullExpectedResults[i], splitOnNullResults[i]);
2423         }
2424 
2425         final String stringToSplitOnCharactersAndString = "abstemiouslyaeiouyabstemiously";
2426 
2427         final String[] splitOnStringExpectedResults = {"abstemiously", "abstemiously"};
2428         final String[] splitOnStringResults = StringUtils.splitByWholeSeparator(stringToSplitOnCharactersAndString, "aeiouy");
2429         assertEquals(splitOnStringExpectedResults.length, splitOnStringResults.length);
2430         for (int i = 0; i < splitOnStringExpectedResults.length; i += 1) {
2431             assertEquals(splitOnStringExpectedResults[i], splitOnStringResults[i]);
2432         }
2433 
2434         final String[] splitWithMultipleSeparatorExpectedResults = {"ab", "cd", "ef"};
2435         final String[] splitWithMultipleSeparator = StringUtils.splitByWholeSeparator("ab:cd::ef", ":");
2436         assertEquals(splitWithMultipleSeparatorExpectedResults.length, splitWithMultipleSeparator.length);
2437         for (int i = 0; i < splitWithMultipleSeparatorExpectedResults.length; i++) {
2438             assertEquals(splitWithMultipleSeparatorExpectedResults[i], splitWithMultipleSeparator[i]);
2439         }
2440     }
2441 
2442     @Test
2443     void testSplitByWholeString_StringStringBooleanInt() {
2444         assertArrayEquals(null, StringUtils.splitByWholeSeparator(null, ".", 3));
2445 
2446         assertEquals(0, StringUtils.splitByWholeSeparator("", ".", 3).length);
2447 
2448         final String stringToSplitOnNulls = "ab   de fg";
2449         final String[] splitOnNullExpectedResults = {"ab", "de fg"};
2450         //String[] splitOnNullExpectedResults = { "ab", "de" } ;
2451 
2452         final String[] splitOnNullResults = StringUtils.splitByWholeSeparator(stringToSplitOnNulls, null, 2);
2453         assertEquals(splitOnNullExpectedResults.length, splitOnNullResults.length);
2454         for (int i = 0; i < splitOnNullExpectedResults.length; i += 1) {
2455             assertEquals(splitOnNullExpectedResults[i], splitOnNullResults[i]);
2456         }
2457 
2458         final String stringToSplitOnCharactersAndString = "abstemiouslyaeiouyabstemiouslyaeiouyabstemiously";
2459 
2460         final String[] splitOnStringExpectedResults = {"abstemiously", "abstemiouslyaeiouyabstemiously"};
2461         //String[] splitOnStringExpectedResults = { "abstemiously", "abstemiously" } ;
2462         final String[] splitOnStringResults = StringUtils.splitByWholeSeparator(stringToSplitOnCharactersAndString, "aeiouy", 2);
2463         assertEquals(splitOnStringExpectedResults.length, splitOnStringResults.length);
2464         for (int i = 0; i < splitOnStringExpectedResults.length; i++) {
2465             assertEquals(splitOnStringExpectedResults[i], splitOnStringResults[i]);
2466         }
2467     }
2468 
2469     @Test
2470     void testSplitPreserveAllTokens_String() {
2471         assertNull(StringUtils.splitPreserveAllTokens(null));
2472         assertEquals(0, StringUtils.splitPreserveAllTokens("").length);
2473 
2474         String str = "abc def";
2475         String[] res = StringUtils.splitPreserveAllTokens(str);
2476         assertEquals(2, res.length);
2477         assertEquals("abc", res[0]);
2478         assertEquals("def", res[1]);
2479 
2480         str = "abc  def";
2481         res = StringUtils.splitPreserveAllTokens(str);
2482         assertEquals(3, res.length);
2483         assertEquals("abc", res[0]);
2484         assertEquals("", res[1]);
2485         assertEquals("def", res[2]);
2486 
2487         str = " abc ";
2488         res = StringUtils.splitPreserveAllTokens(str);
2489         assertEquals(3, res.length);
2490         assertEquals("", res[0]);
2491         assertEquals("abc", res[1]);
2492         assertEquals("", res[2]);
2493 
2494         str = "a b .c";
2495         res = StringUtils.splitPreserveAllTokens(str);
2496         assertEquals(3, res.length);
2497         assertEquals("a", res[0]);
2498         assertEquals("b", res[1]);
2499         assertEquals(".c", res[2]);
2500 
2501         str = " a b .c";
2502         res = StringUtils.splitPreserveAllTokens(str);
2503         assertEquals(4, res.length);
2504         assertEquals("", res[0]);
2505         assertEquals("a", res[1]);
2506         assertEquals("b", res[2]);
2507         assertEquals(".c", res[3]);
2508 
2509         str = "a  b  .c";
2510         res = StringUtils.splitPreserveAllTokens(str);
2511         assertEquals(5, res.length);
2512         assertEquals("a", res[0]);
2513         assertEquals("", res[1]);
2514         assertEquals("b", res[2]);
2515         assertEquals("", res[3]);
2516         assertEquals(".c", res[4]);
2517 
2518         str = " a  ";
2519         res = StringUtils.splitPreserveAllTokens(str);
2520         assertEquals(4, res.length);
2521         assertEquals("", res[0]);
2522         assertEquals("a", res[1]);
2523         assertEquals("", res[2]);
2524         assertEquals("", res[3]);
2525 
2526         str = " a  b";
2527         res = StringUtils.splitPreserveAllTokens(str);
2528         assertEquals(4, res.length);
2529         assertEquals("", res[0]);
2530         assertEquals("a", res[1]);
2531         assertEquals("", res[2]);
2532         assertEquals("b", res[3]);
2533 
2534         str = "a" + WHITESPACE + "b" + NON_WHITESPACE + "c";
2535         res = StringUtils.splitPreserveAllTokens(str);
2536         assertEquals(WHITESPACE.length() + 1, res.length);
2537         assertEquals("a", res[0]);
2538         for (int i = 1; i < WHITESPACE.length() - 1; i++) {
2539             assertEquals("", res[i]);
2540         }
2541         assertEquals("b" + NON_WHITESPACE + "c", res[WHITESPACE.length()]);
2542     }
2543 
2544     @Test
2545     void testSplitPreserveAllTokens_StringChar() {
2546         assertNull(StringUtils.splitPreserveAllTokens(null, '.'));
2547         assertEquals(0, StringUtils.splitPreserveAllTokens("", '.').length);
2548 
2549         String str = "a.b. c";
2550         String[] res = StringUtils.splitPreserveAllTokens(str, '.');
2551         assertEquals(3, res.length);
2552         assertEquals("a", res[0]);
2553         assertEquals("b", res[1]);
2554         assertEquals(" c", res[2]);
2555 
2556         str = "a.b.. c";
2557         res = StringUtils.splitPreserveAllTokens(str, '.');
2558         assertEquals(4, res.length);
2559         assertEquals("a", res[0]);
2560         assertEquals("b", res[1]);
2561         assertEquals("", res[2]);
2562         assertEquals(" c", res[3]);
2563 
2564         str = ".a.";
2565         res = StringUtils.splitPreserveAllTokens(str, '.');
2566         assertEquals(3, res.length);
2567         assertEquals("", res[0]);
2568         assertEquals("a", res[1]);
2569         assertEquals("", res[2]);
2570 
2571         str = ".a..";
2572         res = StringUtils.splitPreserveAllTokens(str, '.');
2573         assertEquals(4, res.length);
2574         assertEquals("", res[0]);
2575         assertEquals("a", res[1]);
2576         assertEquals("", res[2]);
2577         assertEquals("", res[3]);
2578 
2579         str = "..a.";
2580         res = StringUtils.splitPreserveAllTokens(str, '.');
2581         assertEquals(4, res.length);
2582         assertEquals("", res[0]);
2583         assertEquals("", res[1]);
2584         assertEquals("a", res[2]);
2585         assertEquals("", res[3]);
2586 
2587         str = "..a";
2588         res = StringUtils.splitPreserveAllTokens(str, '.');
2589         assertEquals(3, res.length);
2590         assertEquals("", res[0]);
2591         assertEquals("", res[1]);
2592         assertEquals("a", res[2]);
2593 
2594         str = "a b c";
2595         res = StringUtils.splitPreserveAllTokens(str, ' ');
2596         assertEquals(3, res.length);
2597         assertEquals("a", res[0]);
2598         assertEquals("b", res[1]);
2599         assertEquals("c", res[2]);
2600 
2601         str = "a  b  c";
2602         res = StringUtils.splitPreserveAllTokens(str, ' ');
2603         assertEquals(5, res.length);
2604         assertEquals("a", res[0]);
2605         assertEquals("", res[1]);
2606         assertEquals("b", res[2]);
2607         assertEquals("", res[3]);
2608         assertEquals("c", res[4]);
2609 
2610         str = " a b c";
2611         res = StringUtils.splitPreserveAllTokens(str, ' ');
2612         assertEquals(4, res.length);
2613         assertEquals("", res[0]);
2614         assertEquals("a", res[1]);
2615         assertEquals("b", res[2]);
2616         assertEquals("c", res[3]);
2617 
2618         str = "  a b c";
2619         res = StringUtils.splitPreserveAllTokens(str, ' ');
2620         assertEquals(5, res.length);
2621         assertEquals("", res[0]);
2622         assertEquals("", res[1]);
2623         assertEquals("a", res[2]);
2624         assertEquals("b", res[3]);
2625         assertEquals("c", res[4]);
2626 
2627         str = "a b c ";
2628         res = StringUtils.splitPreserveAllTokens(str, ' ');
2629         assertEquals(4, res.length);
2630         assertEquals("a", res[0]);
2631         assertEquals("b", res[1]);
2632         assertEquals("c", res[2]);
2633         assertEquals("", res[3]);
2634 
2635         str = "a b c  ";
2636         res = StringUtils.splitPreserveAllTokens(str, ' ');
2637         assertEquals(5, res.length);
2638         assertEquals("a", res[0]);
2639         assertEquals("b", res[1]);
2640         assertEquals("c", res[2]);
2641         assertEquals("", res[3]);
2642         assertEquals("", res[4]);
2643 
2644         // Match example in javadoc
2645         {
2646             final String[] results;
2647             final String[] expectedResults = {"a", "", "b", "c"};
2648             results = StringUtils.splitPreserveAllTokens("a..b.c", '.');
2649             assertEquals(expectedResults.length, results.length);
2650             for (int i = 0; i < expectedResults.length; i++) {
2651                 assertEquals(expectedResults[i], results[i]);
2652             }
2653         }
2654     }
2655 
2656     @Test
2657     void testSplitPreserveAllTokens_StringString_StringStringInt() {
2658         assertNull(StringUtils.splitPreserveAllTokens(null, "."));
2659         assertNull(StringUtils.splitPreserveAllTokens(null, ".", 3));
2660 
2661         assertEquals(0, StringUtils.splitPreserveAllTokens("", ".").length);
2662         assertEquals(0, StringUtils.splitPreserveAllTokens("", ".", 3).length);
2663 
2664         innerTestSplitPreserveAllTokens('.', ".", ' ');
2665         innerTestSplitPreserveAllTokens('.', ".", ',');
2666         innerTestSplitPreserveAllTokens('.', ".,", 'x');
2667         for (int i = 0; i < WHITESPACE.length(); i++) {
2668             for (int j = 0; j < NON_WHITESPACE.length(); j++) {
2669                 innerTestSplitPreserveAllTokens(WHITESPACE.charAt(i), null, NON_WHITESPACE.charAt(j));
2670                 innerTestSplitPreserveAllTokens(WHITESPACE.charAt(i), String.valueOf(WHITESPACE.charAt(i)), NON_WHITESPACE.charAt(j));
2671             }
2672         }
2673 
2674         {
2675             final String[] results;
2676             final String[] expectedResults = {"ab", "de fg"};
2677             results = StringUtils.splitPreserveAllTokens("ab de fg", null, 2);
2678             assertEquals(expectedResults.length, results.length);
2679             for (int i = 0; i < expectedResults.length; i++) {
2680                 assertEquals(expectedResults[i], results[i]);
2681             }
2682         }
2683 
2684         {
2685             final String[] results;
2686             final String[] expectedResults = {"ab", "  de fg"};
2687             results = StringUtils.splitPreserveAllTokens("ab   de fg", null, 2);
2688             assertEquals(expectedResults.length, results.length);
2689             for (int i = 0; i < expectedResults.length; i++) {
2690                 assertEquals(expectedResults[i], results[i]);
2691             }
2692         }
2693 
2694         {
2695             final String[] results;
2696             final String[] expectedResults = {"ab", "::de:fg"};
2697             results = StringUtils.splitPreserveAllTokens("ab:::de:fg", ":", 2);
2698             assertEquals(expectedResults.length, results.length);
2699             for (int i = 0; i < expectedResults.length; i++) {
2700                 assertEquals(expectedResults[i], results[i]);
2701             }
2702         }
2703 
2704         {
2705             final String[] results;
2706             final String[] expectedResults = {"ab", "", " de fg"};
2707             results = StringUtils.splitPreserveAllTokens("ab   de fg", null, 3);
2708             assertEquals(expectedResults.length, results.length);
2709             for (int i = 0; i < expectedResults.length; i++) {
2710                 assertEquals(expectedResults[i], results[i]);
2711             }
2712         }
2713 
2714         {
2715             final String[] results;
2716             final String[] expectedResults = {"ab", "", "", "de fg"};
2717             results = StringUtils.splitPreserveAllTokens("ab   de fg", null, 4);
2718             assertEquals(expectedResults.length, results.length);
2719             for (int i = 0; i < expectedResults.length; i++) {
2720                 assertEquals(expectedResults[i], results[i]);
2721             }
2722         }
2723 
2724         {
2725             final String[] expectedResults = {"ab", "cd:ef"};
2726             final String[] results;
2727             results = StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 2);
2728             assertEquals(expectedResults.length, results.length);
2729             for (int i = 0; i < expectedResults.length; i++) {
2730                 assertEquals(expectedResults[i], results[i]);
2731             }
2732         }
2733 
2734         {
2735             final String[] results;
2736             final String[] expectedResults = {"ab", ":cd:ef"};
2737             results = StringUtils.splitPreserveAllTokens("ab::cd:ef", ":", 2);
2738             assertEquals(expectedResults.length, results.length);
2739             for (int i = 0; i < expectedResults.length; i++) {
2740                 assertEquals(expectedResults[i], results[i]);
2741             }
2742         }
2743 
2744         {
2745             final String[] results;
2746             final String[] expectedResults = {"ab", "", ":cd:ef"};
2747             results = StringUtils.splitPreserveAllTokens("ab:::cd:ef", ":", 3);
2748             assertEquals(expectedResults.length, results.length);
2749             for (int i = 0; i < expectedResults.length; i++) {
2750                 assertEquals(expectedResults[i], results[i]);
2751             }
2752         }
2753 
2754         {
2755             final String[] results;
2756             final String[] expectedResults = {"ab", "", "", "cd:ef"};
2757             results = StringUtils.splitPreserveAllTokens("ab:::cd:ef", ":", 4);
2758             assertEquals(expectedResults.length, results.length);
2759             for (int i = 0; i < expectedResults.length; i++) {
2760                 assertEquals(expectedResults[i], results[i]);
2761             }
2762         }
2763 
2764         {
2765             final String[] results;
2766             final String[] expectedResults = {"", "ab", "", "", "cd:ef"};
2767             results = StringUtils.splitPreserveAllTokens(":ab:::cd:ef", ":", 5);
2768             assertEquals(expectedResults.length, results.length);
2769             for (int i = 0; i < expectedResults.length; i++) {
2770                 assertEquals(expectedResults[i], results[i]);
2771             }
2772         }
2773 
2774         {
2775             final String[] results;
2776             final String[] expectedResults = {"", "", "ab", "", "", "cd:ef"};
2777             results = StringUtils.splitPreserveAllTokens("::ab:::cd:ef", ":", 6);
2778             assertEquals(expectedResults.length, results.length);
2779             for (int i = 0; i < expectedResults.length; i++) {
2780                 assertEquals(expectedResults[i], results[i]);
2781             }
2782         }
2783 
2784     }
2785 
2786     // Methods on StringUtils that are immutable in spirit (i.e. calculate the length)
2787     // should take a CharSequence parameter. Methods that are mutable in spirit (i.e. capitalize)
2788     // should take a String or String[] parameter and return String or String[].
2789     // This test enforces that this is done.
2790     @Test
2791     void testStringUtilsCharSequenceContract() {
2792         final Class<StringUtils> c = StringUtils.class;
2793         // Methods that are expressly excluded from testStringUtilsCharSequenceContract()
2794         final String[] excludeMethods = {
2795             "public static int org.apache.commons.lang3.StringUtils.compare(java.lang.String,java.lang.String)",
2796             "public static int org.apache.commons.lang3.StringUtils.compare(java.lang.String,java.lang.String,boolean)",
2797             "public static int org.apache.commons.lang3.StringUtils.compareIgnoreCase(java.lang.String,java.lang.String)",
2798             "public static int org.apache.commons.lang3.StringUtils.compareIgnoreCase(java.lang.String,java.lang.String,boolean)",
2799             "public static byte[] org.apache.commons.lang3.StringUtils.getBytes(java.lang.String,java.nio.charset.Charset)",
2800             "public static byte[] org.apache.commons.lang3.StringUtils.getBytes(java.lang.String,java.lang.String) throws java.io.UnsupportedEncodingException"
2801         };
2802         final Method[] methods = c.getMethods();
2803 
2804         for (final Method m : methods) {
2805             final String methodStr = m.toString();
2806             if (m.getReturnType() == String.class || m.getReturnType() == String[].class) {
2807                 // Assume this is mutable and ensure the first parameter is not CharSequence.
2808                 // It may be String or it may be something else (String[], Object, Object[]) so
2809                 // don't actively test for that.
2810                 final Class<?>[] params = m.getParameterTypes();
2811                 if (params.length > 0 && (params[0] == CharSequence.class || params[0] == CharSequence[].class)) {
2812                     assertFalse(ArrayUtils.contains(excludeMethods, methodStr), "The method \"" + methodStr + "\" appears to be mutable in spirit and therefore must not accept a CharSequence");
2813                 }
2814             } else {
2815                 // Assume this is immutable in spirit and ensure the first parameter is not String.
2816                 // As above, it may be something other than CharSequence.
2817                 final Class<?>[] params = m.getParameterTypes();
2818                 if (params.length > 0 && (params[0] == String.class || params[0] == String[].class)) {
2819                     assertTrue(ArrayUtils.contains(excludeMethods, methodStr),
2820                             "The method \"" + methodStr + "\" appears to be immutable in spirit and therefore must not accept a String");
2821                 }
2822             }
2823         }
2824     }
2825 
2826     @Test
2827     void testSwapCase_String() {
2828         assertNull(StringUtils.swapCase(null));
2829         assertEquals("", StringUtils.swapCase(""));
2830         assertEquals("  ", StringUtils.swapCase("  "));
2831 
2832         assertEquals("i", WordUtils.swapCase("I"));
2833         assertEquals("I", WordUtils.swapCase("i"));
2834         assertEquals("I AM HERE 123", StringUtils.swapCase("i am here 123"));
2835         assertEquals("i aM hERE 123", StringUtils.swapCase("I Am Here 123"));
2836         assertEquals("I AM here 123", StringUtils.swapCase("i am HERE 123"));
2837         assertEquals("i am here 123", StringUtils.swapCase("I AM HERE 123"));
2838 
2839         final String test = "This String contains a TitleCase character: \u01C8";
2840         final String expect = "tHIS sTRING CONTAINS A tITLEcASE CHARACTER: \u01C9";
2841         assertEquals(expect, WordUtils.swapCase(test));
2842         assertEquals(expect, StringUtils.swapCase(test));
2843     }
2844 
2845     @Test
2846     void testToCodePoints() {
2847         final int orphanedHighSurrogate = 0xD801;
2848         final int orphanedLowSurrogate = 0xDC00;
2849         final int supplementary = 0x2070E;
2850         final int[] codePoints = { 'a', orphanedHighSurrogate, 'b', 'c', supplementary, 'd', orphanedLowSurrogate, 'e' };
2851         final String s = new String(codePoints, 0, codePoints.length);
2852         assertArrayEquals(codePoints, StringUtils.toCodePoints(s));
2853         assertNull(StringUtils.toCodePoints(null));
2854         assertArrayEquals(ArrayUtils.EMPTY_INT_ARRAY, StringUtils.toCodePoints(""));
2855         assertArrayEquals(new int[] { 'a' }, StringUtils.toCodePoints("a"));
2856         assertArrayEquals(new int[] { 'a', 'b' }, StringUtils.toCodePoints("ab"));
2857         assertArrayEquals(new int[] { 'a', 'b', 'c' }, StringUtils.toCodePoints("abc"));
2858     }
2859 
2860     @Test
2861     void testToCodePointsEmoji() {
2862         assertArrayEquals(ArrayFill.fill(new int[14], 129418), StringUtils.toCodePoints("🦊🦊🦊🦊🦊🦊🦊🦊🦊🦊🦊🦊🦊🦊"));
2863         assertArrayEquals(new int[] { 128105, 127995, 8205, 128104, 127995, 8205, 128102, 127995, 8205, 128102, 127995, 128105, 127996, 8205, 128104, 127996,
2864                 8205, 128102, 127996, 8205, 128102, 127996, 128105, 127997, 8205, 128104, 127997, 8205, 128102, 127997, 8205, 128102, 127997, 128105, 127998,
2865                 8205, 128104, 127998, 8205, 128102, 127998, 8205, 128102, 127998, 128105, 127999, 8205, 128104, 127999, 8205, 128102, 127999, 8205, 128102,
2866                 127999, 128105, 127995, 8205, 128104, 127995, 8205, 128102, 127995, 8205, 128102, 127995, 128105, 127996, 8205, 128104, 127996, 8205, 128102,
2867                 127996, 8205, 128102, 127996, 128105, 127997, 8205, 128104, 127997, 8205, 128102, 127997, 8205, 128102, 127997, 128105, 127998, 8205, 128104,
2868                 127998, 8205, 128102, 127998, 8205, 128102, 127998, 128105, 127999, 8205, 128104, 127999, 8205, 128102, 127999, 8205, 128102, 127999 },
2869                 StringUtils.toCodePoints(
2870                         "👩🏻‍👨🏻‍👦🏻‍👦🏻👩🏼‍👨🏼‍👦🏼‍👦🏼👩🏽‍👨🏽‍👦🏽‍👦🏽👩🏾‍👨🏾‍👦🏾‍👦🏾👩🏿‍👨🏿‍👦🏿‍👦🏿👩🏻‍👨🏻‍👦🏻‍👦🏻👩🏼‍👨🏼‍👦🏼‍👦🏼👩🏽‍👨🏽‍👦🏽‍👦🏽👩🏾‍👨🏾‍👦🏾‍👦🏾👩🏿‍👨🏿‍👦🏿‍👦🏿"));
2871     }
2872 
2873     /**
2874      * Tests {@link StringUtils#toEncodedString(byte[], Charset)}
2875      *
2876      * @see StringUtils#toEncodedString(byte[], Charset)
2877      */
2878     @Test
2879     void testToEncodedString() {
2880         final String expectedString = "The quick brown fox jumps over the lazy dog.";
2881         String encoding = SystemUtils.FILE_ENCODING;
2882         byte[] expectedBytes = expectedString.getBytes(Charset.defaultCharset());
2883         // sanity check start
2884         assertArrayEquals(expectedBytes, expectedString.getBytes());
2885         // sanity check end
2886         assertEquals(expectedString, StringUtils.toEncodedString(expectedBytes, Charset.defaultCharset()));
2887         assertEquals(expectedString, StringUtils.toEncodedString(expectedBytes, Charset.forName(encoding)));
2888         encoding = StandardCharsets.UTF_16.name();
2889         expectedBytes = expectedString.getBytes(Charset.forName(encoding));
2890         assertEquals(expectedString, StringUtils.toEncodedString(expectedBytes, Charset.forName(encoding)));
2891     }
2892 
2893     @Test
2894     @ReadsDefaultLocale
2895     @WritesDefaultLocale
2896     void testToRootLowerCase() {
2897         assertNull(StringUtils.toRootLowerCase(null));
2898         assertEquals("a", StringUtils.toRootLowerCase("A"));
2899         assertEquals("a", StringUtils.toRootLowerCase("a"));
2900         final Locale TURKISH = Locale.forLanguageTag("tr");
2901         // Sanity checks:
2902         assertNotEquals("title", "TITLE".toLowerCase(TURKISH));
2903         assertEquals("title", "TITLE".toLowerCase(Locale.ROOT));
2904         assertEquals("title", StringUtils.toRootLowerCase("TITLE"));
2905     }
2906 
2907     @Test
2908     @DefaultLocale("tr")
2909     @ReadsDefaultLocale
2910     void testToRootLowerCaseTurkish() {
2911         assertEquals("title", StringUtils.toRootLowerCase("TITLE"));
2912     }
2913 
2914     @Test
2915     @ReadsDefaultLocale
2916     @WritesDefaultLocale
2917     void testToRootUpperCase() {
2918         assertNull(StringUtils.toRootUpperCase(null));
2919         assertEquals("A", StringUtils.toRootUpperCase("a"));
2920         assertEquals("A", StringUtils.toRootUpperCase("A"));
2921         final Locale TURKISH = Locale.forLanguageTag("tr");
2922         // Sanity checks:
2923         assertNotEquals("TITLE", "title".toUpperCase(TURKISH));
2924         assertEquals("TITLE", "title".toUpperCase(Locale.ROOT));
2925         assertEquals("TITLE", StringUtils.toRootUpperCase("title"));
2926         // Make sure we are not using the default Locale:
2927         final Locale defaultLocale = Locale.getDefault();
2928         try {
2929             Locale.setDefault(TURKISH);
2930             assertEquals("TITLE", StringUtils.toRootUpperCase("title"));
2931         } finally {
2932             Locale.setDefault(defaultLocale);
2933         }
2934     }
2935 
2936     /**
2937      * Tests {@link StringUtils#toString(byte[], String)}
2938      *
2939      * @throws UnsupportedEncodingException because the method under test max throw it
2940      * @see StringUtils#toString(byte[], String)
2941      */
2942     @Test
2943     void testToString() throws UnsupportedEncodingException {
2944         final String expectedString = "The quick brown fox jumps over the lazy dog.";
2945         byte[] expectedBytes = expectedString.getBytes(Charset.defaultCharset());
2946         // sanity check start
2947         assertArrayEquals(expectedBytes, expectedString.getBytes());
2948         // sanity check end
2949         assertEquals(expectedString, StringUtils.toString(expectedBytes, null));
2950         assertEquals(expectedString, StringUtils.toString(expectedBytes, SystemUtils.FILE_ENCODING));
2951         final String encoding = StandardCharsets.UTF_16.name();
2952         expectedBytes = expectedString.getBytes(Charset.forName(encoding));
2953         assertEquals(expectedString, StringUtils.toString(expectedBytes, encoding));
2954     }
2955 
2956     @Test
2957     void testTruncate_StringInt() {
2958         assertNull(StringUtils.truncate(null, 12));
2959         assertIllegalArgumentException(() -> StringUtils.truncate(null, -1), "maxWidth cannot be negative");
2960         assertIllegalArgumentException(() -> StringUtils.truncate(null, -10), "maxWidth cannot be negative");
2961         assertIllegalArgumentException(() -> StringUtils.truncate(null, Integer.MIN_VALUE), "maxWidth cannot be negative");
2962         assertEquals("", StringUtils.truncate("", 10));
2963         assertEquals("abc", StringUtils.truncate("abcdefghij", 3));
2964         assertEquals("abcdef", StringUtils.truncate("abcdefghij", 6));
2965         assertEquals("", StringUtils.truncate("abcdefghij", 0));
2966         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", -1), "maxWidth cannot be negative");
2967         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", -100), "maxWidth cannot be negative");
2968         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", Integer.MIN_VALUE), "maxWidth cannot be negative");
2969         assertEquals("abcdefghij", StringUtils.truncate("abcdefghijklmno", 10));
2970         assertEquals("abcdefghijklmno", StringUtils.truncate("abcdefghijklmno", Integer.MAX_VALUE));
2971         assertEquals("abcde", StringUtils.truncate("abcdefghijklmno", 5));
2972         assertEquals("abc", StringUtils.truncate("abcdefghijklmno", 3));
2973     }
2974 
2975     @Test
2976     void testTruncate_StringIntInt() {
2977         assertNull(StringUtils.truncate(null, 0, 12));
2978         assertIllegalArgumentException(() -> StringUtils.truncate(null, -1, 0), "offset cannot be negative");
2979         assertIllegalArgumentException(() -> StringUtils.truncate(null, -10, -4), "offset cannot be negative");
2980         assertIllegalArgumentException(() -> StringUtils.truncate(null, Integer.MIN_VALUE, Integer.MIN_VALUE), "offset cannot be negative");
2981         assertNull(StringUtils.truncate(null, 10, 12));
2982         assertEquals("", StringUtils.truncate("", 0, 10));
2983         assertEquals("", StringUtils.truncate("", 2, 10));
2984         assertEquals("abc", StringUtils.truncate("abcdefghij", 0, 3));
2985         assertEquals("fghij", StringUtils.truncate("abcdefghij", 5, 6));
2986         assertEquals("", StringUtils.truncate("abcdefghij", 0, 0));
2987         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", 0, -1), "maxWidth cannot be negative");
2988         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", 0, -10), "maxWidth cannot be negative");
2989         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", 0, -100), "maxWidth cannot be negative");
2990         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", 1, -100), "maxWidth cannot be negative");
2991         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", 0, Integer.MIN_VALUE), "maxWidth cannot be negative");
2992         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", -1, 0), "offset cannot be negative");
2993         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", -10, 0), "offset cannot be negative");
2994         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", -100, 1), "offset cannot be negative");
2995         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", Integer.MIN_VALUE, 0), "offset cannot be negative");
2996         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", -1, -1), "offset cannot be negative");
2997         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", -10, -10), "offset cannot be negative");
2998         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", -100, -100), "offset cannot be negative");
2999         assertIllegalArgumentException(() -> StringUtils.truncate("abcdefghij", Integer.MIN_VALUE, Integer.MIN_VALUE),
3000                 "offset cannot be negative");
3001         final String raspberry = "raspberry peach";
3002         assertEquals("peach", StringUtils.truncate(raspberry, 10, 15));
3003         assertEquals("abcdefghij", StringUtils.truncate("abcdefghijklmno", 0, 10));
3004         assertEquals("abcdefghijklmno", StringUtils.truncate("abcdefghijklmno", 0, Integer.MAX_VALUE));
3005         assertEquals("bcdefghijk", StringUtils.truncate("abcdefghijklmno", 1, 10));
3006         assertEquals("cdefghijkl", StringUtils.truncate("abcdefghijklmno", 2, 10));
3007         assertEquals("defghijklm", StringUtils.truncate("abcdefghijklmno", 3, 10));
3008         assertEquals("efghijklmn", StringUtils.truncate("abcdefghijklmno", 4, 10));
3009         assertEquals("fghijklmno", StringUtils.truncate("abcdefghijklmno", 5, 10));
3010         assertEquals("fghij", StringUtils.truncate("abcdefghijklmno", 5, 5));
3011         assertEquals("fgh", StringUtils.truncate("abcdefghijklmno", 5, 3));
3012         assertEquals("klm", StringUtils.truncate("abcdefghijklmno", 10, 3));
3013         assertEquals("klmno", StringUtils.truncate("abcdefghijklmno", 10, Integer.MAX_VALUE));
3014         assertEquals("n", StringUtils.truncate("abcdefghijklmno", 13, 1));
3015         assertEquals("no", StringUtils.truncate("abcdefghijklmno", 13, Integer.MAX_VALUE));
3016         assertEquals("o", StringUtils.truncate("abcdefghijklmno", 14, 1));
3017         assertEquals("o", StringUtils.truncate("abcdefghijklmno", 14, Integer.MAX_VALUE));
3018         assertEquals("", StringUtils.truncate("abcdefghijklmno", 15, 1));
3019         assertEquals("", StringUtils.truncate("abcdefghijklmno", 15, Integer.MAX_VALUE));
3020         assertEquals("", StringUtils.truncate("abcdefghijklmno", Integer.MAX_VALUE, Integer.MAX_VALUE));
3021     }
3022 
3023     @Test
3024     void testUnCapitalize() {
3025         assertNull(StringUtils.uncapitalize(null));
3026 
3027         assertEquals(FOO_UNCAP, StringUtils.uncapitalize(FOO_CAP), "uncapitalize(String) failed");
3028         assertEquals(FOO_UNCAP, StringUtils.uncapitalize(FOO_UNCAP), "uncapitalize(string) failed");
3029         assertEquals("", StringUtils.uncapitalize(""), "uncapitalize(empty-string) failed");
3030         assertEquals("x", StringUtils.uncapitalize("X"), "uncapitalize(single-char-string) failed");
3031 
3032         // Examples from uncapitalize Javadoc
3033         assertEquals("cat", StringUtils.uncapitalize("cat"));
3034         assertEquals("cat", StringUtils.uncapitalize("Cat"));
3035         assertEquals("cAT", StringUtils.uncapitalize("CAT"));
3036     }
3037 
3038     @Test
3039     void testUnescapeSurrogatePairs() {
3040         assertEquals("\uD83D\uDE30", StringEscapeUtils.unescapeCsv("\uD83D\uDE30"));
3041         // Examples from https://en.wikipedia.org/wiki/UTF-16
3042         assertEquals("\uD800\uDC00", StringEscapeUtils.unescapeCsv("\uD800\uDC00"));
3043         assertEquals("\uD834\uDD1E", StringEscapeUtils.unescapeCsv("\uD834\uDD1E"));
3044         assertEquals("\uDBFF\uDFFD", StringEscapeUtils.unescapeCsv("\uDBFF\uDFFD"));
3045         assertEquals("\uDBFF\uDFFD", StringEscapeUtils.unescapeHtml3("\uDBFF\uDFFD"));
3046         assertEquals("\uDBFF\uDFFD", StringEscapeUtils.unescapeHtml4("\uDBFF\uDFFD"));
3047     }
3048 
3049     @Test
3050     void testUnwrap_StringChar() {
3051         assertNull(StringUtils.unwrap(null, null));
3052         assertNull(StringUtils.unwrap(null, CharUtils.NUL));
3053         assertNull(StringUtils.unwrap(null, '1'));
3054 
3055         assertEquals("abc", StringUtils.unwrap("abc", null));
3056         assertEquals("a", StringUtils.unwrap("a", "a"));
3057         assertEquals("", StringUtils.unwrap("aa", "a"));
3058         assertEquals("abc", StringUtils.unwrap("\'abc\'", '\''));
3059         assertEquals("abc", StringUtils.unwrap("AabcA", 'A'));
3060         assertEquals("AabcA", StringUtils.unwrap("AAabcAA", 'A'));
3061         assertEquals("abc", StringUtils.unwrap("abc", 'b'));
3062         assertEquals("#A", StringUtils.unwrap("#A", '#'));
3063         assertEquals("A#", StringUtils.unwrap("A#", '#'));
3064         assertEquals("ABA", StringUtils.unwrap("AABAA", 'A'));
3065     }
3066 
3067     @Test
3068     void testUnwrap_StringString() {
3069         assertNull(StringUtils.unwrap(null, null));
3070         assertNull(StringUtils.unwrap(null, ""));
3071         assertNull(StringUtils.unwrap(null, "1"));
3072 
3073         assertEquals("abc", StringUtils.unwrap("abc", null));
3074         assertEquals("abc", StringUtils.unwrap("abc", ""));
3075         assertEquals("a", StringUtils.unwrap("a", "a"));
3076         assertEquals("ababa", StringUtils.unwrap("ababa", "aba"));
3077         assertEquals("", StringUtils.unwrap("aa", "a"));
3078         assertEquals("abc", StringUtils.unwrap("\'abc\'", "\'"));
3079         assertEquals("abc", StringUtils.unwrap("\"abc\"", "\""));
3080         assertEquals("abc\"xyz", StringUtils.unwrap("\"abc\"xyz\"", "\""));
3081         assertEquals("abc\"xyz\"", StringUtils.unwrap("\"abc\"xyz\"\"", "\""));
3082         assertEquals("abc\'xyz\'", StringUtils.unwrap("\"abc\'xyz\'\"", "\""));
3083         assertEquals("\"abc\'xyz\'\"", StringUtils.unwrap("AA\"abc\'xyz\'\"AA", "AA"));
3084         assertEquals("\"abc\'xyz\'\"", StringUtils.unwrap("123\"abc\'xyz\'\"123", "123"));
3085         assertEquals("AA\"abc\'xyz\'\"", StringUtils.unwrap("AA\"abc\'xyz\'\"", "AA"));
3086         assertEquals("AA\"abc\'xyz\'\"AA", StringUtils.unwrap("AAA\"abc\'xyz\'\"AAA", "A"));
3087         assertEquals("\"abc\'xyz\'\"AA", StringUtils.unwrap("\"abc\'xyz\'\"AA", "AA"));
3088     }
3089 
3090     @Test
3091     void testUpperCase() {
3092         assertNull(StringUtils.upperCase(null));
3093         assertNull(StringUtils.upperCase(null, Locale.ENGLISH));
3094         assertEquals("FOO TEST THING", StringUtils.upperCase("fOo test THING"), "upperCase(String) failed");
3095         assertEquals("", StringUtils.upperCase(""), "upperCase(empty-string) failed");
3096         assertEquals("FOO TEST THING", StringUtils.upperCase("fOo test THING", Locale.ENGLISH),
3097                 "upperCase(String, Locale) failed");
3098         assertEquals("", StringUtils.upperCase("", Locale.ENGLISH),
3099                 "upperCase(empty-string, Locale) failed");
3100     }
3101 
3102     @Test
3103     void testWrap_StringChar() {
3104         assertNull(StringUtils.wrap(null, CharUtils.NUL));
3105         assertNull(StringUtils.wrap(null, '1'));
3106 
3107         assertEquals("", StringUtils.wrap("", CharUtils.NUL));
3108         assertEquals("xabx", StringUtils.wrap("ab", 'x'));
3109         assertEquals("\"ab\"", StringUtils.wrap("ab", '\"'));
3110         assertEquals("\"\"ab\"\"", StringUtils.wrap("\"ab\"", '\"'));
3111         assertEquals("'ab'", StringUtils.wrap("ab", '\''));
3112         assertEquals("''abcd''", StringUtils.wrap("'abcd'", '\''));
3113         assertEquals("'\"abcd\"'", StringUtils.wrap("\"abcd\"", '\''));
3114         assertEquals("\"'abcd'\"", StringUtils.wrap("'abcd'", '\"'));
3115     }
3116 
3117     @Test
3118     void testWrap_StringString() {
3119         assertNull(StringUtils.wrap(null, null));
3120         assertNull(StringUtils.wrap(null, ""));
3121         assertNull(StringUtils.wrap(null, "1"));
3122 
3123         assertNull(StringUtils.wrap(null, null));
3124         assertEquals("", StringUtils.wrap("", ""));
3125         assertEquals("ab", StringUtils.wrap("ab", null));
3126         assertEquals("xabx", StringUtils.wrap("ab", "x"));
3127         assertEquals("\"ab\"", StringUtils.wrap("ab", "\""));
3128         assertEquals("\"\"ab\"\"", StringUtils.wrap("\"ab\"", "\""));
3129         assertEquals("'ab'", StringUtils.wrap("ab", "'"));
3130         assertEquals("''abcd''", StringUtils.wrap("'abcd'", "'"));
3131         assertEquals("'\"abcd\"'", StringUtils.wrap("\"abcd\"", "'"));
3132         assertEquals("\"'abcd'\"", StringUtils.wrap("'abcd'", "\""));
3133     }
3134 
3135     @Test
3136     void testWrapIfMissing_StringChar() {
3137         assertNull(StringUtils.wrapIfMissing(null, CharUtils.NUL));
3138         assertNull(StringUtils.wrapIfMissing(null, '1'));
3139 
3140         assertEquals("", StringUtils.wrapIfMissing("", CharUtils.NUL));
3141         assertEquals("xabx", StringUtils.wrapIfMissing("ab", 'x'));
3142         assertEquals("\"ab\"", StringUtils.wrapIfMissing("ab", '\"'));
3143         assertEquals("\"ab\"", StringUtils.wrapIfMissing("\"ab\"", '\"'));
3144         assertEquals("'ab'", StringUtils.wrapIfMissing("ab", '\''));
3145         assertEquals("'abcd'", StringUtils.wrapIfMissing("'abcd'", '\''));
3146         assertEquals("'\"abcd\"'", StringUtils.wrapIfMissing("\"abcd\"", '\''));
3147         assertEquals("\"'abcd'\"", StringUtils.wrapIfMissing("'abcd'", '\"'));
3148         assertEquals("/x/", StringUtils.wrapIfMissing("x", '/'));
3149         assertEquals("/x/y/z/", StringUtils.wrapIfMissing("x/y/z", '/'));
3150         assertEquals("/x/y/z/", StringUtils.wrapIfMissing("/x/y/z", '/'));
3151         assertEquals("/x/y/z/", StringUtils.wrapIfMissing("x/y/z/", '/'));
3152 
3153         assertSame("/", StringUtils.wrapIfMissing("/", '/'));
3154         assertSame("/x/", StringUtils.wrapIfMissing("/x/", '/'));
3155     }
3156 
3157     @Test
3158     void testWrapIfMissing_StringString() {
3159         assertNull(StringUtils.wrapIfMissing(null, "\0"));
3160         assertNull(StringUtils.wrapIfMissing(null, "1"));
3161 
3162         assertEquals("", StringUtils.wrapIfMissing("", "\0"));
3163         assertEquals("xabx", StringUtils.wrapIfMissing("ab", "x"));
3164         assertEquals("\"ab\"", StringUtils.wrapIfMissing("ab", "\""));
3165         assertEquals("\"ab\"", StringUtils.wrapIfMissing("\"ab\"", "\""));
3166         assertEquals("'ab'", StringUtils.wrapIfMissing("ab", "\'"));
3167         assertEquals("'abcd'", StringUtils.wrapIfMissing("'abcd'", "\'"));
3168         assertEquals("'\"abcd\"'", StringUtils.wrapIfMissing("\"abcd\"", "\'"));
3169         assertEquals("\"'abcd'\"", StringUtils.wrapIfMissing("'abcd'", "\""));
3170         assertEquals("/x/", StringUtils.wrapIfMissing("x", "/"));
3171         assertEquals("/x/y/z/", StringUtils.wrapIfMissing("x/y/z", "/"));
3172         assertEquals("/x/y/z/", StringUtils.wrapIfMissing("/x/y/z", "/"));
3173         assertEquals("/x/y/z/", StringUtils.wrapIfMissing("x/y/z/", "/"));
3174         assertEquals("/", StringUtils.wrapIfMissing("/", "/"));
3175         assertEquals("ab/ab", StringUtils.wrapIfMissing("/", "ab"));
3176 
3177         assertSame("ab/ab", StringUtils.wrapIfMissing("ab/ab", "ab"));
3178         assertSame("//x//", StringUtils.wrapIfMissing("//x//", "//"));
3179     }
3180 }