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