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