Skip to content

Commit cc0824a

Browse files
committed
Strengthen Converter and HelpFormatter tests
1 parent 5719037 commit cc0824a

2 files changed

Lines changed: 156 additions & 2 deletions

File tree

src/test/java/org/apache/commons/cli/ConverterTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more
2121
import static org.junit.jupiter.api.Assertions.assertThrows;
2222

2323
import java.net.URL;
24+
import java.nio.file.Path;
2425
import java.text.DateFormat;
2526
import java.text.SimpleDateFormat;
2627
import java.util.ArrayList;
@@ -91,13 +92,26 @@ void testDate() throws Exception {
9192
assertThrows(java.text.ParseException.class, () -> Converter.DATE.apply("Jun 06 17:48:57 EDT 2002"));
9293
}
9394

95+
@Test
96+
void testDefault() throws Exception {
97+
assertEquals("value", Converter.DEFAULT.apply("value"));
98+
assertEquals("", Converter.DEFAULT.apply(""));
99+
}
100+
94101
@Test
95102
void testFile() throws Exception {
96103
final URL url = this.getClass().getClassLoader().getResource("./org/apache/commons/cli/existing-readable.file");
97104
final String fileName = url.toString().substring("file:".length());
98105
assertNotNull(Converter.FILE.apply(fileName));
99106
}
100107

