Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ public static int indexOfWrap(final CharSequence text, final int width, final in
break;
}
}
// if we found it return it, otherwise just chop at limit
return pos > startPos ? pos : limit - 1;
// if we found it return it, otherwise just chop at limit, always consuming at least one character so that a width of 1
// still advances past startPos and the wrap loop in makeColumnQueue terminates.
return pos > startPos ? pos : Math.max(limit - 1, startPos + 1);
}

/**
Expand Down Expand Up @@ -218,12 +219,14 @@ public void appendHeader(final int level, final CharSequence text) throws IOExce
@Override
public void appendList(final boolean ordered, final Collection<CharSequence> list) throws IOException {
if (list != null && !list.isEmpty()) {
final TextStyle.Builder builder = TextStyle.builder().setLeftPad(textStyleBuilder.getLeftPad()).setIndent(DEFAULT_LIST_INDENT);
// wrap at the configured width rather than the entry length: an entry with a line break that is shorter than the
// list indent would otherwise leave no room for its continuation lines.
final TextStyle.Builder builder = TextStyle.builder().setLeftPad(textStyleBuilder.getLeftPad()).setIndent(DEFAULT_LIST_INDENT)
.setMaxWidth(textStyleBuilder.getMaxWidth());
int i = 1;
for (final CharSequence line : list) {
final String entry = ordered ? String.format(" %s. %s", i++, Util.defaultValue(line, BLANK_LINE))
: String.format(" * %s", Util.defaultValue(line, BLANK_LINE));
builder.setMaxWidth(Math.min(textStyleBuilder.getMaxWidth(), entry.length()));
printQueue(makeColumnQueue(entry, builder.get()));
}
output.append(System.lineSeparator());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,21 @@ void testAppendList() throws IOException {
assertEquals(expected, actual, "null list failed");
}

@Test
void testAppendListWithLineBreak() throws IOException {
// an entry shorter than the list indent used to throw and an 8 character entry used to loop until the heap was exhausted
final List<String> expected = new ArrayList<>();
expected.add(" * a");
expected.add(" b");
expected.add(" * ab");
expected.add(" cd");
expected.add("");

underTest.appendList(false, Arrays.asList("a\nb", "ab\ncd"));
final List<String> actual = IOUtils.readLines(new StringReader(sb.toString()));
assertEquals(expected, actual);
}

@Test
void testAppendParagraph() throws IOException {
final String[] expected = { " Hello World", "" };
Expand Down Expand Up @@ -281,6 +296,10 @@ void testindexOfWrapPos() {
assertThrows(IllegalArgumentException.class, () -> TextHelpAppendable.indexOfWrap("", 0, 0));
assertEquals(3, TextHelpAppendable.indexOfWrap("Hello", 4, 0));

// a width of 1 must still consume one character, otherwise makeColumnQueue never advances
assertEquals(1, TextHelpAppendable.indexOfWrap("Hello", 1, 0), "width of 1 did not advance");
assertEquals(3, TextHelpAppendable.indexOfWrap("Hello", 1, 2), "width of 1 did not advance past startPos");

// startPos + width must not overflow when width is TextStyle.UNSET_MAX_WIDTH
assertEquals(30, TextHelpAppendable.indexOfWrap(testString, TextStyle.UNSET_MAX_WIDTH, 0), "did not find break character with unbounded width");
assertEquals(testString.length(), TextHelpAppendable.indexOfWrap(testString, TextStyle.UNSET_MAX_WIDTH, 31), "overflow produced a negative wrap index");
Expand Down Expand Up @@ -357,6 +376,24 @@ void testMakeColumnQueueWithMultipleTrailingLineBreaks() {
assertEquals(expected, result, "left aligned failed");
}

@Test
void testMakeColumnQueueWithWidthOfOne() {
// an indent one less than the max width leaves a usable width of 1 for the continuation lines, which used to loop forever
final String text = "hello world";
final TextStyle.Builder styleBuilder = TextStyle.builder().setMaxWidth(5).setIndent(4).setLeftPad(0);

final Queue<String> expected = new LinkedList<>();
expected.add("hello");
expected.add(" w");
expected.add(" o");
expected.add(" r");
expected.add(" l");
expected.add(" d");

final Queue<String> result = underTest.makeColumnQueue(text, styleBuilder.get());
assertEquals(expected, result);
}

@Test
void testPrintWrapped() throws IOException {
String text = "The quick brown fox jumps over the lazy dog";
Expand Down