diff --git a/core/src/main/java/net/jbock/compiler/Tokenizer.java b/core/src/main/java/net/jbock/compiler/Tokenizer.java index e1e715160..30c4be046 100644 --- a/core/src/main/java/net/jbock/compiler/Tokenizer.java +++ b/core/src/main/java/net/jbock/compiler/Tokenizer.java @@ -304,6 +304,7 @@ private CodeBlock parseMethodTryBlock( private CodeBlock parseMethodCatchBlock(ParameterSpec e) { CodeBlock.Builder spec = CodeBlock.builder(); + spec.addStatement("$N.printStackTrace($N.out)", e, err); if (context.addHelp) { spec.addStatement("$N.println($S)", err, "Usage:"); spec.addStatement("$N.incrementIndent()", err); diff --git a/examples/src/test/java/net/jbock/examples/AdditionArgumentsTest.java b/examples/src/test/java/net/jbock/examples/AdditionArgumentsTest.java index 85c085440..ee0b5e4ad 100644 --- a/examples/src/test/java/net/jbock/examples/AdditionArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/AdditionArgumentsTest.java @@ -28,7 +28,7 @@ void optionalPresent() { @Test void wrongNumber() { - f.assertThat("-a", "2").failsWithLine4( + f.assertThat("-a", "2").failsWithUsageMessage( "For input string: \"-a\""); } diff --git a/examples/src/test/java/net/jbock/examples/AllCharactersArgumentsTest.java b/examples/src/test/java/net/jbock/examples/AllCharactersArgumentsTest.java index 46230b42a..d7d8a9b1d 100644 --- a/examples/src/test/java/net/jbock/examples/AllCharactersArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/AllCharactersArgumentsTest.java @@ -33,7 +33,7 @@ void fail() { "--bigChar", "A", "--charOpt", "X", "--charList", "b", - "--charList", "c").failsWithLine4( + "--charList", "c").failsWithUsageMessage( "Not a character: "); } } \ No newline at end of file diff --git a/examples/src/test/java/net/jbock/examples/CpArgumentsTest.java b/examples/src/test/java/net/jbock/examples/CpArgumentsTest.java index 089077775..5c249f427 100644 --- a/examples/src/test/java/net/jbock/examples/CpArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/CpArgumentsTest.java @@ -15,15 +15,15 @@ class CpArgumentsTest { @Test void errorMissingSource() { - f.assertThat().failsWithLine4("Missing parameter: "); - f.assertThat("-r").failsWithLine4("Missing parameter: "); + f.assertThat().failsWithUsageMessage("Missing parameter: "); + f.assertThat("-r").failsWithUsageMessage("Missing parameter: "); } @Test void errorMissingDest() { - f.assertThat("a").failsWithLine4("Missing parameter: "); - f.assertThat("a", "-r").failsWithLine4("Missing parameter: "); - f.assertThat("-r", "a").failsWithLine4("Missing parameter: "); + f.assertThat("a").failsWithUsageMessage("Missing parameter: "); + f.assertThat("a", "-r").failsWithUsageMessage("Missing parameter: "); + f.assertThat("-r", "a").failsWithUsageMessage("Missing parameter: "); } @Test @@ -44,17 +44,17 @@ void minimal() { @Test void dashNotIgnored() { - f.assertThat("-a", "b").failsWithLine4("Invalid option: -a"); + f.assertThat("-a", "b").failsWithUsageMessage("Invalid option: -a"); } @Test void tooMany() { - f.assertThat("a", "b", "c").failsWithLine4("Invalid option: c"); + f.assertThat("a", "b", "c").failsWithUsageMessage("Invalid option: c"); } @Test void tooManyAndFlag() { - f.assertThat("-r", "a", "b", "c").failsWithLine4("Invalid option: c"); + f.assertThat("-r", "a", "b", "c").failsWithUsageMessage("Invalid option: c"); } @Test diff --git a/examples/src/test/java/net/jbock/examples/CurlArgumentsTest.java b/examples/src/test/java/net/jbock/examples/CurlArgumentsTest.java index a16148876..3fc904d10 100644 --- a/examples/src/test/java/net/jbock/examples/CurlArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/CurlArgumentsTest.java @@ -158,50 +158,50 @@ void variousTests() { @Test void errorInvalidGrouping() { - f.assertThat("-vH1").failsWithLine4("Invalid option: -vH1"); + f.assertThat("-vH1").failsWithUsageMessage("Invalid option: -vH1"); } @Test void errorInvalidGroupingLong() { - f.assertThat("-vXPOST").failsWithLine4("Invalid option: -vXPOST"); + f.assertThat("-vXPOST").failsWithUsageMessage("Invalid option: -vXPOST"); } @Test void errorGroupingDuplicateFlag() { - f.assertThat("-v", "-vH'Content-Type: application/xml'").failsWithLine4( + f.assertThat("-v", "-vH'Content-Type: application/xml'").failsWithUsageMessage( "Invalid option: -vH'Content-Type: application/xml'"); } @Test void errorMissingRepeatable() { - f.assertThat("-H").failsWithLine4("Missing value after token: -H"); + f.assertThat("-H").failsWithUsageMessage("Missing value after token: -H"); } @Test void errorMissingNonRepeatable() { - f.assertThat("--request").failsWithLine4("Missing value after token: --request"); + f.assertThat("--request").failsWithUsageMessage("Missing value after token: --request"); } @Test void errorDuplicateNonRepeatableLong() { - f.assertThat("--request", "GET", "--request", "POST").failsWithLine4( + f.assertThat("--request", "GET", "--request", "POST").failsWithUsageMessage( "Option METHOD (-X, --request) is not repeatable"); } @Test void errorDuplicateNonRepeatableShort() { - f.assertThat("-X1", "-X2").failsWithLine4("Option METHOD (-X, --request) is not repeatable"); + f.assertThat("-X1", "-X2").failsWithUsageMessage("Option METHOD (-X, --request) is not repeatable"); } @Test void errorDuplicateNonRepeatableLongDetachedShortAttached() { - f.assertThat("--request", "1", "-X2").failsWithLine4( + f.assertThat("--request", "1", "-X2").failsWithUsageMessage( "Option METHOD (-X, --request) is not repeatable"); } @Test void errorDuplicateNonRepeatableLongAttachedShortDetached() { - f.assertThat("--request=1", "-X", "2").failsWithLine4( + f.assertThat("--request=1", "-X", "2").failsWithUsageMessage( "Option METHOD (-X, --request) is not repeatable"); } diff --git a/examples/src/test/java/net/jbock/examples/CustomMapperArgumentsTest.java b/examples/src/test/java/net/jbock/examples/CustomMapperArgumentsTest.java index ae11ac34e..6ee7924b4 100644 --- a/examples/src/test/java/net/jbock/examples/CustomMapperArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/CustomMapperArgumentsTest.java @@ -57,8 +57,8 @@ void success() { @Test void invalidOptions() { - f.assertThat("--date", "FooBar").failsWithLine4("For input string: \"FooBar\""); - f.assertThat().failsWithLine4("Missing required option: DATE (--date)"); + f.assertThat("--date", "FooBar").failsWithUsageMessage("For input string: \"FooBar\""); + f.assertThat().failsWithUsageMessage("Missing required option: DATE (--date)"); } @Test diff --git a/examples/src/test/java/net/jbock/examples/GradleArgumentsTest.java b/examples/src/test/java/net/jbock/examples/GradleArgumentsTest.java index f74be2727..55bdbbe23 100644 --- a/examples/src/test/java/net/jbock/examples/GradleArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/GradleArgumentsTest.java @@ -16,39 +16,39 @@ class GradleArgumentsTest { @Test void errorShortLongConflict() { - f.assertThat("-m", "hello", "--message=goodbye").failsWithLine4( + f.assertThat("-m", "hello", "--message=goodbye").failsWithUsageMessage( "Option MESSAGE (-m, --message) is not repeatable"); } @Test void errorMissingValue() { // there's nothing after -m - f.assertThat("-m").failsWithLine4("Missing value after token: -m"); + f.assertThat("-m").failsWithUsageMessage("Missing value after token: -m"); } @Test void errorLongShortConflict() { - f.assertThat("--message=hello", "-m", "goodbye").failsWithLine4( + f.assertThat("--message=hello", "-m", "goodbye").failsWithUsageMessage( "Option MESSAGE (-m, --message) is not repeatable"); } @Test void errorLongLongConflict() { - f.assertThat("--message=hello", "--message=goodbye").failsWithLine4( + f.assertThat("--message=hello", "--message=goodbye").failsWithUsageMessage( "Option MESSAGE (-m, --message) is not repeatable"); } @Test void errorInvalidOption() { - f.assertThat("-c1").failsWithLine4("Invalid option: -c1"); - f.assertThat("-c-v").failsWithLine4("Invalid option: -c-v"); - f.assertThat("-c-").failsWithLine4("Invalid option: -c-"); - f.assertThat("-c=v").failsWithLine4("Invalid option: -c=v"); - f.assertThat("-c=").failsWithLine4("Invalid option: -c="); - f.assertThat("-cX=1").failsWithLine4("Invalid option: -cX=1"); - f.assertThat("-cvv").failsWithLine4("Invalid option: -cvv"); - f.assertThat("-cvx").failsWithLine4("Invalid option: -cvx"); - f.assertThat("-cvm").failsWithLine4("Invalid option: -cvm"); + f.assertThat("-c1").failsWithUsageMessage("Invalid option: -c1"); + f.assertThat("-c-v").failsWithUsageMessage("Invalid option: -c-v"); + f.assertThat("-c-").failsWithUsageMessage("Invalid option: -c-"); + f.assertThat("-c=v").failsWithUsageMessage("Invalid option: -c=v"); + f.assertThat("-c=").failsWithUsageMessage("Invalid option: -c="); + f.assertThat("-cX=1").failsWithUsageMessage("Invalid option: -cX=1"); + f.assertThat("-cvv").failsWithUsageMessage("Invalid option: -cvv"); + f.assertThat("-cvx").failsWithUsageMessage("Invalid option: -cvx"); + f.assertThat("-cvm").failsWithUsageMessage("Invalid option: -cvm"); } @Test @@ -141,7 +141,7 @@ void testRepeatableShortAttached() { @Test void testLongSuppressed() { // Long option --cmos is suppressed - f.assertThat("--cmos").failsWithLine4("Invalid option: --cmos"); + f.assertThat("--cmos").failsWithUsageMessage("Invalid option: --cmos"); } @Test @@ -179,7 +179,7 @@ void twoFlags() { @Test void errorSuspiciousInput() { - f.assertThat("-cvm", "hello").failsWithLine4("Invalid option: -cvm"); + f.assertThat("-cvm", "hello").failsWithUsageMessage("Invalid option: -cvm"); } @Test diff --git a/examples/src/test/java/net/jbock/examples/HelplessArgumentsTest.java b/examples/src/test/java/net/jbock/examples/HelplessArgumentsTest.java index 71e637fab..dad13ef96 100644 --- a/examples/src/test/java/net/jbock/examples/HelplessArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/HelplessArgumentsTest.java @@ -58,7 +58,7 @@ void errorNoArguments() { TestOutputStream out = new TestOutputStream(); HelplessArguments_Parser.create().withErrorStream(out.out).parse(new String[]{}); String message = out.toString(); - assertTrue(message.startsWith(String.join("\n", fullUsage))); + assertTrue(message.contains(String.join("\n", fullUsage))); assertTrue(message.contains("Missing parameter: ")); } @@ -67,7 +67,7 @@ void errorInvalidOption() { TestOutputStream out = new TestOutputStream(); HelplessArguments_Parser.create().withErrorStream(out.out).parse(new String[]{"-p"}); String message = out.toString(); - assertTrue(message.startsWith(String.join("\n", fullUsage))); + assertTrue(message.contains(String.join("\n", fullUsage))); assertTrue(message.contains("Invalid option: -p")); } } diff --git a/examples/src/test/java/net/jbock/examples/MvArgumentsTest.java b/examples/src/test/java/net/jbock/examples/MvArgumentsTest.java index dd6dffcda..8b46b2dac 100644 --- a/examples/src/test/java/net/jbock/examples/MvArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/MvArgumentsTest.java @@ -10,28 +10,28 @@ class MvArgumentsTest { @Test void notEnoughArguments() { - f.assertThat().failsWithLine4("Missing parameter: "); - f.assertThat("a").failsWithLine4("Missing parameter: "); + f.assertThat().failsWithUsageMessage("Missing parameter: "); + f.assertThat("a").failsWithUsageMessage("Missing parameter: "); } @Test void invalidOption() { - f.assertThat("-aa", "b").failsWithLine4("Invalid option: -aa"); + f.assertThat("-aa", "b").failsWithUsageMessage("Invalid option: -aa"); } @Test void excessOption() { - f.assertThat("a", "b", "c").failsWithLine4("Invalid option: c"); + f.assertThat("a", "b", "c").failsWithUsageMessage("Invalid option: c"); } @Test void invalidOptionEscapeSequenceSecond() { - f.assertThat("a", "--").failsWithLine4("Invalid option: --"); + f.assertThat("a", "--").failsWithUsageMessage("Invalid option: --"); } @Test void invalidOptionEscapeSequenceThird() { - f.assertThat("a", "b", "--", "c").failsWithLine4("Invalid option: --"); + f.assertThat("a", "b", "--", "c").failsWithUsageMessage("Invalid option: --"); } @Test diff --git a/examples/src/test/java/net/jbock/examples/NoNameArgumentsTest.java b/examples/src/test/java/net/jbock/examples/NoNameArgumentsTest.java index 28ff1d918..b816d0f4b 100644 --- a/examples/src/test/java/net/jbock/examples/NoNameArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/NoNameArgumentsTest.java @@ -57,12 +57,12 @@ void testOptionalInt() { @Test void errorMissingInt() { - f.assertThat("--cmos").failsWithLine4("Missing required option: NUMBER (-n, --number)"); + f.assertThat("--cmos").failsWithUsageMessage("Missing required option: NUMBER (-n, --number)"); } @Test void errorUnknownToken() { - f.assertThat("blabla").failsWithLine4("Invalid option: blabla"); + f.assertThat("blabla").failsWithUsageMessage("Invalid option: blabla"); } @Test diff --git a/examples/src/test/java/net/jbock/examples/PositionalArgumentsTest.java b/examples/src/test/java/net/jbock/examples/PositionalArgumentsTest.java index a9060669b..8150e5a55 100644 --- a/examples/src/test/java/net/jbock/examples/PositionalArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/PositionalArgumentsTest.java @@ -15,9 +15,9 @@ class PositionalArgumentsTest { @Test void errorMissingParameters() { - f.assertThat().failsWithLine4("Missing parameter: "); - f.assertThat("a").failsWithLine4("Missing parameter: "); - f.assertThat("a", "b").failsWithLine4("Missing parameter: "); + f.assertThat().failsWithUsageMessage("Missing parameter: "); + f.assertThat("a").failsWithUsageMessage("Missing parameter: "); + f.assertThat("a", "b").failsWithUsageMessage("Missing parameter: "); } @Test diff --git a/examples/src/test/java/net/jbock/examples/RequiredArgumentsTest.java b/examples/src/test/java/net/jbock/examples/RequiredArgumentsTest.java index c3e0d3c5f..d9c9d96df 100644 --- a/examples/src/test/java/net/jbock/examples/RequiredArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/RequiredArgumentsTest.java @@ -17,24 +17,24 @@ void success() { @Test void errorDirMissing() { - f.assertThat().failsWithLine4("Missing required option: DIR (--dir)"); + f.assertThat().failsWithUsageMessage("Missing required option: DIR (--dir)"); } @Test void errorRepeatedArgument() { - f.assertThat("--dir", "A", "--dir", "B").failsWithLine4( + f.assertThat("--dir", "A", "--dir", "B").failsWithUsageMessage( "Option DIR (--dir) is not repeatable"); - f.assertThat("--dir=A", "--dir", "B").failsWithLine4( + f.assertThat("--dir=A", "--dir", "B").failsWithUsageMessage( "Option DIR (--dir) is not repeatable"); - f.assertThat("--dir=A", "--dir=B").failsWithLine4( + f.assertThat("--dir=A", "--dir=B").failsWithUsageMessage( "Option DIR (--dir) is not repeatable"); - f.assertThat("--dir", "A", "--dir=B").failsWithLine4( + f.assertThat("--dir", "A", "--dir=B").failsWithUsageMessage( "Option DIR (--dir) is not repeatable"); } @Test void errorDetachedAttached() { - f.assertThat("--dir", "A", "--dir=B").failsWithLine4("Option DIR (--dir) is not repeatable"); + f.assertThat("--dir", "A", "--dir=B").failsWithUsageMessage("Option DIR (--dir) is not repeatable"); } @Test diff --git a/examples/src/test/java/net/jbock/examples/SimpleArgumentsTest.java b/examples/src/test/java/net/jbock/examples/SimpleArgumentsTest.java index 5ba095813..5971eae37 100644 --- a/examples/src/test/java/net/jbock/examples/SimpleArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/SimpleArgumentsTest.java @@ -12,8 +12,8 @@ class SimpleArgumentsTest { @Test void invalidOptions() { - f.assertThat("xf", "1").failsWithLine4("Invalid option: xf"); - f.assertThat("-xf", "1").failsWithLine4("Invalid option: -xf"); + f.assertThat("xf", "1").failsWithUsageMessage("Invalid option: xf"); + f.assertThat("-xf", "1").failsWithUsageMessage("Invalid option: -xf"); } @Test diff --git a/examples/src/test/java/net/jbock/examples/TarArgumentsTest.java b/examples/src/test/java/net/jbock/examples/TarArgumentsTest.java index fc21656a7..d49d6bee8 100644 --- a/examples/src/test/java/net/jbock/examples/TarArgumentsTest.java +++ b/examples/src/test/java/net/jbock/examples/TarArgumentsTest.java @@ -26,8 +26,8 @@ void testExtract() { @Test void noGrouping() { - f.assertThat("-v", "xf", "foo.tar").failsWithLine4("Invalid option: xf"); - f.assertThat("-v", "-xf", "foo.tar").failsWithLine4("Invalid option: -xf"); + f.assertThat("-v", "xf", "foo.tar").failsWithUsageMessage("Invalid option: xf"); + f.assertThat("-v", "-xf", "foo.tar").failsWithUsageMessage("Invalid option: -xf"); } @Test diff --git a/examples/src/test/java/net/jbock/examples/fixture/ParserTestFixture.java b/examples/src/test/java/net/jbock/examples/fixture/ParserTestFixture.java index 8abf30d57..5dd36c0fc 100644 --- a/examples/src/test/java/net/jbock/examples/fixture/ParserTestFixture.java +++ b/examples/src/test/java/net/jbock/examples/fixture/ParserTestFixture.java @@ -6,6 +6,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -188,15 +189,22 @@ private JsonAssert(Optional parsed, String stdout, String stderr) { this.stderr = stderr; } - public void failsWithLine4(String expectedMessage) { + public void failsWithUsageMessage(String expectedMessage) { if (parsed.isPresent()) { fail("Expecting a failure" + " but parsing was successful"); } assertTrue(stdout.isEmpty()); - assertTrue(stderr.startsWith("Usage:")); - String actualMessage = stderr.split("\\r?\\n", -1)[4].trim(); - assertEquals(expectedMessage, actualMessage); + String[] tokens = stderr.split("\\r?\\n", -1); + for (int i = 0; i < tokens.length; i++) { + String token = tokens[i]; + if (token.startsWith("Usage:")) { + String actualMessage = tokens[i + 4].trim(); + assertEquals(expectedMessage, actualMessage); + return; + } + } + failsWithLines("Usage line not found"); } public void failsWithLines(String... expected) { @@ -206,7 +214,16 @@ public void failsWithLines(String... expected) { } assertTrue(stdout.isEmpty()); String[] actualMessage = stderr.split("\\r?\\n", -1); - compareArrays(expected, actualMessage); + for (int i = 0; i < actualMessage.length; i++) { + String token = actualMessage[i]; + if (token.startsWith("Usage:")) { + String[] copy = new String[actualMessage.length - i]; + System.arraycopy(actualMessage, i, copy, 0, copy.length); + compareArrays(expected, copy); + return; + } + } + failsWithLines("Usage line not found"); } public void satisfies(Predicate predicate) {