108+
@Test
109+
void testPath() throws Exception {
110+
final Path path = Converter.PATH.apply("src");
111+
assertNotNull(path);
112+
assertEquals("src", path.toString());
113+
}
114+
101115
@ParameterizedTest
102116
@MethodSource("numberTestParameters")
103117
void testNumber(final String str, final Number expected) throws Exception {

src/test/java/org/apache/commons/cli/HelpFormatterTest.java

Lines changed: 142 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ Licensed to the Apache Software Foundation (ASF) under one or more
2121
import static org.junit.jupiter.api.Assertions.assertEquals;
2222
import static org.junit.jupiter.api.Assertions.assertNotNull;
2323
import static org.junit.jupiter.api.Assertions.assertNull;
24+
import static org.junit.jupiter.api.Assertions.assertSame;
25+
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
2426
import static org.junit.jupiter.api.Assertions.assertThrows;
27+
import static org.junit.jupiter.api.Assertions.assertTrue;
2528
import static org.mockito.Mockito.spy;
2629
import static org.mockito.Mockito.when;
2730

@@ -31,6 +34,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more
3134
import java.io.PrintWriter;
3235
import java.io.StringWriter;
3336
import java.io.UncheckedIOException;
37+
import java.time.Duration;
3438
import java.util.ArrayList;
3539
import java.util.List;
3640
import java.util.stream.Stream;
@@ -172,6 +176,51 @@ void testDeprecatedPrintOptionsZeroWidth(final int width) {
172176
assertNotNull(result);
173177
}
174178

179+
@Test
180+
void testAppendWrappedTextCutsLongWordAfterPadding() throws IOException {
181+
final StringBuilder sb = new StringBuilder();
182+
final HelpFormatter formatter = new HelpFormatter();
183+
184+
assertTimeoutPreemptively(Duration.ofMillis(200), () -> assertSame(sb, formatter.appendWrappedText(sb, 7, 4, "abc defghijk")));
185+
assertEquals("abc" + EOL + " def" + EOL + " ghi" + EOL + " jk", sb.toString());
186+
}
187+
188+
@Test
189+
void testAppendWrappedTextResetsOversizedPadding() throws IOException {
190+
final StringBuilder sb = new StringBuilder();
191+
final HelpFormatter formatter = new HelpFormatter();
192+
193+
assertTimeoutPreemptively(Duration.ofMillis(200), () -> assertSame(sb, formatter.appendWrappedText(sb, 4, 6, "a b c d")));
194+
assertEquals("a b" + EOL + " c d", sb.toString());
195+
}
196+
197+
@Test
198+
void testAppendWrappedTextResetsPaddingWhenItMatchesWidth() {
199+
final StringBuilder sb = new StringBuilder();
200+
final HelpFormatter formatter = new HelpFormatter();
201+
202+
assertTimeoutPreemptively(Duration.ofMillis(200), () -> assertSame(sb, formatter.appendWrappedText(sb, 5, 5, "a b c d")));
203+
assertEquals("a b c" + EOL + " d", sb.toString());
204+
}
205+
206+
@Test
207+
void testAppendWrappedTextReturnsSameAppendableWhenNoWrapIsNeeded() throws IOException {
208+
final StringBuilder sb = new StringBuilder();
209+
final HelpFormatter formatter = new HelpFormatter();
210+
211+
assertSame(sb, formatter.appendWrappedText(sb, 20, 4, "value "));
212+
assertEquals("value", sb.toString());
213+
}
214+
215+
@Test
216+
void testAppendWrappedTextZeroWidthReturnsImmediately() {
217+
final StringBuilder sb = new StringBuilder("seed");
218+
final HelpFormatter formatter = new HelpFormatter();
219+
220+
assertTimeoutPreemptively(Duration.ofMillis(200), () -> assertSame(sb, formatter.appendWrappedText(sb, 0, 4, "value")));
221+
assertEquals("seed", sb.toString());
222+
}
223+
175224
@Test
176225
void testFindWrapPos() {
177226
final HelpFormatter hf = new HelpFormatter();
@@ -199,6 +248,11 @@ void testFindWrapPos() {
199248
assertEquals(7, hf.findWrapPos(text, 6, 0), "wrap position 6");
200249
}
201250

251+
@Test
252+
void testFindWrapPosDoesNotWrapAtWhitespaceAtStartPosition() {
253+
assertEquals(1, new HelpFormatter().findWrapPos(" word", 1, 0));
254+
}
255+
202256
@Test
203257
void testHeaderStartingWithLineSeparator0() {
204258
// related to Bugzilla #21215
@@ -544,6 +598,42 @@ void testPrintOptionGroupUsage() {
544598
assertEquals("usage: app [-a | -b | -c]" + EOL, out.toString());
545599
}
546600

601+
@Test
602+
void testPrintOptionGroupUsagePreservesInsertionOrderWithNullComparator() {
603+
final OptionGroup optionGroup = new OptionGroup();
604+
optionGroup.addOption(Option.builder("c").get());
605+
optionGroup.addOption(Option.builder("a").get());
606+
optionGroup.addOption(Option.builder("b").get());
607+
608+
final Options options = new Options();
609+
options.addOptionGroup(optionGroup);
610+
611+
final StringWriter out = new StringWriter();
612+
final HelpFormatter formatter = new HelpFormatter();
613+
formatter.setOptionComparator(null);
614+
formatter.printUsage(new PrintWriter(out), 80, "app", options);
615+
616+
assertEquals("usage: app [-c | -a | -b]" + EOL, out.toString());
617+
}
618+
619+
@Test
620+
void testPrintOptionGroupUsageSortsWhenComparatorPresent() {
621+
final OptionGroup optionGroup = new OptionGroup();
622+
optionGroup.addOption(Option.builder("c").get());
623+
optionGroup.addOption(Option.builder("a").get());
624+
optionGroup.addOption(Option.builder("b").get());
625+
626+
final Options options = new Options();
627+
options.addOptionGroup(optionGroup);
628+
629+
final StringWriter out = new StringWriter();
630+
final HelpFormatter formatter = new HelpFormatter();
631+
formatter.setOptionComparator((opt1, opt2) -> opt2.getKey().compareToIgnoreCase(opt1.getKey()));
632+
formatter.printUsage(new PrintWriter(out), 80, "app", options);
633+
634+
assertEquals("usage: app [-c | -b | -a]" + EOL, out.toString());
635+
}
636+
547637
@Test
548638
void testPrintOptions() {
549639
final StringBuffer sb = new StringBuffer();
@@ -557,7 +647,7 @@ void testPrintOptions() {
557647

558648
options = new Options().addOption("a", false, "aaaa aaaa aaaa aaaa aaaa");
559649
expected = lpad + "-a" + dpad + "aaaa aaaa aaaa aaaa aaaa";
560-
hf.renderOptions(sb, 60, options, leftPad, descPad);
650+
assertSame(sb, hf.renderOptions(sb, 60, options, leftPad, descPad));
561651
assertEquals(expected, sb.toString(), "simple non-wrapped option");
562652

563653
int nextLineTabStop = leftPad + descPad + "-a".length();
@@ -586,6 +676,16 @@ void testPrintOptions() {
586676
assertEquals(expected, sb.toString(), "multiple wrapped options");
587677
}
588678

679+
@Test
680+
void testPrintOptionsShowSinceKeepsLongestPrefixAligned() {
681+
final Options options = new Options().addOption(Option.builder("a").longOpt("alpha").since("v1").desc("desc").get());
682+
final HelpFormatter formatter = HelpFormatter.builder().setShowSince(true).get();
683+
final StringBuffer sb = new StringBuffer();
684+
685+
assertSame(sb, formatter.renderOptions(sb, 80, options, 2, 2));
686+
assertEquals("Options Since Description" + EOL + " -a,--alpha v1 desc", sb.toString());
687+
}
688+
589689
@Test
590690
void testPrintOptionWithEmptyArgNameUsage() {
591691
final Option option = new Option("f", true, null);
@@ -674,6 +774,23 @@ void testPrintUsage() {
674774
assertEquals("usage: app [-a] [-b] [-c]" + EOL, bytesOut.toString());
675775
}
676776

777+
@Test
778+
void testPrintUsageWrapsArgumentsUsingSyntaxIndentation() {
779+
final StringWriter out = new StringWriter();
780+
781+
new HelpFormatter().printUsage(new PrintWriter(out), 12, "cmd arg1 arg2");
782+
783+
assertEquals("usage: cmd" + EOL
784+
+ " a" + EOL
785+
+ " r" + EOL
786+
+ " g" + EOL
787+
+ " 1" + EOL
788+
+ " a" + EOL
789+
+ " r" + EOL
790+
+ " g" + EOL
791+
+ " 2" + EOL, out.toString());
792+
}
793+
677794
@Test
678795
void testRenderSince() throws IOException {
679796
final String[] expected = {"Options Since Description", " -n,--no-since - Description for n",
@@ -704,7 +821,7 @@ void testRenderWrappedTextMultiLine() {
704821
//@formatter:on
705822

706823
final StringBuffer sb = new StringBuffer();
707-
new HelpFormatter().renderWrappedText(sb, width, padding, expected);
824+
assertSame(sb, new HelpFormatter().renderWrappedText(sb, width, padding, expected));
708825
assertEquals(expected, sb.toString(), "multi line text");
709826
}
710827

@@ -794,6 +911,8 @@ void testRtrim() {
794911

795912
assertNull(formatter.rtrim(null));
796913
assertEquals("", formatter.rtrim(""));
914+
assertEquals("", formatter.rtrim(" "));
915+
assertEquals("foo", formatter.rtrim("foo "));
797916
assertEquals(" foo", formatter.rtrim(" foo "));
798917
}
799918

@@ -813,4 +932,25 @@ void testUsageWithLongOptSeparator() {
813932

814933
assertEquals("usage: create [--age=<arg>] [-f <arg>] [-s <SIZE>]", out.toString().trim());
815934
}
935+
936+
@Test
937+
void testPrintHelpFlushesConfiguredPrintWriter() {
938+
final class FlushAwareStringWriter extends StringWriter {
939+
private boolean flushed;
940+
941+
@Override
942+
public void flush() {
943+
flushed = true;
944+
super.flush();
945+
}
946+
}
947+
948+
final FlushAwareStringWriter out = new FlushAwareStringWriter();
949+
final HelpFormatter formatter = HelpFormatter.builder().setPrintWriter(new PrintWriter(out)).get();
950+
final Options options = new Options().addOption("a", false, "desc");
951+
952+
formatter.printHelp(80, "app", "header", options, "footer", false);
953+
954+
assertTrue(out.flushed);
955+
}
816956
}

0 commit comments

Comments
 (0)