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  
18  package org.apache.commons.lang3.text;
19  
20  import static org.apache.commons.lang3.LangAssertions.assertIndexOutOfBoundsException;
21  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
22  import static org.junit.jupiter.api.Assertions.assertEquals;
23  import static org.junit.jupiter.api.Assertions.assertFalse;
24  import static org.junit.jupiter.api.Assertions.assertNotEquals;
25  import static org.junit.jupiter.api.Assertions.assertNotNull;
26  import static org.junit.jupiter.api.Assertions.assertNotSame;
27  import static org.junit.jupiter.api.Assertions.assertNull;
28  import static org.junit.jupiter.api.Assertions.assertSame;
29  import static org.junit.jupiter.api.Assertions.assertTrue;
30  
31  import java.io.IOException;
32  import java.io.Reader;
33  import java.io.StringReader;
34  import java.io.StringWriter;
35  import java.io.Writer;
36  import java.nio.CharBuffer;
37  
38  import org.apache.commons.lang3.AbstractLangTest;
39  import org.apache.commons.lang3.ArrayUtils;
40  import org.junit.jupiter.api.Test;
41  
42  /**
43   * Tests for {@link org.apache.commons.lang3.text.StrBuilder}.
44   */
45  @Deprecated
46  class StrBuilderTest extends AbstractLangTest {
47  
48      private static final class MockReadable implements Readable {
49  
50          private final CharBuffer src;
51  
52          MockReadable(final String src) {
53              this.src = CharBuffer.wrap(src);
54          }
55  
56          @Override
57          public int read(final CharBuffer cb) throws IOException {
58              return src.read(cb);
59          }
60      }
61  
62      static final StrMatcher A_NUMBER_MATCHER = new StrMatcher() {
63          @Override
64          public int isMatch(final char[] buffer, int pos, final int bufferStart, final int bufferEnd) {
65              if (buffer[pos] == 'A') {
66                  pos++;
67                  if (pos < bufferEnd && buffer[pos] >= '0' && buffer[pos] <= '9') {
68                      return 2;
69                  }
70              }
71              return 0;
72          }
73      };
74  
75      @Test
76      void test_LANG_1131_EqualsWithNullStrBuilder() {
77          final StrBuilder sb = new StrBuilder();
78          final StrBuilder other = null;
79          assertNotEquals(sb, other);
80      }
81  
82      @Test
83      void testAppendCharBuffer() {
84          final StrBuilder sb1 = new StrBuilder();
85          final CharBuffer buf = CharBuffer.allocate(10);
86          buf.append("0123456789");
87          buf.flip();
88          sb1.append(buf);
89          assertEquals("0123456789", sb1.toString());
90  
91          final StrBuilder sb2 = new StrBuilder();
92          sb2.append(buf, 1, 8);
93          assertEquals("12345678", sb2.toString());
94      }
95  
96      @Test
97      void testAppendToCharBuffer() throws Exception {
98          final StrBuilder sb = new StrBuilder("1234567890");
99          final String text = "Test ";
100         final CharBuffer buffer = CharBuffer.allocate(sb.size() + text.length());
101         buffer.put(text);
102 
103         sb.appendTo(buffer);
104 
105         buffer.flip();
106         assertEquals("Test 1234567890", buffer.toString());
107     }
108 
109     @Test
110     void testAppendToStringBuffer() throws Exception {
111         final StrBuilder sb = new StrBuilder("1234567890");
112         final StringBuffer buffer = new StringBuffer("Test ");
113 
114         sb.appendTo(buffer);
115 
116         assertEquals("Test 1234567890", buffer.toString());
117     }
118 
119     @Test
120     void testAppendToStringBuilder() throws Exception {
121         final StrBuilder sb = new StrBuilder("1234567890");
122         final StringBuilder builder = new StringBuilder("Test ");
123 
124         sb.appendTo(builder);
125 
126         assertEquals("Test 1234567890", builder.toString());
127     }
128 
129     @Test
130     void testAppendToWriter() throws Exception {
131         final StrBuilder sb = new StrBuilder("1234567890");
132         final StringWriter writer = new StringWriter();
133         writer.append("Test ");
134 
135         sb.appendTo(writer);
136 
137         assertEquals("Test 1234567890", writer.toString());
138     }
139 
140     @Test
141     void testAsBuilder() {
142         final StrBuilder sb = new StrBuilder().appendAll("Lorem", " ", "ipsum", " ", "dolor");
143         assertEquals(sb.toString(), sb.build());
144     }
145 
146     @Test
147     void testAsReader() throws Exception {
148         final StrBuilder sb = new StrBuilder("some text");
149         try (Reader reader = sb.asReader()) {
150             assertTrue(reader.ready());
151             final char[] buf = new char[40];
152             assertEquals(9, reader.read(buf));
153             assertEquals("some text", new String(buf, 0, 9));
154 
155             assertEquals(-1, reader.read());
156             assertFalse(reader.ready());
157             assertEquals(0, reader.skip(2));
158             assertEquals(0, reader.skip(-1));
159 
160             assertTrue(reader.markSupported());
161         }
162         char[] array = new char[3];
163         try (Reader reader = sb.asReader()) {
164             assertEquals('s', reader.read());
165             reader.mark(-1);
166             assertEquals(3, reader.read(array, 0, 3));
167             assertEquals('o', array[0]);
168             assertEquals('m', array[1]);
169             assertEquals('e', array[2]);
170             reader.reset();
171             assertEquals(1, reader.read(array, 1, 1));
172             assertEquals('o', array[0]);
173             assertEquals('o', array[1]);
174             assertEquals('e', array[2]);
175             assertEquals(2, reader.skip(2));
176             assertEquals(' ', reader.read());
177 
178             assertTrue(reader.ready());
179             reader.close();
180             assertTrue(reader.ready());
181         }
182         try (Reader r = sb.asReader()) {
183             final char[] arr = new char[3];
184             assertIndexOutOfBoundsException(() -> r.read(arr, -1, 0));
185             assertIndexOutOfBoundsException(() -> r.read(arr, 0, -1));
186             assertIndexOutOfBoundsException(() -> r.read(arr, 100, 1));
187             assertIndexOutOfBoundsException(() -> r.read(arr, 0, 100));
188             assertIndexOutOfBoundsException(() -> r.read(arr, Integer.MAX_VALUE, Integer.MAX_VALUE));
189 
190             assertEquals(0, r.read(arr, 0, 0));
191             assertEquals(0, arr[0]);
192             assertEquals(0, arr[1]);
193             assertEquals(0, arr[2]);
194 
195             r.skip(9);
196             assertEquals(-1, r.read(arr, 0, 1));
197 
198             r.reset();
199             array = new char[30];
200             assertEquals(9, r.read(array, 0, 30));
201         }
202     }
203 
204     @Test
205     void testAsTokenizer() {
206         // from Javadoc
207         final StrBuilder b = new StrBuilder();
208         b.append("a b ");
209         final StrTokenizer t = b.asTokenizer();
210 
211         final String[] tokens1 = t.getTokenArray();
212         assertEquals(2, tokens1.length);
213         assertEquals("a", tokens1[0]);
214         assertEquals("b", tokens1[1]);
215         assertEquals(2, t.size());
216 
217         b.append("c d ");
218         final String[] tokens2 = t.getTokenArray();
219         assertEquals(2, tokens2.length);
220         assertEquals("a", tokens2[0]);
221         assertEquals("b", tokens2[1]);
222         assertEquals(2, t.size());
223         assertEquals("a", t.next());
224         assertEquals("b", t.next());
225 
226         t.reset();
227         final String[] tokens3 = t.getTokenArray();
228         assertEquals(4, tokens3.length);
229         assertEquals("a", tokens3[0]);
230         assertEquals("b", tokens3[1]);
231         assertEquals("c", tokens3[2]);
232         assertEquals("d", tokens3[3]);
233         assertEquals(4, t.size());
234         assertEquals("a", t.next());
235         assertEquals("b", t.next());
236         assertEquals("c", t.next());
237         assertEquals("d", t.next());
238 
239         assertEquals("a b c d ", t.getContent());
240     }
241 
242     @Test
243     void testAsWriter() throws Exception {
244         final StrBuilder sb = new StrBuilder("base");
245         try (Writer writer = sb.asWriter()) {
246 
247             writer.write('l');
248             assertEquals("basel", sb.toString());
249 
250             writer.write(new char[] { 'i', 'n' });
251             assertEquals("baselin", sb.toString());
252 
253             writer.write(new char[] { 'n', 'e', 'r' }, 1, 2);
254             assertEquals("baseliner", sb.toString());
255 
256             writer.write(" rout");
257             assertEquals("baseliner rout", sb.toString());
258 
259             writer.write("ping that server", 1, 3);
260             assertEquals("baseliner routing", sb.toString());
261 
262             writer.flush(); // no effect
263             assertEquals("baseliner routing", sb.toString());
264 
265             writer.close(); // no effect
266             assertEquals("baseliner routing", sb.toString());
267 
268             writer.write(" hi"); // works after close
269             assertEquals("baseliner routing hi", sb.toString());
270 
271             sb.setLength(4); // mix and match
272             writer.write('d');
273             assertEquals("based", sb.toString());
274         }
275     }
276 
277     @Test
278     void testCapacity() {
279         final StrBuilder sb = new StrBuilder();
280         assertEquals(sb.buffer.length, sb.capacity());
281 
282         sb.append("HelloWorldHelloWorldHelloWorldHelloWorld");
283         assertEquals(sb.buffer.length, sb.capacity());
284     }
285 
286     @Test
287     void testCapacityAndLength() {
288         final StrBuilder sb = new StrBuilder();
289         assertEquals(32, sb.capacity());
290         assertEquals(0, sb.length());
291         assertEquals(0, sb.size());
292         assertTrue(sb.isEmpty());
293 
294         sb.minimizeCapacity();
295         assertEquals(0, sb.capacity());
296         assertEquals(0, sb.length());
297         assertEquals(0, sb.size());
298         assertTrue(sb.isEmpty());
299 
300         sb.ensureCapacity(32);
301         assertTrue(sb.capacity() >= 32);
302         assertEquals(0, sb.length());
303         assertEquals(0, sb.size());
304         assertTrue(sb.isEmpty());
305 
306         sb.append("foo");
307         assertTrue(sb.capacity() >= 32);
308         assertEquals(3, sb.length());
309         assertEquals(3, sb.size());
310         assertFalse(sb.isEmpty());
311 
312         sb.clear();
313         assertTrue(sb.capacity() >= 32);
314         assertEquals(0, sb.length());
315         assertEquals(0, sb.size());
316         assertTrue(sb.isEmpty());
317 
318         sb.append("123456789012345678901234567890123");
319         assertTrue(sb.capacity() > 32);
320         assertEquals(33, sb.length());
321         assertEquals(33, sb.size());
322         assertFalse(sb.isEmpty());
323 
324         sb.ensureCapacity(16);
325         assertTrue(sb.capacity() > 16);
326         assertEquals(33, sb.length());
327         assertEquals(33, sb.size());
328         assertFalse(sb.isEmpty());
329 
330         sb.minimizeCapacity();
331         assertEquals(33, sb.capacity());
332         assertEquals(33, sb.length());
333         assertEquals(33, sb.size());
334         assertFalse(sb.isEmpty());
335 
336         assertIndexOutOfBoundsException(() -> sb.setLength(-1), "setLength(-1) expected StringIndexOutOfBoundsException");
337 
338         sb.setLength(33);
339         assertEquals(33, sb.capacity());
340         assertEquals(33, sb.length());
341         assertEquals(33, sb.size());
342         assertFalse(sb.isEmpty());
343 
344         sb.setLength(16);
345         assertTrue(sb.capacity() >= 16);
346         assertEquals(16, sb.length());
347         assertEquals(16, sb.size());
348         assertEquals("1234567890123456", sb.toString());
349         assertFalse(sb.isEmpty());
350 
351         sb.setLength(32);
352         assertTrue(sb.capacity() >= 32);
353         assertEquals(32, sb.length());
354         assertEquals(32, sb.size());
355         assertEquals("1234567890123456\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sb.toString());
356         assertFalse(sb.isEmpty());
357 
358         sb.setLength(0);
359         assertTrue(sb.capacity() >= 32);
360         assertEquals(0, sb.length());
361         assertEquals(0, sb.size());
362         assertTrue(sb.isEmpty());
363     }
364 
365     @Test
366     void testChaining() {
367         final StrBuilder sb = new StrBuilder();
368         assertSame(sb, sb.setNewLineText(null));
369         assertSame(sb, sb.setNullText(null));
370         assertSame(sb, sb.setLength(1));
371         assertSame(sb, sb.setCharAt(0, 'a'));
372         assertSame(sb, sb.ensureCapacity(0));
373         assertSame(sb, sb.minimizeCapacity());
374         assertSame(sb, sb.clear());
375         assertSame(sb, sb.reverse());
376         assertSame(sb, sb.trim());
377     }
378 
379     @Test
380     void testCharAt() {
381         final StrBuilder sb = new StrBuilder();
382         assertIndexOutOfBoundsException(() -> sb.charAt(0), "charAt(0) expected IndexOutOfBoundsException");
383         assertIndexOutOfBoundsException(() -> sb.charAt(-1), "charAt(-1) expected IndexOutOfBoundsException");
384         sb.append("foo");
385         assertEquals('f', sb.charAt(0));
386         assertEquals('o', sb.charAt(1));
387         assertEquals('o', sb.charAt(2));
388         assertIndexOutOfBoundsException(() -> sb.charAt(-1), "charAt(-1) expected IndexOutOfBoundsException");
389         assertIndexOutOfBoundsException(() -> sb.charAt(3), "charAt(3) expected IndexOutOfBoundsException");
390     }
391 
392     @Test
393     void testClear() {
394         final StrBuilder sb = new StrBuilder();
395         sb.append("Hello");
396         sb.clear();
397         assertEquals(0, sb.length());
398         assertTrue(sb.buffer.length >= 5);
399     }
400 
401     @Test
402     void testConstructors() {
403         final StrBuilder sb0 = new StrBuilder();
404         assertEquals(32, sb0.capacity());
405         assertEquals(0, sb0.length());
406         assertEquals(0, sb0.size());
407 
408         final StrBuilder sb1 = new StrBuilder(32);
409         assertEquals(32, sb1.capacity());
410         assertEquals(0, sb1.length());
411         assertEquals(0, sb1.size());
412 
413         final StrBuilder sb2 = new StrBuilder(0);
414         assertEquals(32, sb2.capacity());
415         assertEquals(0, sb2.length());
416         assertEquals(0, sb2.size());
417 
418         final StrBuilder sb3 = new StrBuilder(-1);
419         assertEquals(32, sb3.capacity());
420         assertEquals(0, sb3.length());
421         assertEquals(0, sb3.size());
422 
423         final StrBuilder sb4 = new StrBuilder(1);
424         assertEquals(1, sb4.capacity());
425         assertEquals(0, sb4.length());
426         assertEquals(0, sb4.size());
427 
428         final StrBuilder sb5 = new StrBuilder(null);
429         assertEquals(32, sb5.capacity());
430         assertEquals(0, sb5.length());
431         assertEquals(0, sb5.size());
432 
433         final StrBuilder sb6 = new StrBuilder("");
434         assertEquals(32, sb6.capacity());
435         assertEquals(0, sb6.length());
436         assertEquals(0, sb6.size());
437 
438         final StrBuilder sb7 = new StrBuilder("foo");
439         assertEquals(35, sb7.capacity());
440         assertEquals(3, sb7.length());
441         assertEquals(3, sb7.size());
442     }
443 
444     @Test
445     void testContains_char() {
446         final StrBuilder sb = new StrBuilder("abcdefghijklmnopqrstuvwxyz");
447         assertTrue(sb.contains('a'));
448         assertTrue(sb.contains('o'));
449         assertTrue(sb.contains('z'));
450         assertFalse(sb.contains('1'));
451     }
452 
453     @Test
454     void testContains_String() {
455         final StrBuilder sb = new StrBuilder("abcdefghijklmnopqrstuvwxyz");
456         assertTrue(sb.contains("a"));
457         assertTrue(sb.contains("pq"));
458         assertTrue(sb.contains("z"));
459         assertFalse(sb.contains("zyx"));
460         assertFalse(sb.contains((String) null));
461     }
462 
463     @Test
464     void testContains_StrMatcher() {
465         StrBuilder sb = new StrBuilder("abcdefghijklmnopqrstuvwxyz");
466         assertTrue(sb.contains(StrMatcher.charMatcher('a')));
467         assertTrue(sb.contains(StrMatcher.stringMatcher("pq")));
468         assertTrue(sb.contains(StrMatcher.charMatcher('z')));
469         assertFalse(sb.contains(StrMatcher.stringMatcher("zy")));
470         assertFalse(sb.contains((StrMatcher) null));
471 
472         sb = new StrBuilder();
473         assertFalse(sb.contains(A_NUMBER_MATCHER));
474         sb.append("B A1 C");
475         assertTrue(sb.contains(A_NUMBER_MATCHER));
476     }
477 
478     @Test
479     void testDeleteAll_char() {
480         StrBuilder sb = new StrBuilder("abcbccba");
481         sb.deleteAll('X');
482         assertEquals("abcbccba", sb.toString());
483         sb.deleteAll('a');
484         assertEquals("bcbccb", sb.toString());
485         sb.deleteAll('c');
486         assertEquals("bbb", sb.toString());
487         sb.deleteAll('b');
488         assertEquals("", sb.toString());
489 
490         sb = new StrBuilder("");
491         sb.deleteAll('b');
492         assertEquals("", sb.toString());
493     }
494 
495     @Test
496     void testDeleteAll_String() {
497         StrBuilder sb = new StrBuilder("abcbccba");
498         sb.deleteAll((String) null);
499         assertEquals("abcbccba", sb.toString());
500         sb.deleteAll("");
501         assertEquals("abcbccba", sb.toString());
502 
503         sb.deleteAll("X");
504         assertEquals("abcbccba", sb.toString());
505         sb.deleteAll("a");
506         assertEquals("bcbccb", sb.toString());
507         sb.deleteAll("c");
508         assertEquals("bbb", sb.toString());
509         sb.deleteAll("b");
510         assertEquals("", sb.toString());
511 
512         sb = new StrBuilder("abcbccba");
513         sb.deleteAll("bc");
514         assertEquals("acba", sb.toString());
515 
516         sb = new StrBuilder("");
517         sb.deleteAll("bc");
518         assertEquals("", sb.toString());
519     }
520 
521     @Test
522     void testDeleteAll_StrMatcher() {
523         StrBuilder sb = new StrBuilder("A0xA1A2yA3");
524         sb.deleteAll((StrMatcher) null);
525         assertEquals("A0xA1A2yA3", sb.toString());
526         sb.deleteAll(A_NUMBER_MATCHER);
527         assertEquals("xy", sb.toString());
528 
529         sb = new StrBuilder("Ax1");
530         sb.deleteAll(A_NUMBER_MATCHER);
531         assertEquals("Ax1", sb.toString());
532 
533         sb = new StrBuilder("");
534         sb.deleteAll(A_NUMBER_MATCHER);
535         assertEquals("", sb.toString());
536     }
537 
538     @Test
539     void testDeleteCharAt() {
540         final StrBuilder sb = new StrBuilder("abc");
541         sb.deleteCharAt(0);
542         assertEquals("bc", sb.toString());
543 
544         assertIndexOutOfBoundsException(() -> sb.deleteCharAt(1000));
545     }
546 
547     @Test
548     void testDeleteFirst_char() {
549         StrBuilder sb = new StrBuilder("abcba");
550         sb.deleteFirst('X');
551         assertEquals("abcba", sb.toString());
552         sb.deleteFirst('a');
553         assertEquals("bcba", sb.toString());
554         sb.deleteFirst('c');
555         assertEquals("bba", sb.toString());
556         sb.deleteFirst('b');
557         assertEquals("ba", sb.toString());
558 
559         sb = new StrBuilder("");
560         sb.deleteFirst('b');
561         assertEquals("", sb.toString());
562     }
563 
564     @Test
565     void testDeleteFirst_String() {
566         StrBuilder sb = new StrBuilder("abcbccba");
567         sb.deleteFirst((String) null);
568         assertEquals("abcbccba", sb.toString());
569         sb.deleteFirst("");
570         assertEquals("abcbccba", sb.toString());
571 
572         sb.deleteFirst("X");
573         assertEquals("abcbccba", sb.toString());
574         sb.deleteFirst("a");
575         assertEquals("bcbccba", sb.toString());
576         sb.deleteFirst("c");
577         assertEquals("bbccba", sb.toString());
578         sb.deleteFirst("b");
579         assertEquals("bccba", sb.toString());
580 
581         sb = new StrBuilder("abcbccba");
582         sb.deleteFirst("bc");
583         assertEquals("abccba", sb.toString());
584 
585         sb = new StrBuilder("");
586         sb.deleteFirst("bc");
587         assertEquals("", sb.toString());
588     }
589 
590     @Test
591     void testDeleteFirst_StrMatcher() {
592         StrBuilder sb = new StrBuilder("A0xA1A2yA3");
593         sb.deleteFirst((StrMatcher) null);
594         assertEquals("A0xA1A2yA3", sb.toString());
595         sb.deleteFirst(A_NUMBER_MATCHER);
596         assertEquals("xA1A2yA3", sb.toString());
597 
598         sb = new StrBuilder("Ax1");
599         sb.deleteFirst(A_NUMBER_MATCHER);
600         assertEquals("Ax1", sb.toString());
601 
602         sb = new StrBuilder("");
603         sb.deleteFirst(A_NUMBER_MATCHER);
604         assertEquals("", sb.toString());
605     }
606 
607     @Test
608     void testDeleteIntInt() {
609         final StrBuilder sb = new StrBuilder("abc");
610         sb.delete(0, 1);
611         assertEquals("bc", sb.toString());
612         sb.delete(1, 2);
613         assertEquals("b", sb.toString());
614         sb.delete(0, 1);
615         assertEquals("", sb.toString());
616         sb.delete(0, 1000);
617         assertEquals("", sb.toString());
618 
619         assertIndexOutOfBoundsException(() -> sb.delete(1, 2));
620         assertIndexOutOfBoundsException(() -> sb.delete(-1, 1));
621         assertIndexOutOfBoundsException(() -> new StrBuilder("anything").delete(2, 1));
622     }
623 
624     @Test
625     void testEndsWith() {
626         final StrBuilder sb = new StrBuilder();
627         assertFalse(sb.endsWith("a"));
628         assertFalse(sb.endsWith("c"));
629         assertTrue(sb.endsWith(""));
630         assertFalse(sb.endsWith(null));
631         sb.append("abc");
632         assertTrue(sb.endsWith("c"));
633         assertTrue(sb.endsWith("bc"));
634         assertTrue(sb.endsWith("abc"));
635         assertFalse(sb.endsWith("cba"));
636         assertFalse(sb.endsWith("abcd"));
637         assertFalse(sb.endsWith(" abc"));
638         assertFalse(sb.endsWith("abc "));
639     }
640 
641     @Test
642     void testEnsureCapacity() {
643         final StrBuilder sb = new StrBuilder();
644         sb.ensureCapacity(2);
645         assertTrue(sb.capacity() >= 2);
646 
647         sb.ensureCapacity(-1);
648         assertTrue(sb.capacity() >= 0);
649 
650         sb.append("HelloWorld");
651         sb.ensureCapacity(40);
652         assertTrue(sb.capacity() >= 40);
653     }
654 
655     @Test
656     void testEquals() {
657         final StrBuilder sb1 = new StrBuilder();
658         final StrBuilder sb2 = new StrBuilder();
659         assertEquals(sb1, sb2);
660         assertEquals(sb1, sb1);
661         assertEquals(sb2, sb2);
662         assertEquals(sb1, sb2);
663 
664         sb1.append("abc");
665         assertNotEquals(sb1, sb2);
666         assertNotEquals(sb1, sb2);
667 
668         sb2.append("ABC");
669         assertNotEquals(sb1, sb2);
670         assertNotEquals(sb1, sb2);
671 
672         sb2.clear().append("abc");
673         assertEquals(sb1, sb2);
674         assertEquals(sb1, sb2);
675 
676         assertNotEquals(sb1, Integer.valueOf(1));
677         assertNotEquals("abc", sb1);
678     }
679 
680     @Test
681     void testEqualsIgnoreCase() {
682         final StrBuilder sb1 = new StrBuilder();
683         final StrBuilder sb2 = new StrBuilder();
684         assertTrue(sb1.equalsIgnoreCase(sb1));
685         assertTrue(sb1.equalsIgnoreCase(sb2));
686         assertTrue(sb2.equalsIgnoreCase(sb2));
687 
688         sb1.append("abc");
689         assertFalse(sb1.equalsIgnoreCase(sb2));
690 
691         sb2.append("ABC");
692         assertTrue(sb1.equalsIgnoreCase(sb2));
693 
694         sb2.clear().append("abc");
695         assertTrue(sb1.equalsIgnoreCase(sb2));
696         assertTrue(sb1.equalsIgnoreCase(sb1));
697         assertTrue(sb2.equalsIgnoreCase(sb2));
698 
699         sb2.clear().append("aBc");
700         assertTrue(sb1.equalsIgnoreCase(sb2));
701 
702         // characters that only fold together via toLowerCase, matching String.equalsIgnoreCase
703         sb1.clear().append("\u004B"); // LATIN CAPITAL LETTER K
704         sb2.clear().append("\u212A"); // KELVIN SIGN, lower-cases to 'k'
705         assertTrue(sb1.equalsIgnoreCase(sb2));
706         assertTrue(sb2.equalsIgnoreCase(sb1));
707 
708         sb1.clear().append("\u00E5"); // LATIN SMALL LETTER A WITH RING ABOVE
709         sb2.clear().append("\u212B"); // ANGSTROM SIGN, lower-cases to the same
710         assertTrue(sb1.equalsIgnoreCase(sb2));
711     }
712 
713     @Test
714     void testGetChars () {
715         final StrBuilder sb = new StrBuilder();
716 
717         char[] input = new char[10];
718         char[] a = sb.getChars(input);
719         assertSame (input, a);
720         assertArrayEquals(new char[10], a);
721 
722         sb.append("junit");
723         a = sb.getChars(input);
724         assertSame(input, a);
725         assertArrayEquals(new char[]{'j', 'u', 'n', 'i', 't', 0, 0, 0, 0, 0}, a);
726 
727         a = sb.getChars(null);
728         assertNotSame(input, a);
729         assertEquals(5, a.length);
730         assertArrayEquals("junit".toCharArray(), a);
731 
732         input = new char[5];
733         a = sb.getChars(input);
734         assertSame(input, a);
735 
736         input = new char[4];
737         a = sb.getChars(input);
738         assertNotSame(input, a);
739     }
740 
741     @Test
742     void testGetCharsIntIntCharArrayInt() {
743         final StrBuilder sb = new StrBuilder();
744 
745         sb.append("junit");
746         final char[] a = new char[5];
747         sb.getChars(0, 5, a, 0);
748         assertArrayEquals(new char[]{'j', 'u', 'n', 'i', 't'}, a);
749 
750         final char[] b = new char[5];
751         sb.getChars(0, 2, b, 3);
752         assertArrayEquals(new char[]{0, 0, 0, 'j', 'u'}, b);
753 
754         assertIndexOutOfBoundsException(() -> sb.getChars(-1, 0, b, 0));
755         assertIndexOutOfBoundsException(() -> sb.getChars(0, -1, b, 0));
756         assertIndexOutOfBoundsException(() -> sb.getChars(0, 20, b, 0));
757         assertIndexOutOfBoundsException(() -> sb.getChars(4, 2, b, 0));
758     }
759 
760     @Test
761     void testGetSetNewLineText() {
762         final StrBuilder sb = new StrBuilder();
763         assertNull(sb.getNewLineText());
764 
765         sb.setNewLineText("#");
766         assertEquals("#", sb.getNewLineText());
767 
768         sb.setNewLineText("");
769         assertEquals("", sb.getNewLineText());
770 
771         sb.setNewLineText(null);
772         assertNull(sb.getNewLineText());
773     }
774 
775     @Test
776     void testGetSetNullText() {
777         final StrBuilder sb = new StrBuilder();
778         assertNull(sb.getNullText());
779 
780         sb.setNullText("null");
781         assertEquals("null", sb.getNullText());
782 
783         sb.setNullText("");
784         assertNull(sb.getNullText());
785 
786         sb.setNullText("NULL");
787         assertEquals("NULL", sb.getNullText());
788 
789         sb.setNullText(null);
790         assertNull(sb.getNullText());
791     }
792 
793     @Test
794     void testHashCode() {
795         final StrBuilder sb = new StrBuilder();
796         final int hc1a = sb.hashCode();
797         final int hc1b = sb.hashCode();
798         assertEquals(0, hc1a);
799         assertEquals(hc1a, hc1b);
800 
801         sb.append("abc");
802         final int hc2a = sb.hashCode();
803         final int hc2b = sb.hashCode();
804         assertTrue(hc2a != 0);
805         assertEquals(hc2a, hc2b);
806     }
807 
808     @Test
809     void testIndexOf_char() {
810         final StrBuilder sb = new StrBuilder("abab");
811         assertEquals(0, sb.indexOf('a'));
812 
813         // should work like String#indexOf
814         assertEquals("abab".indexOf('a'), sb.indexOf('a'));
815 
816         assertEquals(1, sb.indexOf('b'));
817         assertEquals("abab".indexOf('b'), sb.indexOf('b'));
818 
819         assertEquals(-1, sb.indexOf('z'));
820     }
821 
822     @Test
823     void testIndexOf_char_int() {
824         StrBuilder sb = new StrBuilder("abab");
825         assertEquals(0, sb.indexOf('a', -1));
826         assertEquals(0, sb.indexOf('a', 0));
827         assertEquals(2, sb.indexOf('a', 1));
828         assertEquals(-1, sb.indexOf('a', 4));
829         assertEquals(-1, sb.indexOf('a', 5));
830 
831         // should work like String#indexOf
832         assertEquals("abab".indexOf('a', 1), sb.indexOf('a', 1));
833 
834         assertEquals(3, sb.indexOf('b', 2));
835         assertEquals("abab".indexOf('b', 2), sb.indexOf('b', 2));
836 
837         assertEquals(-1, sb.indexOf('z', 2));
838 
839         sb = new StrBuilder("xyzabc");
840         assertEquals(2, sb.indexOf('z', 0));
841         assertEquals(-1, sb.indexOf('z', 3));
842     }
843 
844     @Test
845     void testIndexOf_String() {
846         final StrBuilder sb = new StrBuilder("abab");
847 
848         assertEquals(0, sb.indexOf("a"));
849         //should work like String#indexOf
850         assertEquals("abab".indexOf("a"), sb.indexOf("a"));
851 
852         assertEquals(0, sb.indexOf("ab"));
853         //should work like String#indexOf
854         assertEquals("abab".indexOf("ab"), sb.indexOf("ab"));
855 
856         assertEquals(1, sb.indexOf("b"));
857         assertEquals("abab".indexOf("b"), sb.indexOf("b"));
858 
859         assertEquals(1, sb.indexOf("ba"));
860         assertEquals("abab".indexOf("ba"), sb.indexOf("ba"));
861 
862         assertEquals(-1, sb.indexOf("z"));
863 
864         assertEquals(-1, sb.indexOf((String) null));
865     }
866 
867     @Test
868     void testIndexOf_String_int() {
869         StrBuilder sb = new StrBuilder("abab");
870         assertEquals(0, sb.indexOf("a", -1));
871         assertEquals(0, sb.indexOf("a", 0));
872         assertEquals(2, sb.indexOf("a", 1));
873         assertEquals(2, sb.indexOf("a", 2));
874         assertEquals(-1, sb.indexOf("a", 3));
875         assertEquals(-1, sb.indexOf("a", 4));
876         assertEquals(-1, sb.indexOf("a", 5));
877 
878         assertEquals(-1, sb.indexOf("abcdef", 0));
879         assertEquals(0, sb.indexOf("", 0));
880         assertEquals(1, sb.indexOf("", 1));
881 
882         //should work like String#indexOf
883         assertEquals ("abab".indexOf("a", 1), sb.indexOf("a", 1));
884 
885         assertEquals(2, sb.indexOf("ab", 1));
886         //should work like String#indexOf
887         assertEquals("abab".indexOf("ab", 1), sb.indexOf("ab", 1));
888 
889         assertEquals(3, sb.indexOf("b", 2));
890         assertEquals("abab".indexOf("b", 2), sb.indexOf("b", 2));
891 
892         assertEquals(1, sb.indexOf("ba", 1));
893         assertEquals("abab".indexOf("ba", 2), sb.indexOf("ba", 2));
894 
895         assertEquals(-1, sb.indexOf("z", 2));
896 
897         sb = new StrBuilder("xyzabc");
898         assertEquals(2, sb.indexOf("za", 0));
899         assertEquals(-1, sb.indexOf("za", 3));
900 
901         assertEquals(-1, sb.indexOf((String) null, 2));
902     }
903 
904     @Test
905     void testIndexOf_StrMatcher() {
906         final StrBuilder sb = new StrBuilder();
907         assertEquals(-1, sb.indexOf((StrMatcher) null));
908         assertEquals(-1, sb.indexOf(StrMatcher.charMatcher('a')));
909 
910         sb.append("ab bd");
911         assertEquals(0, sb.indexOf(StrMatcher.charMatcher('a')));
912         assertEquals(1, sb.indexOf(StrMatcher.charMatcher('b')));
913         assertEquals(2, sb.indexOf(StrMatcher.spaceMatcher()));
914         assertEquals(4, sb.indexOf(StrMatcher.charMatcher('d')));
915         assertEquals(-1, sb.indexOf(StrMatcher.noneMatcher()));
916         assertEquals(-1, sb.indexOf((StrMatcher) null));
917 
918         sb.append(" A1 junction");
919         assertEquals(6, sb.indexOf(A_NUMBER_MATCHER));
920     }
921 
922     @Test
923     void testIndexOf_StrMatcher_int() {
924         final StrBuilder sb = new StrBuilder();
925         assertEquals(-1, sb.indexOf((StrMatcher) null, 2));
926         assertEquals(-1, sb.indexOf(StrMatcher.charMatcher('a'), 2));
927         assertEquals(-1, sb.indexOf(StrMatcher.charMatcher('a'), 0));
928 
929         sb.append("ab bd");
930         assertEquals(0, sb.indexOf(StrMatcher.charMatcher('a'), -2));
931         assertEquals(0, sb.indexOf(StrMatcher.charMatcher('a'), 0));
932         assertEquals(-1, sb.indexOf(StrMatcher.charMatcher('a'), 2));
933         assertEquals(-1, sb.indexOf(StrMatcher.charMatcher('a'), 20));
934 
935         assertEquals(1, sb.indexOf(StrMatcher.charMatcher('b'), -1));
936         assertEquals(1, sb.indexOf(StrMatcher.charMatcher('b'), 0));
937         assertEquals(1, sb.indexOf(StrMatcher.charMatcher('b'), 1));
938         assertEquals(3, sb.indexOf(StrMatcher.charMatcher('b'), 2));
939         assertEquals(3, sb.indexOf(StrMatcher.charMatcher('b'), 3));
940         assertEquals(-1, sb.indexOf(StrMatcher.charMatcher('b'), 4));
941         assertEquals(-1, sb.indexOf(StrMatcher.charMatcher('b'), 5));
942         assertEquals(-1, sb.indexOf(StrMatcher.charMatcher('b'), 6));
943 
944         assertEquals(2, sb.indexOf(StrMatcher.spaceMatcher(), -2));
945         assertEquals(2, sb.indexOf(StrMatcher.spaceMatcher(), 0));
946         assertEquals(2, sb.indexOf(StrMatcher.spaceMatcher(), 2));
947         assertEquals(-1, sb.indexOf(StrMatcher.spaceMatcher(), 4));
948         assertEquals(-1, sb.indexOf(StrMatcher.spaceMatcher(), 20));
949 
950         assertEquals(-1, sb.indexOf(StrMatcher.noneMatcher(), 0));
951         assertEquals(-1, sb.indexOf((StrMatcher) null, 0));
952 
953         sb.append(" A1 junction with A2");
954         assertEquals(6, sb.indexOf(A_NUMBER_MATCHER, 5));
955         assertEquals(6, sb.indexOf(A_NUMBER_MATCHER, 6));
956         assertEquals(23, sb.indexOf(A_NUMBER_MATCHER, 7));
957         assertEquals(23, sb.indexOf(A_NUMBER_MATCHER, 22));
958         assertEquals(23, sb.indexOf(A_NUMBER_MATCHER, 23));
959         assertEquals(-1, sb.indexOf(A_NUMBER_MATCHER, 24));
960     }
961 
962     @Test
963     void testIndexOfLang294() {
964         final StrBuilder sb = new StrBuilder("onetwothree");
965         sb.deleteFirst("three");
966         assertEquals(-1, sb.indexOf("three"));
967     }
968 
969     @Test
970     void testIsEmpty() {
971         final StrBuilder sb = new StrBuilder();
972         assertTrue(sb.isEmpty());
973 
974         sb.append("Hello");
975         assertFalse(sb.isEmpty());
976 
977         sb.clear();
978         assertTrue(sb.isEmpty());
979     }
980 
981     @Test
982     void testLang294() {
983         final StrBuilder sb = new StrBuilder("\n%BLAH%\nDo more stuff\neven more stuff\n%BLAH%\n");
984         sb.deleteAll("\n%BLAH%");
985         assertEquals("\nDo more stuff\neven more stuff\n", sb.toString());
986     }
987 
988     @Test
989     void testLang295() {
990         final StrBuilder sb = new StrBuilder("onetwothree");
991         sb.deleteFirst("three");
992         assertFalse(sb.contains('h'), "The contains(char) method is looking beyond the end of the string");
993         assertEquals(-1, sb.indexOf('h'), "The indexOf(char) method is looking beyond the end of the string");
994     }
995 
996     @Test
997     void testLang412Left() {
998         final StrBuilder sb = new StrBuilder();
999         sb.appendFixedWidthPadLeft(null, 10, '*');
1000         assertEquals("**********", sb.toString(), "Failed to invoke appendFixedWidthPadLeft correctly");
1001     }
1002 
1003     @Test
1004     void testLang412Right() {
1005         final StrBuilder sb = new StrBuilder();
1006         sb.appendFixedWidthPadRight(null, 10, '*');
1007         assertEquals("**********", sb.toString(), "Failed to invoke appendFixedWidthPadRight correctly");
1008     }
1009 
1010     @Test
1011     void testLastIndexOf_char() {
1012         final StrBuilder sb = new StrBuilder("abab");
1013 
1014         assertEquals (2, sb.lastIndexOf('a'));
1015         //should work like String#lastIndexOf
1016         assertEquals ("abab".lastIndexOf('a'), sb.lastIndexOf('a'));
1017 
1018         assertEquals(3, sb.lastIndexOf('b'));
1019         assertEquals ("abab".lastIndexOf('b'), sb.lastIndexOf('b'));
1020 
1021         assertEquals (-1, sb.lastIndexOf('z'));
1022     }
1023 
1024     @Test
1025     void testLastIndexOf_char_int() {
1026         StrBuilder sb = new StrBuilder("abab");
1027         assertEquals(-1, sb.lastIndexOf('a', -1));
1028         assertEquals(0, sb.lastIndexOf('a', 0));
1029         assertEquals(0, sb.lastIndexOf('a', 1));
1030 
1031         // should work like String#lastIndexOf
1032         assertEquals("abab".lastIndexOf('a', 1), sb.lastIndexOf('a', 1));
1033 
1034         assertEquals(1, sb.lastIndexOf('b', 2));
1035         assertEquals("abab".lastIndexOf('b', 2), sb.lastIndexOf('b', 2));
1036 
1037         assertEquals(-1, sb.lastIndexOf('z', 2));
1038 
1039         sb = new StrBuilder("xyzabc");
1040         assertEquals(2, sb.lastIndexOf('z', sb.length()));
1041         assertEquals(-1, sb.lastIndexOf('z', 1));
1042     }
1043 
1044     @Test
1045     void testLastIndexOf_String() {
1046         final StrBuilder sb = new StrBuilder("abab");
1047 
1048         assertEquals(2, sb.lastIndexOf("a"));
1049         //should work like String#lastIndexOf
1050         assertEquals("abab".lastIndexOf("a"), sb.lastIndexOf("a"));
1051 
1052         assertEquals(2, sb.lastIndexOf("ab"));
1053         //should work like String#lastIndexOf
1054         assertEquals("abab".lastIndexOf("ab"), sb.lastIndexOf("ab"));
1055 
1056         assertEquals(3, sb.lastIndexOf("b"));
1057         assertEquals("abab".lastIndexOf("b"), sb.lastIndexOf("b"));
1058 
1059         assertEquals(1, sb.lastIndexOf("ba"));
1060         assertEquals("abab".lastIndexOf("ba"), sb.lastIndexOf("ba"));
1061 
1062         assertEquals(4, sb.lastIndexOf(""));
1063         //should work like String#lastIndexOf
1064         assertEquals("abab".lastIndexOf(""), sb.lastIndexOf(""));
1065         assertEquals("".lastIndexOf(""), new StrBuilder().lastIndexOf(""));
1066 
1067         assertEquals(-1, sb.lastIndexOf("z"));
1068 
1069         assertEquals(-1, sb.lastIndexOf((String) null));
1070     }
1071 
1072     @Test
1073     void testLastIndexOf_String_int() {
1074         StrBuilder sb = new StrBuilder("abab");
1075         assertEquals(-1, sb.lastIndexOf("a", -1));
1076         assertEquals(0, sb.lastIndexOf("a", 0));
1077         assertEquals(0, sb.lastIndexOf("a", 1));
1078         assertEquals(2, sb.lastIndexOf("a", 2));
1079         assertEquals(2, sb.lastIndexOf("a", 3));
1080         assertEquals(2, sb.lastIndexOf("a", 4));
1081         assertEquals(2, sb.lastIndexOf("a", 5));
1082 
1083         assertEquals(-1, sb.lastIndexOf("abcdef", 3));
1084         assertEquals("abab".lastIndexOf("", 3), sb.lastIndexOf("", 3));
1085         assertEquals("abab".lastIndexOf("", 1), sb.lastIndexOf("", 1));
1086 
1087         //should work like String#lastIndexOf
1088         assertEquals("abab".lastIndexOf("a", 1), sb.lastIndexOf("a", 1));
1089 
1090         assertEquals(0, sb.lastIndexOf("ab", 1));
1091         //should work like String#lastIndexOf
1092         assertEquals("abab".lastIndexOf("ab", 1), sb.lastIndexOf("ab", 1));
1093 
1094         assertEquals(1, sb.lastIndexOf("b", 2));
1095         assertEquals("abab".lastIndexOf("b", 2), sb.lastIndexOf("b", 2));
1096 
1097         assertEquals(1, sb.lastIndexOf("ba", 2));
1098         assertEquals("abab".lastIndexOf("ba", 2), sb.lastIndexOf("ba", 2));
1099 
1100         assertEquals(-1, sb.lastIndexOf("z", 2));
1101 
1102         sb = new StrBuilder("xyzabc");
1103         assertEquals(2, sb.lastIndexOf("za", sb.length()));
1104         assertEquals(-1, sb.lastIndexOf("za", 1));
1105 
1106         assertEquals(-1, sb.lastIndexOf((String) null, 2));
1107     }
1108 
1109     @Test
1110     void testLastIndexOf_StrMatcher() {
1111         final StrBuilder sb = new StrBuilder();
1112         assertEquals(-1, sb.lastIndexOf((StrMatcher) null));
1113         assertEquals(-1, sb.lastIndexOf(StrMatcher.charMatcher('a')));
1114 
1115         sb.append("ab bd");
1116         assertEquals(0, sb.lastIndexOf(StrMatcher.charMatcher('a')));
1117         assertEquals(3, sb.lastIndexOf(StrMatcher.charMatcher('b')));
1118         assertEquals(2, sb.lastIndexOf(StrMatcher.spaceMatcher()));
1119         assertEquals(4, sb.lastIndexOf(StrMatcher.charMatcher('d')));
1120         assertEquals(-1, sb.lastIndexOf(StrMatcher.noneMatcher()));
1121         assertEquals(-1, sb.lastIndexOf((StrMatcher) null));
1122 
1123         sb.append(" A1 junction");
1124         assertEquals(6, sb.lastIndexOf(A_NUMBER_MATCHER));
1125     }
1126 
1127     @Test
1128     void testLastIndexOf_StrMatcher_int() {
1129         final StrBuilder sb = new StrBuilder();
1130         assertEquals(-1, sb.lastIndexOf((StrMatcher) null, 2));
1131         assertEquals(-1, sb.lastIndexOf(StrMatcher.charMatcher('a'), 2));
1132         assertEquals(-1, sb.lastIndexOf(StrMatcher.charMatcher('a'), 0));
1133         assertEquals(-1, sb.lastIndexOf(StrMatcher.charMatcher('a'), -1));
1134 
1135         sb.append("ab bd");
1136         assertEquals(-1, sb.lastIndexOf(StrMatcher.charMatcher('a'), -2));
1137         assertEquals(0, sb.lastIndexOf(StrMatcher.charMatcher('a'), 0));
1138         assertEquals(0, sb.lastIndexOf(StrMatcher.charMatcher('a'), 2));
1139         assertEquals(0, sb.lastIndexOf(StrMatcher.charMatcher('a'), 20));
1140 
1141         assertEquals(-1, sb.lastIndexOf(StrMatcher.charMatcher('b'), -1));
1142         assertEquals(-1, sb.lastIndexOf(StrMatcher.charMatcher('b'), 0));
1143         assertEquals(1, sb.lastIndexOf(StrMatcher.charMatcher('b'), 1));
1144         assertEquals(1, sb.lastIndexOf(StrMatcher.charMatcher('b'), 2));
1145         assertEquals(3, sb.lastIndexOf(StrMatcher.charMatcher('b'), 3));
1146         assertEquals(3, sb.lastIndexOf(StrMatcher.charMatcher('b'), 4));
1147         assertEquals(3, sb.lastIndexOf(StrMatcher.charMatcher('b'), 5));
1148         assertEquals(3, sb.lastIndexOf(StrMatcher.charMatcher('b'), 6));
1149 
1150         assertEquals(-1, sb.lastIndexOf(StrMatcher.spaceMatcher(), -2));
1151         assertEquals(-1, sb.lastIndexOf(StrMatcher.spaceMatcher(), 0));
1152         assertEquals(2, sb.lastIndexOf(StrMatcher.spaceMatcher(), 2));
1153         assertEquals(2, sb.lastIndexOf(StrMatcher.spaceMatcher(), 4));
1154         assertEquals(2, sb.lastIndexOf(StrMatcher.spaceMatcher(), 20));
1155 
1156         assertEquals(-1, sb.lastIndexOf(StrMatcher.noneMatcher(), 0));
1157         assertEquals(-1, sb.lastIndexOf((StrMatcher) null, 0));
1158 
1159         sb.append(" A1 junction with A2");
1160         assertEquals(-1, sb.lastIndexOf(A_NUMBER_MATCHER, 5));
1161         assertEquals(-1, sb.lastIndexOf(A_NUMBER_MATCHER, 6)); // A matches, 1 is outside bounds
1162         assertEquals(6, sb.lastIndexOf(A_NUMBER_MATCHER, 7));
1163         assertEquals(6, sb.lastIndexOf(A_NUMBER_MATCHER, 22));
1164         assertEquals(6, sb.lastIndexOf(A_NUMBER_MATCHER, 23)); // A matches, 2 is outside bounds
1165         assertEquals(23, sb.lastIndexOf(A_NUMBER_MATCHER, 24));
1166     }
1167 
1168     @Test
1169     void testLeftString() {
1170         final StrBuilder sb = new StrBuilder("left right");
1171         assertEquals("left", sb.leftString(4));
1172         assertEquals("", sb.leftString(0));
1173         assertEquals("", sb.leftString(-5));
1174         assertEquals("left right", sb.leftString(15));
1175     }
1176 
1177     @Test
1178     void testLength() {
1179         final StrBuilder sb = new StrBuilder();
1180         assertEquals(0, sb.length());
1181 
1182         sb.append("Hello");
1183         assertEquals(5, sb.length());
1184     }
1185 
1186     @Test
1187     void testMidString() {
1188         final StrBuilder sb = new StrBuilder("hello goodbye hello");
1189         assertEquals("goodbye", sb.midString(6, 7));
1190         assertEquals("hello", sb.midString(0, 5));
1191         assertEquals("hello", sb.midString(-5, 5));
1192         assertEquals("", sb.midString(0, -1));
1193         assertEquals("", sb.midString(20, 2));
1194         assertEquals("hello", sb.midString(14, 22));
1195         // a length that overflows index + length must still return the rest
1196         assertEquals("hello", sb.midString(14, Integer.MAX_VALUE));
1197     }
1198 
1199     @Test
1200     void testMinimizeCapacity() {
1201         final StrBuilder sb = new StrBuilder();
1202         sb.minimizeCapacity();
1203         assertEquals(0, sb.capacity());
1204 
1205         sb.append("HelloWorld");
1206         sb.minimizeCapacity();
1207         assertEquals(10, sb.capacity());
1208     }
1209 
1210     @Test
1211     void testReadFromCharBuffer() throws Exception {
1212         String s = "";
1213         for (int i = 0; i < 100; ++i) {
1214             final StrBuilder sb = new StrBuilder();
1215             final int len = sb.readFrom(CharBuffer.wrap(s));
1216 
1217             assertEquals(s.length(), len);
1218             assertEquals(s, sb.toString());
1219 
1220             s += Integer.toString(i);
1221         }
1222     }
1223 
1224     @Test
1225     void testReadFromCharBufferAppendsToEnd() throws Exception {
1226         final StrBuilder sb = new StrBuilder("Test");
1227         sb.readFrom(CharBuffer.wrap(" 123"));
1228         assertEquals("Test 123", sb.toString());
1229     }
1230 
1231     @Test
1232     void testReadFromReadable() throws Exception {
1233         String s = "";
1234         for (int i = 0; i < 100; ++i) {
1235             final StrBuilder sb = new StrBuilder();
1236             final int len = sb.readFrom(new MockReadable(s));
1237 
1238             assertEquals(s.length(), len);
1239             assertEquals(s, sb.toString());
1240 
1241             s += Integer.toString(i);
1242         }
1243     }
1244 
1245     @Test
1246     void testReadFromReadableAppendsToEnd() throws Exception {
1247         final StrBuilder sb = new StrBuilder("Test");
1248         sb.readFrom(new MockReadable(" 123"));
1249         assertEquals("Test 123", sb.toString());
1250     }
1251 
1252     @Test
1253     void testReadFromReader() throws Exception {
1254         String s = "";
1255         for (int i = 0; i < 100; ++i) {
1256             final StrBuilder sb = new StrBuilder();
1257             final int len = sb.readFrom(new StringReader(s));
1258 
1259             assertEquals(s.length(), len);
1260             assertEquals(s, sb.toString());
1261 
1262             s += Integer.toString(i);
1263         }
1264     }
1265 
1266     @Test
1267     void testReadFromReaderAppendsToEnd() throws Exception {
1268         final StrBuilder sb = new StrBuilder("Test");
1269         sb.readFrom(new StringReader(" 123"));
1270         assertEquals("Test 123", sb.toString());
1271     }
1272 
1273     @Test
1274     void testReplace_int_int_String() {
1275         final StrBuilder sb = new StrBuilder("abc");
1276         sb.replace(0, 1, "d");
1277         assertEquals("dbc", sb.toString());
1278         sb.replace(0, 1, "aaa");
1279         assertEquals("aaabc", sb.toString());
1280         sb.replace(0, 3, "");
1281         assertEquals("bc", sb.toString());
1282         sb.replace(1, 2, null);
1283         assertEquals("b", sb.toString());
1284         sb.replace(1, 1000, "text");
1285         assertEquals("btext", sb.toString());
1286         sb.replace(0, 1000, "text");
1287         assertEquals("text", sb.toString());
1288 
1289         final StrBuilder sb1 = new StrBuilder("atext");
1290         sb1.replace(1, 1, "ny");
1291         assertEquals("anytext", sb1.toString());
1292         assertIndexOutOfBoundsException(() -> sb1.replace(2, 1, "anything"));
1293 
1294         final StrBuilder sb2 = new StrBuilder();
1295         assertIndexOutOfBoundsException(() -> sb2.replace(1, 2, "anything"));
1296         assertIndexOutOfBoundsException(() -> sb2.replace(-1, 1, "anything"));
1297     }
1298 
1299     @Test
1300     void testReplace_StrMatcher_String_int_int_int_VaryCount() {
1301         StrBuilder sb = new StrBuilder("aaxaaaayaa");
1302         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 10, -1);
1303         assertEquals("-x--y-", sb.toString());
1304 
1305         sb = new StrBuilder("aaxaaaayaa");
1306         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 10, 0);
1307         assertEquals("aaxaaaayaa", sb.toString());
1308 
1309         sb = new StrBuilder("aaxaaaayaa");
1310         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 10, 1);
1311         assertEquals("-xaaaayaa", sb.toString());
1312 
1313         sb = new StrBuilder("aaxaaaayaa");
1314         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 10, 2);
1315         assertEquals("-x-aayaa", sb.toString());
1316 
1317         sb = new StrBuilder("aaxaaaayaa");
1318         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 10, 3);
1319         assertEquals("-x--yaa", sb.toString());
1320 
1321         sb = new StrBuilder("aaxaaaayaa");
1322         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 10, 4);
1323         assertEquals("-x--y-", sb.toString());
1324 
1325         sb = new StrBuilder("aaxaaaayaa");
1326         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 10, 5);
1327         assertEquals("-x--y-", sb.toString());
1328     }
1329 
1330     @Test
1331     void testReplace_StrMatcher_String_int_int_int_VaryEndIndex() {
1332         StrBuilder sb = new StrBuilder("aaxaaaayaa");
1333         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 0, -1);
1334         assertEquals("aaxaaaayaa", sb.toString());
1335 
1336         sb = new StrBuilder("aaxaaaayaa");
1337         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 2, -1);
1338         assertEquals("-xaaaayaa", sb.toString());
1339 
1340         sb = new StrBuilder("aaxaaaayaa");
1341         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 3, -1);
1342         assertEquals("-xaaaayaa", sb.toString());
1343 
1344         sb = new StrBuilder("aaxaaaayaa");
1345         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 4, -1);
1346         assertEquals("-xaaaayaa", sb.toString());
1347 
1348         sb = new StrBuilder("aaxaaaayaa");
1349         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 5, -1);
1350         assertEquals("-x-aayaa", sb.toString());
1351 
1352         sb = new StrBuilder("aaxaaaayaa");
1353         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 6, -1);
1354         assertEquals("-x-aayaa", sb.toString());
1355 
1356         sb = new StrBuilder("aaxaaaayaa");
1357         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 7, -1);
1358         assertEquals("-x--yaa", sb.toString());
1359 
1360         sb = new StrBuilder("aaxaaaayaa");
1361         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 8, -1);
1362         assertEquals("-x--yaa", sb.toString());
1363 
1364         sb = new StrBuilder("aaxaaaayaa");
1365         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 9, -1);
1366         assertEquals("-x--yaa", sb.toString());
1367 
1368         sb = new StrBuilder("aaxaaaayaa");
1369         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 10, -1);
1370         assertEquals("-x--y-", sb.toString());
1371 
1372         sb = new StrBuilder("aaxaaaayaa");
1373         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, 1000, -1);
1374         assertEquals("-x--y-", sb.toString());
1375 
1376         final StrBuilder sb1 = new StrBuilder("aaxaaaayaa");
1377         assertIndexOutOfBoundsException(() -> sb1.replace(StrMatcher.stringMatcher("aa"), "-", 2, 1, -1));
1378         assertEquals("aaxaaaayaa", sb1.toString());
1379     }
1380 
1381     @Test
1382     void testReplace_StrMatcher_String_int_int_int_VaryMatcher() {
1383         StrBuilder sb = new StrBuilder("abcbccba");
1384         sb.replace(null, "x", 0, sb.length(), -1);
1385         assertEquals("abcbccba", sb.toString());
1386 
1387         sb.replace(StrMatcher.charMatcher('a'), "x", 0, sb.length(), -1);
1388         assertEquals("xbcbccbx", sb.toString());
1389 
1390         sb.replace(StrMatcher.stringMatcher("cb"), "x", 0, sb.length(), -1);
1391         assertEquals("xbxcxx", sb.toString());
1392 
1393         sb = new StrBuilder("A1-A2A3-A4");
1394         sb.replace(A_NUMBER_MATCHER, "***", 0, sb.length(), -1);
1395         assertEquals("***-******-***", sb.toString());
1396 
1397         sb = new StrBuilder();
1398         sb.replace(A_NUMBER_MATCHER, "***", 0, sb.length(), -1);
1399         assertEquals("", sb.toString());
1400     }
1401 
1402     @Test
1403     void testReplace_StrMatcher_String_int_int_int_VaryReplace() {
1404         StrBuilder sb = new StrBuilder("abcbccba");
1405         sb.replace(StrMatcher.stringMatcher("cb"), "cb", 0, sb.length(), -1);
1406         assertEquals("abcbccba", sb.toString());
1407 
1408         sb = new StrBuilder("abcbccba");
1409         sb.replace(StrMatcher.stringMatcher("cb"), "-", 0, sb.length(), -1);
1410         assertEquals("ab-c-a", sb.toString());
1411 
1412         sb = new StrBuilder("abcbccba");
1413         sb.replace(StrMatcher.stringMatcher("cb"), "+++", 0, sb.length(), -1);
1414         assertEquals("ab+++c+++a", sb.toString());
1415 
1416         sb = new StrBuilder("abcbccba");
1417         sb.replace(StrMatcher.stringMatcher("cb"), "", 0, sb.length(), -1);
1418         assertEquals("abca", sb.toString());
1419 
1420         sb = new StrBuilder("abcbccba");
1421         sb.replace(StrMatcher.stringMatcher("cb"), null, 0, sb.length(), -1);
1422         assertEquals("abca", sb.toString());
1423     }
1424 
1425     @Test
1426     void testReplace_StrMatcher_String_int_int_int_VaryStartIndex() {
1427         StrBuilder sb = new StrBuilder("aaxaaaayaa");
1428         sb.replace(StrMatcher.stringMatcher("aa"), "-", 0, sb.length(), -1);
1429         assertEquals("-x--y-", sb.toString());
1430 
1431         sb = new StrBuilder("aaxaaaayaa");
1432         sb.replace(StrMatcher.stringMatcher("aa"), "-", 1, sb.length(), -1);
1433         assertEquals("aax--y-", sb.toString());
1434 
1435         sb = new StrBuilder("aaxaaaayaa");
1436         sb.replace(StrMatcher.stringMatcher("aa"), "-", 2, sb.length(), -1);
1437         assertEquals("aax--y-", sb.toString());
1438 
1439         sb = new StrBuilder("aaxaaaayaa");
1440         sb.replace(StrMatcher.stringMatcher("aa"), "-", 3, sb.length(), -1);
1441         assertEquals("aax--y-", sb.toString());
1442 
1443         sb = new StrBuilder("aaxaaaayaa");
1444         sb.replace(StrMatcher.stringMatcher("aa"), "-", 4, sb.length(), -1);
1445         assertEquals("aaxa-ay-", sb.toString());
1446 
1447         sb = new StrBuilder("aaxaaaayaa");
1448         sb.replace(StrMatcher.stringMatcher("aa"), "-", 5, sb.length(), -1);
1449         assertEquals("aaxaa-y-", sb.toString());
1450 
1451         sb = new StrBuilder("aaxaaaayaa");
1452         sb.replace(StrMatcher.stringMatcher("aa"), "-", 6, sb.length(), -1);
1453         assertEquals("aaxaaaay-", sb.toString());
1454 
1455         sb = new StrBuilder("aaxaaaayaa");
1456         sb.replace(StrMatcher.stringMatcher("aa"), "-", 7, sb.length(), -1);
1457         assertEquals("aaxaaaay-", sb.toString());
1458 
1459         sb = new StrBuilder("aaxaaaayaa");
1460         sb.replace(StrMatcher.stringMatcher("aa"), "-", 8, sb.length(), -1);
1461         assertEquals("aaxaaaay-", sb.toString());
1462 
1463         sb = new StrBuilder("aaxaaaayaa");
1464         sb.replace(StrMatcher.stringMatcher("aa"), "-", 9, sb.length(), -1);
1465         assertEquals("aaxaaaayaa", sb.toString());
1466 
1467         sb = new StrBuilder("aaxaaaayaa");
1468         sb.replace(StrMatcher.stringMatcher("aa"), "-", 10, sb.length(), -1);
1469         assertEquals("aaxaaaayaa", sb.toString());
1470 
1471         final StrBuilder sb1 = new StrBuilder("aaxaaaayaa");
1472         assertIndexOutOfBoundsException(() -> sb1.replace(StrMatcher.stringMatcher("aa"), "-", 11, sb1.length(), -1));
1473         assertEquals("aaxaaaayaa", sb1.toString());
1474         final StrBuilder sb2 = new StrBuilder("aaxaaaayaa");
1475         assertIndexOutOfBoundsException(() -> sb2.replace(StrMatcher.stringMatcher("aa"), "-", -1, sb2.length(), -1));
1476         assertEquals("aaxaaaayaa", sb2.toString());
1477     }
1478 
1479     @Test
1480     void testReplaceAll_char_char() {
1481         final StrBuilder sb = new StrBuilder("abcbccba");
1482         sb.replaceAll('x', 'y');
1483         assertEquals("abcbccba", sb.toString());
1484         sb.replaceAll('a', 'd');
1485         assertEquals("dbcbccbd", sb.toString());
1486         sb.replaceAll('b', 'e');
1487         assertEquals("dececced", sb.toString());
1488         sb.replaceAll('c', 'f');
1489         assertEquals("defeffed", sb.toString());
1490         sb.replaceAll('d', 'd');
1491         assertEquals("defeffed", sb.toString());
1492     }
1493 
1494     @Test
1495     void testReplaceAll_String_String() {
1496         StrBuilder sb = new StrBuilder("abcbccba");
1497         sb.replaceAll((String) null, null);
1498         assertEquals("abcbccba", sb.toString());
1499         sb.replaceAll((String) null, "anything");
1500         assertEquals("abcbccba", sb.toString());
1501         sb.replaceAll("", null);
1502         assertEquals("abcbccba", sb.toString());
1503         sb.replaceAll("", "anything");
1504         assertEquals("abcbccba", sb.toString());
1505 
1506         sb.replaceAll("x", "y");
1507         assertEquals("abcbccba", sb.toString());
1508         sb.replaceAll("a", "d");
1509         assertEquals("dbcbccbd", sb.toString());
1510         sb.replaceAll("d", null);
1511         assertEquals("bcbccb", sb.toString());
1512         sb.replaceAll("cb", "-");
1513         assertEquals("b-c-", sb.toString());
1514 
1515         sb = new StrBuilder("abcba");
1516         sb.replaceAll("b", "xbx");
1517         assertEquals("axbxcxbxa", sb.toString());
1518 
1519         sb = new StrBuilder("bb");
1520         sb.replaceAll("b", "xbx");
1521         assertEquals("xbxxbx", sb.toString());
1522     }
1523 
1524     @Test
1525     void testReplaceAll_StrMatcher_String() {
1526         StrBuilder sb = new StrBuilder("abcbccba");
1527         sb.replaceAll((StrMatcher) null, null);
1528         assertEquals("abcbccba", sb.toString());
1529         sb.replaceAll((StrMatcher) null, "anything");
1530         assertEquals("abcbccba", sb.toString());
1531         sb.replaceAll(StrMatcher.noneMatcher(), null);
1532         assertEquals("abcbccba", sb.toString());
1533         sb.replaceAll(StrMatcher.noneMatcher(), "anything");
1534         assertEquals("abcbccba", sb.toString());
1535 
1536         sb.replaceAll(StrMatcher.charMatcher('x'), "y");
1537         assertEquals("abcbccba", sb.toString());
1538         sb.replaceAll(StrMatcher.charMatcher('a'), "d");
1539         assertEquals("dbcbccbd", sb.toString());
1540         sb.replaceAll(StrMatcher.charMatcher('d'), null);
1541         assertEquals("bcbccb", sb.toString());
1542         sb.replaceAll(StrMatcher.stringMatcher("cb"), "-");
1543         assertEquals("b-c-", sb.toString());
1544 
1545         sb = new StrBuilder("abcba");
1546         sb.replaceAll(StrMatcher.charMatcher('b'), "xbx");
1547         assertEquals("axbxcxbxa", sb.toString());
1548 
1549         sb = new StrBuilder("bb");
1550         sb.replaceAll(StrMatcher.charMatcher('b'), "xbx");
1551         assertEquals("xbxxbx", sb.toString());
1552 
1553         sb = new StrBuilder("A1-A2A3-A4");
1554         sb.replaceAll(A_NUMBER_MATCHER, "***");
1555         assertEquals("***-******-***", sb.toString());
1556 
1557         sb = new StrBuilder("Dear X, hello X.");
1558         sb.replaceAll(StrMatcher.stringMatcher("X"), "012345678901234567");
1559         assertEquals("Dear 012345678901234567, hello 012345678901234567.", sb.toString());
1560     }
1561 
1562     @Test
1563     void testReplaceFirst_char_char() {
1564         final StrBuilder sb = new StrBuilder("abcbccba");
1565         sb.replaceFirst('x', 'y');
1566         assertEquals("abcbccba", sb.toString());
1567         sb.replaceFirst('a', 'd');
1568         assertEquals("dbcbccba", sb.toString());
1569         sb.replaceFirst('b', 'e');
1570         assertEquals("decbccba", sb.toString());
1571         sb.replaceFirst('c', 'f');
1572         assertEquals("defbccba", sb.toString());
1573         sb.replaceFirst('d', 'd');
1574         assertEquals("defbccba", sb.toString());
1575     }
1576 
1577     @Test
1578     void testReplaceFirst_String_String() {
1579         StrBuilder sb = new StrBuilder("abcbccba");
1580         sb.replaceFirst((String) null, null);
1581         assertEquals("abcbccba", sb.toString());
1582         sb.replaceFirst((String) null, "anything");
1583         assertEquals("abcbccba", sb.toString());
1584         sb.replaceFirst("", null);
1585         assertEquals("abcbccba", sb.toString());
1586         sb.replaceFirst("", "anything");
1587         assertEquals("abcbccba", sb.toString());
1588 
1589         sb.replaceFirst("x", "y");
1590         assertEquals("abcbccba", sb.toString());
1591         sb.replaceFirst("a", "d");
1592         assertEquals("dbcbccba", sb.toString());
1593         sb.replaceFirst("d", null);
1594         assertEquals("bcbccba", sb.toString());
1595         sb.replaceFirst("cb", "-");
1596         assertEquals("b-ccba", sb.toString());
1597 
1598         sb = new StrBuilder("abcba");
1599         sb.replaceFirst("b", "xbx");
1600         assertEquals("axbxcba", sb.toString());
1601 
1602         sb = new StrBuilder("bb");
1603         sb.replaceFirst("b", "xbx");
1604         assertEquals("xbxb", sb.toString());
1605     }
1606 
1607     @Test
1608     void testReplaceFirst_StrMatcher_String() {
1609         StrBuilder sb = new StrBuilder("abcbccba");
1610         sb.replaceFirst((StrMatcher) null, null);
1611         assertEquals("abcbccba", sb.toString());
1612         sb.replaceFirst((StrMatcher) null, "anything");
1613         assertEquals("abcbccba", sb.toString());
1614         sb.replaceFirst(StrMatcher.noneMatcher(), null);
1615         assertEquals("abcbccba", sb.toString());
1616         sb.replaceFirst(StrMatcher.noneMatcher(), "anything");
1617         assertEquals("abcbccba", sb.toString());
1618 
1619         sb.replaceFirst(StrMatcher.charMatcher('x'), "y");
1620         assertEquals("abcbccba", sb.toString());
1621         sb.replaceFirst(StrMatcher.charMatcher('a'), "d");
1622         assertEquals("dbcbccba", sb.toString());
1623         sb.replaceFirst(StrMatcher.charMatcher('d'), null);
1624         assertEquals("bcbccba", sb.toString());
1625         sb.replaceFirst(StrMatcher.stringMatcher("cb"), "-");
1626         assertEquals("b-ccba", sb.toString());
1627 
1628         sb = new StrBuilder("abcba");
1629         sb.replaceFirst(StrMatcher.charMatcher('b'), "xbx");
1630         assertEquals("axbxcba", sb.toString());
1631 
1632         sb = new StrBuilder("bb");
1633         sb.replaceFirst(StrMatcher.charMatcher('b'), "xbx");
1634         assertEquals("xbxb", sb.toString());
1635 
1636         sb = new StrBuilder("A1-A2A3-A4");
1637         sb.replaceFirst(A_NUMBER_MATCHER, "***");
1638         assertEquals("***-A2A3-A4", sb.toString());
1639     }
1640 
1641     @Test
1642     void testReverse() {
1643         final StrBuilder sb = new StrBuilder();
1644         assertEquals("", sb.reverse().toString());
1645 
1646         sb.clear().append(true);
1647         assertEquals("eurt", sb.reverse().toString());
1648         assertEquals("true", sb.reverse().toString());
1649     }
1650 
1651     @Test
1652     void testReverseSurrogatePairs() {
1653         // U+1F600 GRINNING FACE is a supplementary code point encoded as a surrogate pair; reversing
1654         // must keep the pair intact (high before low) like StringBuilder, not split it into garbage.
1655         final String emoji = "😀";
1656         assertEquals(new StringBuilder("a" + emoji + "b").reverse().toString(), new StrBuilder("a" + emoji + "b").reverse().toString());
1657         assertEquals("b" + emoji + "a", new StrBuilder("a" + emoji + "b").reverse().toString());
1658 
1659         final String emoji2 = "😁";
1660         assertEquals(emoji2 + emoji, new StrBuilder(emoji + emoji2).reverse().toString());
1661 
1662         // An unpaired high surrogate has no partner and is left where it lands.
1663         assertEquals("b\uD800a", new StrBuilder("a\uD800b").reverse().toString());
1664     }
1665 
1666     @Test
1667     void testRightString() {
1668         final StrBuilder sb = new StrBuilder("left right");
1669         assertEquals("right", sb.rightString(5));
1670         assertEquals("", sb.rightString(0));
1671         assertEquals("", sb.rightString(-5));
1672         assertEquals("left right", sb.rightString(15));
1673     }
1674 
1675     @Test
1676     void testSetCharAt() {
1677         final StrBuilder sb = new StrBuilder();
1678         assertIndexOutOfBoundsException(() -> sb.setCharAt(0, 'f'), "setCharAt(0, ) expected IndexOutOfBoundsException");
1679         assertIndexOutOfBoundsException(() -> sb.setCharAt(-1, 'f'), "setCharAt(-1, ) expected IndexOutOfBoundsException");
1680         sb.append("foo");
1681         sb.setCharAt(0, 'b');
1682         sb.setCharAt(1, 'a');
1683         sb.setCharAt(2, 'r');
1684         assertIndexOutOfBoundsException(() -> sb.setCharAt(3, '!'), "setCharAt(3, ) expected IndexOutOfBoundsException");
1685         assertEquals("bar", sb.toString());
1686     }
1687 
1688     @Test
1689     void testSetLength() {
1690         final StrBuilder sb = new StrBuilder();
1691         sb.append("Hello");
1692         sb.setLength(2); // shorten
1693         assertEquals("He", sb.toString());
1694         sb.setLength(2); // no change
1695         assertEquals("He", sb.toString());
1696         sb.setLength(3); // lengthen
1697         assertEquals("He\0", sb.toString());
1698         assertIndexOutOfBoundsException(() -> sb.setLength(-1), "setLength(-1) expected StringIndexOutOfBoundsException");
1699     }
1700 
1701     @Test
1702     void testSize() {
1703         final StrBuilder sb = new StrBuilder();
1704         assertEquals(0, sb.size());
1705 
1706         sb.append("Hello");
1707         assertEquals(5, sb.size());
1708     }
1709 
1710     @Test
1711     void testStartsWith() {
1712         final StrBuilder sb = new StrBuilder();
1713         assertFalse(sb.startsWith("a"));
1714         assertFalse(sb.startsWith(null));
1715         assertTrue(sb.startsWith(""));
1716         sb.append("abc");
1717         assertTrue(sb.startsWith("a"));
1718         assertTrue(sb.startsWith("ab"));
1719         assertTrue(sb.startsWith("abc"));
1720         assertFalse(sb.startsWith("cba"));
1721     }
1722 
1723     @Test
1724     void testSubSequenceIntInt() {
1725        final StrBuilder sb = new StrBuilder ("hello goodbye");
1726        // Start index is negative
1727         assertIndexOutOfBoundsException(() -> sb.subSequence(-1, 5));
1728 
1729         // End index is negative
1730         assertIndexOutOfBoundsException(() -> sb.subSequence(2, -1));
1731 
1732         // End index greater than length()
1733         assertIndexOutOfBoundsException(() -> sb.subSequence(2, sb.length() + 1));
1734 
1735         // Start index greater than end index
1736         assertIndexOutOfBoundsException(() -> sb.subSequence(3, 2));
1737 
1738         // Normal cases
1739         assertEquals ("hello", sb.subSequence(0, 5));
1740         assertEquals ("hello goodbye".subSequence(0, 6), sb.subSequence(0, 6));
1741         assertEquals ("goodbye", sb.subSequence(6, 13));
1742         assertEquals ("hello goodbye".subSequence(6, 13), sb.subSequence(6, 13));
1743     }
1744 
1745     @Test
1746     void testSubstringInt() {
1747         final StrBuilder sb = new StrBuilder ("hello goodbye");
1748         assertEquals ("goodbye", sb.substring(6));
1749         assertEquals ("hello goodbye".substring(6), sb.substring(6));
1750         assertEquals ("hello goodbye", sb.substring(0));
1751         assertEquals ("hello goodbye".substring(0), sb.substring(0));
1752         assertIndexOutOfBoundsException(() -> sb.substring(-1));
1753 
1754         assertIndexOutOfBoundsException(() -> sb.substring(15));
1755     }
1756 
1757     @Test
1758     void testSubstringIntInt() {
1759         final StrBuilder sb = new StrBuilder ("hello goodbye");
1760         assertEquals ("hello", sb.substring(0, 5));
1761         assertEquals ("hello goodbye".substring(0, 6), sb.substring(0, 6));
1762 
1763         assertEquals ("goodbye", sb.substring(6, 13));
1764         assertEquals ("hello goodbye".substring(6, 13), sb.substring(6, 13));
1765 
1766         assertEquals ("goodbye", sb.substring(6, 20));
1767 
1768         assertIndexOutOfBoundsException(() -> sb.substring(-1, 5));
1769         assertIndexOutOfBoundsException(() -> sb.substring(15, 20));
1770     }
1771 
1772     @Test
1773     void testToCharArray() {
1774         final StrBuilder sb = new StrBuilder();
1775         assertEquals(ArrayUtils.EMPTY_CHAR_ARRAY, sb.toCharArray());
1776 
1777         char[] a = sb.toCharArray();
1778         assertNotNull(a, "toCharArray() result is null");
1779         assertEquals(0, a.length, "toCharArray() result is too large");
1780 
1781         sb.append("junit");
1782         a = sb.toCharArray();
1783         assertEquals(5, a.length, "toCharArray() result incorrect length");
1784         assertArrayEquals("junit".toCharArray(), a, "toCharArray() result does not match");
1785     }
1786 
1787     @Test
1788     void testToCharArrayIntInt() {
1789         final StrBuilder sb = new StrBuilder();
1790         assertEquals(ArrayUtils.EMPTY_CHAR_ARRAY, sb.toCharArray(0, 0));
1791 
1792         sb.append("junit");
1793         char[] a = sb.toCharArray(0, 20); // too large test
1794         assertEquals(5, a.length, "toCharArray(int, int) result incorrect length");
1795         assertArrayEquals("junit".toCharArray(), a, "toCharArray(int, int) result does not match");
1796 
1797         a = sb.toCharArray(0, 4);
1798         assertEquals(4, a.length, "toCharArray(int, int) result incorrect length");
1799         assertArrayEquals("juni".toCharArray(), a, "toCharArray(int, int) result does not match");
1800 
1801         a = sb.toCharArray(0, 4);
1802         assertEquals(4, a.length, "toCharArray(int, int) result incorrect length");
1803         assertArrayEquals("juni".toCharArray(), a, "toCharArray(int, int) result does not match");
1804 
1805         a = sb.toCharArray(0, 1);
1806         assertNotNull(a, "toCharArray(int, int) result is null");
1807 
1808         assertIndexOutOfBoundsException(() -> sb.toCharArray(-1, 5), "no string index out of bound on -1");
1809         assertIndexOutOfBoundsException(() -> sb.toCharArray(6, 5), "no string index out of bound on -1");
1810     }
1811 
1812     @Test
1813     void testToString() {
1814         final StrBuilder sb = new StrBuilder("abc");
1815         assertEquals("abc", sb.toString());
1816     }
1817 
1818     @Test
1819     void testToStringBuffer() {
1820         final StrBuilder sb = new StrBuilder();
1821         assertEquals(new StringBuffer().toString(), sb.toStringBuffer().toString());
1822 
1823         sb.append("junit");
1824         assertEquals(new StringBuffer("junit").toString(), sb.toStringBuffer().toString());
1825     }
1826 
1827     @Test
1828     void testToStringBuilder() {
1829         final StrBuilder sb = new StrBuilder();
1830         assertEquals(new StringBuilder().toString(), sb.toStringBuilder().toString());
1831 
1832         sb.append("junit");
1833         assertEquals(new StringBuilder("junit").toString(), sb.toStringBuilder().toString());
1834     }
1835 
1836     @Test
1837     void testTrim() {
1838         final StrBuilder sb = new StrBuilder();
1839         assertEquals("", sb.reverse().toString());
1840 
1841         sb.clear().append(" \u0000 ");
1842         assertEquals("", sb.trim().toString());
1843 
1844         sb.clear().append(" \u0000 a b c");
1845         assertEquals("a b c", sb.trim().toString());
1846 
1847         sb.clear().append("a b c \u0000 ");
1848         assertEquals("a b c", sb.trim().toString());
1849 
1850         sb.clear().append(" \u0000 a b c \u0000 ");
1851         assertEquals("a b c", sb.trim().toString());
1852 
1853         sb.clear().append("a b c");
1854         assertEquals("a b c", sb.trim().toString());
1855     }
1856 }