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.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.mockito.ArgumentMatchers.any;
23  import static org.mockito.ArgumentMatchers.anyInt;
24  import static org.mockito.ArgumentMatchers.anyString;
25  import static org.mockito.Mockito.spy;
26  import static org.mockito.Mockito.times;
27  import static org.mockito.Mockito.verify;
28  
29  import java.text.DecimalFormatSymbols;
30  import java.util.Arrays;
31  import java.util.Collection;
32  import java.util.Collections;
33  import java.util.Iterator;
34  
35  import org.apache.commons.lang3.ArrayUtils;
36  import org.junit.jupiter.api.Test;
37  
38  /**
39   * Tests {@link TextStringBuilder}.
40   */
41  class TextStringBuilderAppendInsertTest {
42  
43      /** The system line separator. */
44      private static final String SEP = System.lineSeparator();
45  
46      /** Test subclass of Object, with a toString method. */
47      private static final Object FOO = new Object() {
48          @Override
49          public String toString() {
50              return "foo";
51          }
52      };
53  
54      @Test
55      void testAppend_Boolean() {
56          final TextStringBuilder sb = new TextStringBuilder();
57          sb.append(true);
58          assertEquals("true", sb.toString());
59  
60          sb.append(false);
61          assertEquals("truefalse", sb.toString());
62  
63          sb.append('!');
64          assertEquals("truefalse!", sb.toString());
65      }
66  
67      @Test
68      void testAppend_CharArray() {
69          TextStringBuilder sb = new TextStringBuilder();
70          sb.setNullText("NULL").append((char[]) null);
71          assertEquals("NULL", sb.toString());
72  
73          sb = new TextStringBuilder();
74          sb.append(ArrayUtils.EMPTY_CHAR_ARRAY);
75          assertEquals("", sb.toString());
76  
77          sb.append(new char[] {'f', 'o', 'o'});
78          assertEquals("foo", sb.toString());
79      }
80  
81      @Test
82      void testAppend_CharArray_int_int() {
83          final TextStringBuilder sb0 = new TextStringBuilder();
84          sb0.setNullText("NULL").append((char[]) null, 0, 1);
85          assertEquals("NULL", sb0.toString());
86  
87          final TextStringBuilder sb = new TextStringBuilder();
88          sb.append(new char[] {'f', 'o', 'o'}, 0, 3);
89          assertEquals("foo", sb.toString());
90  
91          assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new char[] {'b', 'a', 'r'}, -1, 1),
92              "append(char[], -1,) expected IndexOutOfBoundsException");
93  
94          assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new char[] {'b', 'a', 'r'}, 3, 1),
95              "append(char[], 3,) expected IndexOutOfBoundsException");
96  
97          assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new char[] {'b', 'a', 'r'}, 1, -1),
98              "append(char[],, -1) expected IndexOutOfBoundsException");
99  
100         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new char[] {'b', 'a', 'r'}, 1, 3),
101             "append(char[], 1, 3) expected IndexOutOfBoundsException");
102 
103         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new char[] {'b', 'a', 'r'}, -1, 3),
104             "append(char[], -1, 3) expected IndexOutOfBoundsException");
105 
106         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new char[] {'b', 'a', 'r'}, 4, 0),
107             "append(char[], 4, 0) expected IndexOutOfBoundsException");
108 
109         sb.append(new char[] {'b', 'a', 'r'}, 3, 0);
110         assertEquals("foo", sb.toString());
111 
112         sb.append(new char[] {'a', 'b', 'c', 'b', 'a', 'r', 'd', 'e', 'f'}, 3, 3);
113         assertEquals("foobar", sb.toString());
114     }
115 
116     @Test
117     void testAppend_FormattedString() {
118         TextStringBuilder sb;
119 
120         sb = new TextStringBuilder();
121         sb.append("Hi", (Object[]) null);
122         assertEquals("Hi", sb.toString());
123 
124         sb = new TextStringBuilder();
125         sb.append("Hi", "Alice");
126         assertEquals("Hi", sb.toString());
127 
128         sb = new TextStringBuilder();
129         sb.append("Hi %s", "Alice");
130         assertEquals("Hi Alice", sb.toString());
131 
132         sb = new TextStringBuilder();
133         sb.append("Hi %s %,d", "Alice", 5000);
134         // group separator depends on system locale
135         final char groupingSeparator = DecimalFormatSymbols.getInstance().getGroupingSeparator();
136         final String expected = "Hi Alice 5" + groupingSeparator + "000";
137         assertEquals(expected, sb.toString());
138     }
139 
140     @Test
141     void testAppend_Object() {
142         final TextStringBuilder sb = new TextStringBuilder();
143         sb.appendNull();
144         assertEquals("", sb.toString());
145 
146         sb.append((Object) null);
147         assertEquals("", sb.toString());
148 
149         sb.append(FOO);
150         assertEquals("foo", sb.toString());
151 
152         sb.append((StringBuffer) null);
153         assertEquals("foo", sb.toString());
154 
155         sb.append(new StringBuffer("baz"));
156         assertEquals("foobaz", sb.toString());
157 
158         sb.append(new TextStringBuilder("yes"));
159         assertEquals("foobazyes", sb.toString());
160 
161         sb.append((CharSequence) "Seq");
162         assertEquals("foobazyesSeq", sb.toString());
163 
164         sb.append(new StringBuilder("bld")); // Check it supports StringBuilder
165         assertEquals("foobazyesSeqbld", sb.toString());
166     }
167 
168     @Test
169     void testAppend_PrimitiveNumber() {
170         final TextStringBuilder sb = new TextStringBuilder();
171         sb.append(0);
172         assertEquals("0", sb.toString());
173 
174         sb.append(1L);
175         assertEquals("01", sb.toString());
176 
177         sb.append(2.3f);
178         assertEquals("012.3", sb.toString());
179 
180         sb.append(4.5d);
181         assertEquals("012.34.5", sb.toString());
182     }
183 
184     @Test
185     void testAppend_String() {
186         TextStringBuilder sb = new TextStringBuilder();
187         sb.setNullText("NULL").append((String) null);
188         assertEquals("NULL", sb.toString());
189 
190         sb = new TextStringBuilder();
191         sb.append("foo");
192         assertEquals("foo", sb.toString());
193 
194         sb.append("");
195         assertEquals("foo", sb.toString());
196 
197         sb.append("bar");
198         assertEquals("foobar", sb.toString());
199     }
200 
201     @Test
202     void testAppend_String_int_int() {
203         final TextStringBuilder sb0 = new TextStringBuilder();
204         sb0.setNullText("NULL").append((String) null, 0, 1);
205         assertEquals("NULL", sb0.toString());
206 
207         final TextStringBuilder sb = new TextStringBuilder();
208         sb.append("foo", 0, 3);
209         assertEquals("foo", sb.toString());
210         assertThrows(IndexOutOfBoundsException.class, () -> sb.append("bar", -1, 1), "append(char[], -1,) expected IndexOutOfBoundsException");
211         assertThrows(IndexOutOfBoundsException.class, () -> sb.append("bar", 3, 1), "append(char[], 3,) expected IndexOutOfBoundsException");
212         assertThrows(IndexOutOfBoundsException.class, () -> sb.append("bar", 1, -1), "append(char[],, -1) expected IndexOutOfBoundsException");
213         assertThrows(IndexOutOfBoundsException.class, () -> sb.append("bar", 1, 3), "append(char[], 1, 3) expected IndexOutOfBoundsException");
214         assertThrows(IndexOutOfBoundsException.class, () -> sb.append("bar", -1, 3), "append(char[], -1, 3) expected IndexOutOfBoundsException");
215         assertThrows(IndexOutOfBoundsException.class, () -> sb.append("bar", 4, 0), "append(char[], 4, 0) expected IndexOutOfBoundsException");
216         assertThrows(IndexOutOfBoundsException.class, () -> sb.append((CharSequence) "bar", 2, 1), "append(char[], 2, 1) expected IndexOutOfBoundsException");
217         assertThrows(IndexOutOfBoundsException.class, () -> sb.append((CharSequence) "bar", 2, 2), "append(char[], 2, 2) expected IndexOutOfBoundsException");
218         assertThrows(IndexOutOfBoundsException.class, () -> sb.append((CharSequence) "bar", 2, -2), "append(char[], 2, -2) expected IndexOutOfBoundsException");
219         assertThrows(IndexOutOfBoundsException.class, () -> sb.append((CharSequence) "bar", 2, 0), "append(char[], 2, 0) expected IndexOutOfBoundsException");
220 
221         sb.append("bar", 3, 0);
222         assertEquals("foo", sb.toString());
223 
224         sb.append("abcbardef", 3, 3);
225         assertEquals("foobar", sb.toString());
226 
227         sb.append((CharSequence) "abcbardef", 4, 7);
228         assertEquals("foobarard", sb.toString());
229     }
230 
231     @Test
232     void testAppend_StringBuffer() {
233         TextStringBuilder sb = new TextStringBuilder();
234         sb.setNullText("NULL").append((StringBuffer) null);
235         assertEquals("NULL", sb.toString());
236 
237         sb = new TextStringBuilder();
238         sb.append(new StringBuffer("foo"));
239         assertEquals("foo", sb.toString());
240 
241         sb.append(new StringBuffer(""));
242         assertEquals("foo", sb.toString());
243 
244         sb.append(new StringBuffer("bar"));
245         assertEquals("foobar", sb.toString());
246     }
247 
248     @Test
249     void testAppend_StringBuffer_int_int() {
250         final TextStringBuilder sb0 = new TextStringBuilder();
251         sb0.setNullText("NULL").append((StringBuffer) null, 0, 1);
252         assertEquals("NULL", sb0.toString());
253 
254         final TextStringBuilder sb = new TextStringBuilder();
255         sb.append(new StringBuffer("foo"), 0, 3);
256         assertEquals("foo", sb.toString());
257 
258         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuffer("bar"), -1, 1),
259             "append(char[], -1,) expected IndexOutOfBoundsException");
260 
261         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuffer("bar"), 3, 1), "append(char[], 3,) expected IndexOutOfBoundsException");
262 
263         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuffer("bar"), 1, -1),
264             "append(char[],, -1) expected IndexOutOfBoundsException");
265 
266         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuffer("bar"), 1, 3),
267             "append(char[], 1, 3) expected IndexOutOfBoundsException");
268 
269         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuffer("bar"), -1, 3),
270             "append(char[], -1, 3) expected IndexOutOfBoundsException");
271 
272         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuffer("bar"), 4, 0),
273             "append(char[], 4, 0) expected IndexOutOfBoundsException");
274 
275         sb.append(new StringBuffer("bar"), 3, 0);
276         assertEquals("foo", sb.toString());
277 
278         sb.append(new StringBuffer("abcbardef"), 3, 3);
279         assertEquals("foobar", sb.toString());
280     }
281 
282     @Test
283     void testAppend_StringBuilder() {
284         TextStringBuilder sb = new TextStringBuilder();
285         sb.setNullText("NULL").append((String) null);
286         assertEquals("NULL", sb.toString());
287 
288         sb = new TextStringBuilder();
289         sb.append(new StringBuilder("foo"));
290         assertEquals("foo", sb.toString());
291 
292         sb.append(new StringBuilder(""));
293         assertEquals("foo", sb.toString());
294 
295         sb.append(new StringBuilder("bar"));
296         assertEquals("foobar", sb.toString());
297     }
298 
299     @Test
300     void testAppend_StringBuilder_int_int() {
301         final TextStringBuilder sb0 = new TextStringBuilder();
302         sb0.setNullText("NULL").append((String) null, 0, 1);
303         assertEquals("NULL", sb0.toString());
304 
305         final TextStringBuilder sb = new TextStringBuilder();
306         sb.append(new StringBuilder("foo"), 0, 3);
307         assertEquals("foo", sb.toString());
308 
309         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuilder("bar"), -1, 1),
310             "append(StringBuilder, -1,) expected IndexOutOfBoundsException");
311 
312         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuilder("bar"), 3, 1),
313             "append(StringBuilder, 3,) expected IndexOutOfBoundsException");
314 
315         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuilder("bar"), 1, -1),
316             "append(StringBuilder,, -1) expected IndexOutOfBoundsException");
317 
318         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuilder("bar"), 1, 3),
319             "append(StringBuilder, 1, 3) expected IndexOutOfBoundsException");
320 
321         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuilder("bar"), -1, 3),
322             "append(StringBuilder, -1, 3) expected IndexOutOfBoundsException");
323 
324         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new StringBuilder("bar"), 4, 0),
325             "append(StringBuilder, 4, 0) expected IndexOutOfBoundsException");
326 
327         sb.append(new StringBuilder("bar"), 3, 0);
328         assertEquals("foo", sb.toString());
329 
330         sb.append(new StringBuilder("abcbardef"), 3, 3);
331         assertEquals("foobar", sb.toString());
332 
333         sb.append(new StringBuilder("abcbardef"), 4, 3);
334         assertEquals("foobarard", sb.toString());
335     }
336 
337     @Test
338     void testAppend_TextStringBuilder() {
339         TextStringBuilder sb = new TextStringBuilder();
340         sb.setNullText("NULL").append((TextStringBuilder) null);
341         assertEquals("NULL", sb.toString());
342 
343         sb = new TextStringBuilder();
344         sb.append(new TextStringBuilder("foo"));
345         assertEquals("foo", sb.toString());
346 
347         sb.append(new TextStringBuilder(""));
348         assertEquals("foo", sb.toString());
349 
350         sb.append(new TextStringBuilder("bar"));
351         assertEquals("foobar", sb.toString());
352     }
353 
354     @Test
355     void testAppend_TextStringBuilder_int_int() {
356         final TextStringBuilder sb0 = new TextStringBuilder();
357         sb0.setNullText("NULL").append((TextStringBuilder) null, 0, 1);
358         assertEquals("NULL", sb0.toString());
359 
360         final TextStringBuilder sb = new TextStringBuilder();
361         sb.append(new TextStringBuilder("foo"), 0, 3);
362         assertEquals("foo", sb.toString());
363 
364         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new TextStringBuilder("bar"), -1, 1),
365             "append(char[], -1,) expected IndexOutOfBoundsException");
366 
367         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new TextStringBuilder("bar"), 3, 1),
368             "append(char[], 3,) expected IndexOutOfBoundsException");
369 
370         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new TextStringBuilder("bar"), 1, -1),
371             "append(char[],, -1) expected IndexOutOfBoundsException");
372 
373         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new TextStringBuilder("bar"), 1, 3),
374             "append(char[], 1, 3) expected IndexOutOfBoundsException");
375 
376         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new TextStringBuilder("bar"), -1, 3),
377             "append(char[], -1, 3) expected IndexOutOfBoundsException");
378 
379         assertThrows(IndexOutOfBoundsException.class, () -> sb.append(new TextStringBuilder("bar"), 4, 0),
380             "append(char[], 4, 0) expected IndexOutOfBoundsException");
381 
382         sb.append(new TextStringBuilder("bar"), 3, 0);
383         assertEquals("foo", sb.toString());
384 
385         sb.append(new TextStringBuilder("abcbardef"), 3, 3);
386         assertEquals("foobar", sb.toString());
387     }
388 
389     @Test
390     void testAppendAll_Array() {
391         final TextStringBuilder sb = new TextStringBuilder();
392         sb.appendAll((Object[]) null);
393         assertEquals("", sb.toString());
394 
395         sb.clear();
396         sb.appendAll();
397         assertEquals("", sb.toString());
398 
399         sb.clear();
400         sb.appendAll("foo", "bar", "baz");
401         assertEquals("foobarbaz", sb.toString());
402 
403         sb.clear();
404         sb.appendAll("foo", "bar", "baz");
405         assertEquals("foobarbaz", sb.toString());
406     }
407 
408     @Test
409     void testAppendAll_Collection() {
410         final TextStringBuilder sb = new TextStringBuilder();
411         sb.appendAll((Collection<?>) null);
412         assertEquals("", sb.toString());
413 
414         sb.clear();
415         sb.appendAll(Collections.EMPTY_LIST);
416         assertEquals("", sb.toString());
417 
418         sb.clear();
419         sb.appendAll(Arrays.asList("foo", "bar", "baz"));
420         assertEquals("foobarbaz", sb.toString());
421     }
422 
423     @Test
424     void testAppendAll_Iterator() {
425         final TextStringBuilder sb = new TextStringBuilder();
426         sb.appendAll((Iterator<?>) null);
427         assertEquals("", sb.toString());
428 
429         sb.clear();
430         sb.appendAll(Collections.EMPTY_LIST.iterator());
431         assertEquals("", sb.toString());
432 
433         sb.clear();
434         sb.appendAll(Arrays.asList("foo", "bar", "baz").iterator());
435         assertEquals("foobarbaz", sb.toString());
436     }
437 
438     @Test
439     void testAppendFixedWidthPadLeft() {
440         final TextStringBuilder sb = new TextStringBuilder();
441         sb.appendFixedWidthPadLeft("foo", -1, '-');
442         assertEquals("", sb.toString());
443 
444         sb.clear();
445         sb.appendFixedWidthPadLeft("foo", 0, '-');
446         assertEquals("", sb.toString());
447 
448         sb.clear();
449         sb.appendFixedWidthPadLeft("foo", 1, '-');
450         assertEquals("o", sb.toString());
451 
452         sb.clear();
453         sb.appendFixedWidthPadLeft("foo", 2, '-');
454         assertEquals("oo", sb.toString());
455 
456         sb.clear();
457         sb.appendFixedWidthPadLeft("foo", 3, '-');
458         assertEquals("foo", sb.toString());
459 
460         sb.clear();
461         sb.appendFixedWidthPadLeft("foo", 4, '-');
462         assertEquals("-foo", sb.toString());
463 
464         sb.clear();
465         sb.appendFixedWidthPadLeft("foo", 10, '-');
466         assertEquals(10, sb.length());
467         // 1234567890
468         assertEquals("-------foo", sb.toString());
469 
470         sb.clear();
471         sb.setNullText("null");
472         sb.appendFixedWidthPadLeft(null, 5, '-');
473         assertEquals("-null", sb.toString());
474     }
475 
476     @Test
477     void testAppendFixedWidthPadLeft_int() {
478         final TextStringBuilder sb = new TextStringBuilder();
479         sb.appendFixedWidthPadLeft(123, -1, '-');
480         assertEquals("", sb.toString());
481 
482         sb.clear();
483         sb.appendFixedWidthPadLeft(123, 0, '-');
484         assertEquals("", sb.toString());
485 
486         sb.clear();
487         sb.appendFixedWidthPadLeft(123, 1, '-');
488         assertEquals("3", sb.toString());
489 
490         sb.clear();
491         sb.appendFixedWidthPadLeft(123, 2, '-');
492         assertEquals("23", sb.toString());
493 
494         sb.clear();
495         sb.appendFixedWidthPadLeft(123, 3, '-');
496         assertEquals("123", sb.toString());
497 
498         sb.clear();
499         sb.appendFixedWidthPadLeft(123, 4, '-');
500         assertEquals("-123", sb.toString());
501 
502         sb.clear();
503         sb.appendFixedWidthPadLeft(123, 10, '-');
504         assertEquals(10, sb.length());
505         // 1234567890
506         assertEquals("-------123", sb.toString());
507     }
508 
509     @Test
510     void testAppendFixedWidthPadRight() {
511         final TextStringBuilder sb = new TextStringBuilder();
512         sb.appendFixedWidthPadRight("foo", -1, '-');
513         assertEquals("", sb.toString());
514 
515         sb.clear();
516         sb.appendFixedWidthPadRight("foo", 0, '-');
517         assertEquals("", sb.toString());
518 
519         sb.clear();
520         sb.appendFixedWidthPadRight("foo", 1, '-');
521         assertEquals("f", sb.toString());
522 
523         sb.clear();
524         sb.appendFixedWidthPadRight("foo", 2, '-');
525         assertEquals("fo", sb.toString());
526 
527         sb.clear();
528         sb.appendFixedWidthPadRight("foo", 3, '-');
529         assertEquals("foo", sb.toString());
530 
531         sb.clear();
532         sb.appendFixedWidthPadRight("foo", 4, '-');
533         assertEquals("foo-", sb.toString());
534 
535         sb.clear();
536         sb.appendFixedWidthPadRight("foo", 10, '-');
537         assertEquals(10, sb.length());
538         // 1234567890
539         assertEquals("foo-------", sb.toString());
540 
541         sb.clear();
542         sb.setNullText("null");
543         sb.appendFixedWidthPadRight(null, 5, '-');
544         assertEquals("null-", sb.toString());
545     }
546 
547     @Test
548     void testAppendFixedWidthPadRight_int() {
549         final TextStringBuilder sb = new TextStringBuilder();
550         sb.appendFixedWidthPadRight(123, -1, '-');
551         assertEquals("", sb.toString());
552 
553         sb.clear();
554         sb.appendFixedWidthPadRight(123, 0, '-');
555         assertEquals("", sb.toString());
556 
557         sb.clear();
558         sb.appendFixedWidthPadRight(123, 1, '-');
559         assertEquals("1", sb.toString());
560 
561         sb.clear();
562         sb.appendFixedWidthPadRight(123, 2, '-');
563         assertEquals("12", sb.toString());
564 
565         sb.clear();
566         sb.appendFixedWidthPadRight(123, 3, '-');
567         assertEquals("123", sb.toString());
568 
569         sb.clear();
570         sb.appendFixedWidthPadRight(123, 4, '-');
571         assertEquals("123-", sb.toString());
572 
573         sb.clear();
574         sb.appendFixedWidthPadRight(123, 10, '-');
575         assertEquals(10, sb.length());
576         // 1234567890
577         assertEquals("123-------", sb.toString());
578     }
579 
580     @Test
581     void testAppendln_Boolean() {
582         final TextStringBuilder sb = new TextStringBuilder();
583         sb.appendln(true);
584         assertEquals("true" + SEP, sb.toString());
585 
586         sb.clear();
587         sb.appendln(false);
588         assertEquals("false" + SEP, sb.toString());
589     }
590 
591     @Test
592     void testAppendln_CharArray() {
593         final TextStringBuilder sb = spy(new TextStringBuilder());
594         final char[] input = "foo".toCharArray();
595         sb.appendln(input);
596 
597         assertEquals("foo" + SEP, sb.toString());
598 
599         verify(sb, times(1)).append(input);
600         verify(sb, times(1)).appendNewLine();
601     }
602 
603     @Test
604     void testAppendln_CharArray_int_int() {
605         final TextStringBuilder sb = spy(new TextStringBuilder());
606         final char[] input = "foo".toCharArray();
607         sb.appendln(input, 0, 3);
608 
609         assertEquals("foo" + SEP, sb.toString());
610 
611         verify(sb, times(1)).append(input, 0, 3);
612         verify(sb, times(1)).appendNewLine();
613     }
614 
615     @Test
616     void testAppendln_FormattedString() {
617         final TextStringBuilder sb = spy(new TextStringBuilder());
618         sb.appendln("Hello %s", "Alice");
619 
620         assertEquals("Hello Alice" + SEP, sb.toString());
621 
622         verify(sb, times(2)).append(anyString()); // appendNewLine() calls append(String)
623         verify(sb, times(1)).appendNewLine();
624     }
625 
626     @Test
627     void testAppendln_Object() {
628         final TextStringBuilder sb = new TextStringBuilder();
629         sb.appendln((Object) null);
630         assertEquals("" + SEP, sb.toString());
631 
632         sb.appendln(FOO);
633         assertEquals(SEP + "foo" + SEP, sb.toString());
634 
635         sb.appendln(Integer.valueOf(6));
636         assertEquals(SEP + "foo" + SEP + "6" + SEP, sb.toString());
637     }
638 
639     @Test
640     void testAppendln_PrimitiveNumber() {
641         final TextStringBuilder sb = new TextStringBuilder();
642         sb.appendln(0);
643         assertEquals("0" + SEP, sb.toString());
644 
645         sb.clear();
646         sb.appendln(1L);
647         assertEquals("1" + SEP, sb.toString());
648 
649         sb.clear();
650         sb.appendln(2.3f);
651         assertEquals("2.3" + SEP, sb.toString());
652 
653         sb.clear();
654         sb.appendln(4.5d);
655         assertEquals("4.5" + SEP, sb.toString());
656     }
657 
658     @Test
659     void testAppendln_String() {
660         final TextStringBuilder sb = spy(new TextStringBuilder());
661         sb.appendln("foo");
662 
663         assertEquals("foo" + SEP, sb.toString());
664 
665         verify(sb, times(2)).append(anyString()); // appendNewLine() calls append(String)
666         verify(sb, times(1)).appendNewLine();
667     }
668 
669     @Test
670     void testAppendln_String_int_int() {
671         final TextStringBuilder sb = spy(new TextStringBuilder());
672         sb.appendln("foo", 0, 3);
673 
674         assertEquals("foo" + SEP, sb.toString());
675 
676         verify(sb, times(2)).append(anyString(), anyInt(), anyInt()); // appendNewLine() calls append(String)
677         verify(sb, times(1)).appendNewLine();
678     }
679 
680     @Test
681     void testAppendln_StringBuffer() {
682         final TextStringBuilder sb = spy(new TextStringBuilder());
683         sb.appendln(new StringBuffer("foo"));
684 
685         assertEquals("foo" + SEP, sb.toString());
686 
687         verify(sb, times(1)).append(any(StringBuffer.class));
688         verify(sb, times(1)).appendNewLine();
689     }
690 
691     @Test
692     void testAppendln_StringBuffer_int_int() {
693         final TextStringBuilder sb = spy(new TextStringBuilder());
694         sb.appendln(new StringBuffer("foo"), 0, 3);
695 
696         assertEquals("foo" + SEP, sb.toString());
697 
698         verify(sb, times(1)).append(any(StringBuffer.class), anyInt(), anyInt());
699         verify(sb, times(1)).appendNewLine();
700     }
701 
702     @Test
703     void testAppendln_StringBuilder() {
704         final TextStringBuilder sb = spy(new TextStringBuilder());
705         sb.appendln(new StringBuilder("foo"));
706 
707         assertEquals("foo" + SEP, sb.toString());
708 
709         verify(sb, times(1)).append(any(StringBuilder.class));
710         verify(sb, times(1)).appendNewLine();
711     }
712 
713     @Test
714     void testAppendln_StringBuilder_int_int() {
715         final TextStringBuilder sb = spy(new TextStringBuilder());
716         sb.appendln(new StringBuilder("foo"), 0, 3);
717 
718         assertEquals("foo" + SEP, sb.toString());
719 
720         verify(sb, times(1)).append(any(StringBuilder.class), anyInt(), anyInt());
721         verify(sb, times(1)).appendNewLine();
722     }
723 
724     @Test
725     void testAppendln_TextStringBuilder() {
726         final TextStringBuilder sb = spy(new TextStringBuilder());
727         sb.appendln(new TextStringBuilder("foo"));
728 
729         assertEquals("foo" + SEP, sb.toString());
730 
731         verify(sb, times(1)).append(any(TextStringBuilder.class));
732         verify(sb, times(1)).appendNewLine();
733     }
734 
735     @Test
736     void testAppendln_TextStringBuilder_int_int() {
737         final TextStringBuilder sb = spy(new TextStringBuilder());
738         sb.appendln(new TextStringBuilder("foo"), 0, 3);
739 
740         assertEquals("foo" + SEP, sb.toString());
741 
742         verify(sb, times(1)).append(any(TextStringBuilder.class), anyInt(), anyInt());
743         verify(sb, times(1)).appendNewLine();
744     }
745 
746     @Test
747     void testAppendNewLine() {
748         TextStringBuilder sb = new TextStringBuilder("---");
749         sb.appendNewLine().append("+++");
750         assertEquals("---" + SEP + "+++", sb.toString());
751 
752         sb = new TextStringBuilder("---");
753         sb.setNewLineText("#").appendNewLine().setNewLineText(null).appendNewLine();
754         assertEquals("---#" + SEP, sb.toString());
755     }
756 
757     @Test
758     void testAppendPadding() {
759         final TextStringBuilder sb = new TextStringBuilder();
760         sb.append("foo");
761         assertEquals("foo", sb.toString());
762 
763         sb.appendPadding(-1, '-');
764         assertEquals("foo", sb.toString());
765 
766         sb.appendPadding(0, '-');
767         assertEquals("foo", sb.toString());
768 
769         sb.appendPadding(1, '-');
770         assertEquals("foo-", sb.toString());
771 
772         sb.appendPadding(16, '-');
773         assertEquals(20, sb.length());
774         // 12345678901234567890
775         assertEquals("foo-----------------", sb.toString());
776     }
777 
778     @Test
779     void testAppendSeparator_char() {
780         final TextStringBuilder sb = new TextStringBuilder();
781         sb.appendSeparator(','); // no effect
782         assertEquals("", sb.toString());
783         sb.append("foo");
784         assertEquals("foo", sb.toString());
785         sb.appendSeparator(',');
786         assertEquals("foo,", sb.toString());
787     }
788 
789     @Test
790     void testAppendSeparator_char_char() {
791         final TextStringBuilder sb = new TextStringBuilder();
792         final char startSeparator = ':';
793         final char standardSeparator = ',';
794         final String foo = "foo";
795         sb.appendSeparator(standardSeparator, startSeparator); // no effect
796         assertEquals(String.valueOf(startSeparator), sb.toString());
797         sb.append(foo);
798         assertEquals(String.valueOf(startSeparator) + foo, sb.toString());
799         sb.appendSeparator(standardSeparator, startSeparator);
800         assertEquals(String.valueOf(startSeparator) + foo + standardSeparator, sb.toString());
801     }
802 
803     @Test
804     void testAppendSeparator_char_int() {
805         final TextStringBuilder sb = new TextStringBuilder();
806         sb.appendSeparator(',', 0); // no effect
807         assertEquals("", sb.toString());
808         sb.append("foo");
809         assertEquals("foo", sb.toString());
810         sb.appendSeparator(',', 1);
811         assertEquals("foo,", sb.toString());
812 
813         sb.appendSeparator(',', -1); // no effect
814         assertEquals("foo,", sb.toString());
815     }
816 
817     @Test
818     void testAppendSeparator_String() {
819         final TextStringBuilder sb = new TextStringBuilder();
820         sb.appendSeparator(","); // no effect
821         assertEquals("", sb.toString());
822         sb.append("foo");
823         assertEquals("foo", sb.toString());
824         sb.appendSeparator(",");
825         assertEquals("foo,", sb.toString());
826     }
827 
828     @Test
829     void testAppendSeparator_String_int() {
830         final TextStringBuilder sb = new TextStringBuilder();
831         sb.appendSeparator(null, -1); // no effect
832         assertEquals("", sb.toString());
833         sb.appendSeparator(null, 0); // no effect
834         assertEquals("", sb.toString());
835         sb.appendSeparator(null, 1); // no effect
836         assertEquals("", sb.toString());
837         sb.appendSeparator(",", -1); // no effect
838         assertEquals("", sb.toString());
839         sb.appendSeparator(",", 0); // no effect
840         assertEquals("", sb.toString());
841         sb.append("foo");
842         assertEquals("foo", sb.toString());
843         sb.appendSeparator(",", 1);
844         assertEquals("foo,", sb.toString());
845 
846         sb.appendSeparator(",", -1); // no effect
847         assertEquals("foo,", sb.toString());
848     }
849 
850     @Test
851     void testAppendSeparator_String_String() {
852         final TextStringBuilder sb = new TextStringBuilder();
853         final String startSeparator = "order by ";
854         final String standardSeparator = ",";
855         final String foo = "foo";
856         sb.appendSeparator(null, null);
857         assertEquals("", sb.toString());
858         sb.appendSeparator(standardSeparator, null);
859         assertEquals("", sb.toString());
860         sb.appendSeparator(standardSeparator, startSeparator);
861         assertEquals(startSeparator, sb.toString());
862         sb.appendSeparator(null, null);
863         assertEquals(startSeparator, sb.toString());
864         sb.appendSeparator(null, startSeparator);
865         assertEquals(startSeparator, sb.toString());
866         sb.append(foo);
867         assertEquals(startSeparator + foo, sb.toString());
868         sb.appendSeparator(standardSeparator, startSeparator);
869         assertEquals(startSeparator + foo + standardSeparator, sb.toString());
870     }
871 
872     @Test
873     void testAppendWithNullText() {
874         final TextStringBuilder sb = new TextStringBuilder();
875         sb.setNullText("NULL");
876         assertEquals("", sb.toString());
877 
878         sb.appendNull();
879         assertEquals("NULL", sb.toString());
880 
881         sb.append((Object) null);
882         assertEquals("NULLNULL", sb.toString());
883 
884         sb.append(FOO);
885         assertEquals("NULLNULLfoo", sb.toString());
886 
887         sb.append((String) null);
888         assertEquals("NULLNULLfooNULL", sb.toString());
889 
890         sb.append("");
891         assertEquals("NULLNULLfooNULL", sb.toString());
892 
893         sb.append("bar");
894         assertEquals("NULLNULLfooNULLbar", sb.toString());
895 
896         sb.append((StringBuffer) null);
897         assertEquals("NULLNULLfooNULLbarNULL", sb.toString());
898 
899         sb.append(new StringBuffer("baz"));
900         assertEquals("NULLNULLfooNULLbarNULLbaz", sb.toString());
901     }
902 
903     @Test
904     void testAppendWithSeparators_Array() {
905         final TextStringBuilder sb = new TextStringBuilder();
906         sb.appendWithSeparators((Object[]) null, ",");
907         assertEquals("", sb.toString());
908 
909         sb.clear();
910         sb.appendWithSeparators(ArrayUtils.EMPTY_OBJECT_ARRAY, ",");
911         assertEquals("", sb.toString());
912 
913         sb.clear();
914         sb.appendWithSeparators(new Object[] {"foo", "bar", "baz"}, ",");
915         assertEquals("foo,bar,baz", sb.toString());
916 
917         sb.clear();
918         sb.appendWithSeparators(new Object[] {"foo", "bar", "baz"}, null);
919         assertEquals("foobarbaz", sb.toString());
920 
921         sb.clear();
922         sb.appendWithSeparators(new Object[] {"foo", null, "baz"}, ",");
923         assertEquals("foo,,baz", sb.toString());
924     }
925 
926     @Test
927     void testAppendWithSeparators_Collection() {
928         final TextStringBuilder sb = new TextStringBuilder();
929         sb.appendWithSeparators((Collection<?>) null, ",");
930         assertEquals("", sb.toString());
931 
932         sb.clear();
933         sb.appendWithSeparators(Collections.EMPTY_LIST, ",");
934         assertEquals("", sb.toString());
935 
936         sb.clear();
937         sb.appendWithSeparators(Arrays.asList("foo", "bar", "baz"), ",");
938         assertEquals("foo,bar,baz", sb.toString());
939 
940         sb.clear();
941         sb.appendWithSeparators(Arrays.asList("foo", "bar", "baz"), null);
942         assertEquals("foobarbaz", sb.toString());
943 
944         sb.clear();
945         sb.appendWithSeparators(Arrays.asList("foo", null, "baz"), ",");
946         assertEquals("foo,,baz", sb.toString());
947     }
948 
949     @Test
950     void testAppendWithSeparators_Iterator() {
951         final TextStringBuilder sb = new TextStringBuilder();
952         sb.appendWithSeparators((Iterator<?>) null, ",");
953         assertEquals("", sb.toString());
954 
955         sb.clear();
956         sb.appendWithSeparators(Collections.EMPTY_LIST.iterator(), ",");
957         assertEquals("", sb.toString());
958 
959         sb.clear();
960         sb.appendWithSeparators(Arrays.asList("foo", "bar", "baz").iterator(), ",");
961         assertEquals("foo,bar,baz", sb.toString());
962 
963         sb.clear();
964         sb.appendWithSeparators(Arrays.asList("foo", "bar", "baz").iterator(), null);
965         assertEquals("foobarbaz", sb.toString());
966 
967         sb.clear();
968         sb.appendWithSeparators(Arrays.asList("foo", null, "baz").iterator(), ",");
969         assertEquals("foo,,baz", sb.toString());
970     }
971 
972     @Test
973     void testAppendWithSeparatorsWithNullText() {
974         final TextStringBuilder sb = new TextStringBuilder();
975         sb.setNullText("null");
976         sb.appendWithSeparators(new Object[] {"foo", null, "baz"}, ",");
977         assertEquals("foo,null,baz", sb.toString());
978 
979         sb.clear();
980         sb.appendWithSeparators(Arrays.asList("foo", null, "baz"), ",");
981         assertEquals("foo,null,baz", sb.toString());
982     }
983 
984     @Test
985     void testInsert() {
986 
987         final TextStringBuilder sb = new TextStringBuilder();
988         sb.append("barbaz");
989         assertEquals("barbaz", sb.toString());
990 
991         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, FOO));
992 
993         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, FOO));
994 
995         sb.insert(0, (Object) null);
996         assertEquals("barbaz", sb.toString());
997 
998         sb.insert(0, FOO);
999         assertEquals("foobarbaz", sb.toString());
1000 
1001         sb.clear();
1002         sb.append("barbaz");
1003         assertEquals("barbaz", sb.toString());
1004 
1005         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, "foo"));
1006 
1007         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, "foo"));
1008 
1009         sb.insert(0, (String) null);
1010         assertEquals("barbaz", sb.toString());
1011 
1012         sb.insert(0, "foo");
1013         assertEquals("foobarbaz", sb.toString());
1014 
1015         sb.clear();
1016         sb.append("barbaz");
1017         assertEquals("barbaz", sb.toString());
1018 
1019         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, new char[] {'f', 'o', 'o'}));
1020 
1021         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, new char[] {'f', 'o', 'o'}));
1022 
1023         sb.insert(0, (char[]) null);
1024         assertEquals("barbaz", sb.toString());
1025 
1026         sb.insert(0, ArrayUtils.EMPTY_CHAR_ARRAY);
1027         assertEquals("barbaz", sb.toString());
1028 
1029         sb.insert(0, new char[] {'f', 'o', 'o'});
1030         assertEquals("foobarbaz", sb.toString());
1031 
1032         sb.clear();
1033         sb.append("barbaz");
1034         assertEquals("barbaz", sb.toString());
1035 
1036         assertThrows(IndexOutOfBoundsException.class,
1037             () -> sb.insert(-1, new char[] {'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 3, 3));
1038 
1039         assertThrows(IndexOutOfBoundsException.class,
1040             () -> sb.insert(7, new char[] {'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 3, 3));
1041 
1042         sb.insert(0, (char[]) null, 0, 0);
1043         assertEquals("barbaz", sb.toString());
1044 
1045         sb.insert(0, ArrayUtils.EMPTY_CHAR_ARRAY, 0, 0);
1046         assertEquals("barbaz", sb.toString());
1047 
1048         assertThrows(IndexOutOfBoundsException.class,
1049             () -> sb.insert(0, new char[] {'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, -1, 3));
1050 
1051         assertThrows(IndexOutOfBoundsException.class,
1052             () -> sb.insert(0, new char[] {'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 10, 3));
1053 
1054         assertThrows(IndexOutOfBoundsException.class,
1055             () -> sb.insert(0, new char[] {'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 0, -1));
1056 
1057         assertThrows(IndexOutOfBoundsException.class,
1058             () -> sb.insert(0, new char[] {'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 0, 10));
1059 
1060         sb.insert(0, new char[] {'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 0, 0);
1061         assertEquals("barbaz", sb.toString());
1062 
1063         sb.insert(0, new char[] {'a', 'b', 'c', 'f', 'o', 'o', 'd', 'e', 'f'}, 3, 3);
1064         assertEquals("foobarbaz", sb.toString());
1065 
1066         sb.clear();
1067         sb.append("barbaz");
1068         assertEquals("barbaz", sb.toString());
1069 
1070         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, true));
1071 
1072         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, true));
1073 
1074         sb.insert(0, true);
1075         assertEquals("truebarbaz", sb.toString());
1076 
1077         sb.insert(0, false);
1078         assertEquals("falsetruebarbaz", sb.toString());
1079 
1080         sb.clear();
1081         sb.append("barbaz");
1082         assertEquals("barbaz", sb.toString());
1083 
1084         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, '!'));
1085 
1086         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, '!'));
1087 
1088         sb.insert(0, '!');
1089         assertEquals("!barbaz", sb.toString());
1090 
1091         sb.clear();
1092         sb.append("barbaz");
1093         assertEquals("barbaz", sb.toString());
1094 
1095         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, 0));
1096 
1097         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, 0));
1098 
1099         sb.insert(0, '0');
1100         assertEquals("0barbaz", sb.toString());
1101 
1102         sb.clear();
1103         sb.append("barbaz");
1104         assertEquals("barbaz", sb.toString());
1105 
1106         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, 1L));
1107 
1108         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, 1L));
1109 
1110         sb.insert(0, 1L);
1111         assertEquals("1barbaz", sb.toString());
1112 
1113         sb.clear();
1114         sb.append("barbaz");
1115         assertEquals("barbaz", sb.toString());
1116 
1117         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, 2.3F));
1118 
1119         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, 2.3F));
1120 
1121         sb.insert(0, 2.3F);
1122         assertEquals("2.3barbaz", sb.toString());
1123 
1124         sb.clear();
1125         sb.append("barbaz");
1126         assertEquals("barbaz", sb.toString());
1127 
1128         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, 4.5D));
1129 
1130         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, 4.5D));
1131 
1132         sb.insert(0, 4.5D);
1133         assertEquals("4.5barbaz", sb.toString());
1134     }
1135 
1136     @Test
1137     void testInsertWithNullText() {
1138         final TextStringBuilder sb = new TextStringBuilder();
1139         sb.setNullText("null");
1140         sb.append("barbaz");
1141         assertEquals("barbaz", sb.toString());
1142 
1143         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, FOO));
1144 
1145         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, FOO));
1146 
1147         sb.insert(0, (Object) null);
1148         assertEquals("nullbarbaz", sb.toString());
1149 
1150         sb.insert(0, FOO);
1151         assertEquals("foonullbarbaz", sb.toString());
1152 
1153         sb.clear();
1154         sb.append("barbaz");
1155         assertEquals("barbaz", sb.toString());
1156 
1157         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(-1, "foo"));
1158 
1159         assertThrows(IndexOutOfBoundsException.class, () -> sb.insert(7, "foo"));
1160 
1161         sb.insert(0, (String) null);
1162         assertEquals("nullbarbaz", sb.toString());
1163 
1164         sb.insert(0, "foo");
1165         assertEquals("foonullbarbaz", sb.toString());
1166 
1167         sb.insert(0, (char[]) null);
1168         assertEquals("nullfoonullbarbaz", sb.toString());
1169 
1170         sb.insert(0, (char[]) null, 0, 0);
1171         assertEquals("nullnullfoonullbarbaz", sb.toString());
1172     }
1173 
1174     /** See: https://issues.apache.org/jira/browse/LANG-299 */
1175     @Test
1176     void testLang299() {
1177         final TextStringBuilder sb = new TextStringBuilder(1);
1178         sb.appendFixedWidthPadRight("foo", 1, '-');
1179         assertEquals("f", sb.toString());
1180     }
1181 }