Skip to content

Commit

Permalink
#571 add more tests to improve test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
remkop committed Dec 19, 2018
1 parent 558404c commit 873b614
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/main/java/picocli/CommandLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -2153,9 +2153,7 @@ public static Object invoke(String methodName, Class<?> cls, PrintStream out, Pr
* @since 3.6.0
*/
public static List<Method> getCommandMethods(Class<?> cls, String methodName) {
Set<Method> candidates = new TreeSet<Method>(new Comparator<Method>() {
public int compare(Method o1, Method o2) { return o1.getName().compareTo(o2.getName()); }
});
Set<Method> candidates = new HashSet<Method>();
// traverse public member methods (excludes static/non-public, includes inherited)
candidates.addAll(Arrays.asList(Assert.notNull(cls, "class").getMethods()));
// traverse directly declared methods (includes static/non-public, excludes inherited)
Expand All @@ -2167,6 +2165,9 @@ public static List<Method> getCommandMethods(Class<?> cls, String methodName) {
if (methodName == null || methodName.equals(method.getName())) { result.add(method); }
}
}
Collections.sort(result, new Comparator<Method>() {
public int compare(Method o1, Method o2) { return o1.getName().compareTo(o2.getName()); }
});
return result;
}

Expand Down Expand Up @@ -2350,7 +2351,7 @@ public CommandLine setAtFileCommentChar(Character atFileCommentChar) {
private static boolean isMultiValue(Class<?> cls) { return cls.isArray() || Collection.class.isAssignableFrom(cls) || Map.class.isAssignableFrom(cls); }

private static class NoCompletionCandidates implements Iterable<String> {
public Iterator<String> iterator() { return Collections.<String>emptyList().iterator(); }
public Iterator<String> iterator() { throw new UnsupportedOperationException(); }
}
/**
* <p>
Expand Down
20 changes: 20 additions & 0 deletions src/test/java/picocli/CommandLineCommandMethodTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,11 @@ public void testStaticCommandMethod() {
assertEquals(9, CommandLine.invoke("staticCommand", StaticMethodCommand.class, "-x", "3"));
}

@Test
public void testInvokeMethodClassPrintStreamAnsi() {
assertEquals(9, CommandLine.invoke("staticCommand", StaticMethodCommand.class, System.out, Help.Ansi.OFF, "-x", "3"));
}

@Test
public void testCommandMethodsRequireNonArgConstructor() {
try {
Expand Down Expand Up @@ -969,4 +974,19 @@ public void testCommandMethodsUnexpectedError() throws Exception {
assertTrue(actual.getMessage(), actual.getMessage().startsWith("Unhandled error while calling command ("));
}
}

static class Duplicate {
@Command int mycommand() { return 1; }

@Command int mycommand(String[] args) { return 2;}
}

@Test
public void testDuplicateCommandMethodNames() {
try {
CommandLine.invoke("mycommand", Duplicate.class, System.out, System.out, Help.Ansi.OFF, "abd");
} catch (InitializationException ex) {
assertTrue(ex.getMessage().startsWith("Expected exactly one @Command-annotated method for "));
}
}
}
9 changes: 9 additions & 0 deletions src/test/java/picocli/CommandLineDefaultProviderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ public void testDefaultProviderNullByDefault() {
assertNull(cmd.getDefaultValueProvider());
}

@Test(expected = UnsupportedOperationException.class)
public void testNoDefaultProviderThrowsUnsupportedOperation() throws Exception {
Class<IDefaultValueProvider> c = (Class<IDefaultValueProvider>) Class.forName("picocli.CommandLine$NoDefaultProvider");

IDefaultValueProvider provider = CommandLine.defaultFactory().create(c);
assertNotNull(provider);
provider.defaultValue(CommandLine.Model.PositionalParamSpec.builder().build());
}

@Test
public void testDefaultProviderReturnsSetValue() {
CommandLine cmd = new CommandLine(Sub.class);
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/picocli/CommandLineHelpTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3945,4 +3945,21 @@ public void testCustomizableHelpSections() {
"Usage: <header> (<custom header param>)%n");
assertEquals(expected, commandLineWithCustomHelpSections.getUsageMessage(Help.Ansi.OFF));
}

@Test
public void testNullSectionRenderer() {
CommandLine cmd = new CommandLine(new UsageDemo());

cmd.getHelpSectionMap().clear();
cmd.getHelpSectionMap().put(UsageMessageSpec.SECTION_KEY_HEADER, null);
cmd.getHelpSectionMap().put(UsageMessageSpec.SECTION_KEY_DESCRIPTION, new IHelpSectionRenderer() {
public String render(Help help) {
return "abc";
}
});

String actual = cmd.getUsageMessage();
String expected = "abc";
assertEquals(expected, actual);
}
}
56 changes: 56 additions & 0 deletions src/test/java/picocli/CommandLineParseWithHandlersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -806,4 +806,60 @@ public void testRunAllSelf() {
RunAll runAll = new RunAll();
assertSame(runAll, runAll.self());
}

@Test
public void testHandlerThrowsOtherException() {
@Command
class App { }

try {
new CommandLine(new App()).parseWithHandler(new IParseResultHandler2<Object>() {
public Object handleParseResult(ParseResult parseResult) throws ExecutionException {
throw new IllegalArgumentException("abc");
}
}, new String[0]);
} catch (IllegalArgumentException ex) {
assertEquals("abc", ex.getMessage());
}
}

@Test
public void testHandlerThrowsExecutionException() {
@Command
class App { }

try {
new CommandLine(new App()).parseWithHandler(new IParseResultHandler2<Object>() {
public Object handleParseResult(ParseResult parseResult) throws ExecutionException {
throw new ExecutionException(new CommandLine(new App()), "xyz");
}
}, new String[0]);
} catch (ExecutionException ex) {
assertEquals("xyz", ex.getMessage());
}
}

@Command
static class Executable implements Runnable, Callable<Void> {

@Option(names = "-x") int x;

public void run() { }

public Void call() throws Exception {
return null;
}
}

@Test
public void testCallNullResult() {
Object result = CommandLine.call(new Executable(), "-x");
assertNull(result);
}

@Test
public void testCallableClassNullResult() {
Object result = CommandLine.call(Executable.class, CommandLine.defaultFactory(), "-x");
assertNull(result);
}
}
19 changes: 19 additions & 0 deletions src/test/java/picocli/CommandLineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.Socket;
Expand Down Expand Up @@ -3658,4 +3659,22 @@ private String base64(byte[] arr) throws Exception {
System.setIn(in);
}
}

@Test
public void testEmptyObjectArray() throws Exception {
Method m = CommandLine.class.getDeclaredMethod("empty", new Class[] {Object[].class});
m.setAccessible(true);

assertTrue((Boolean) m.invoke(null, new Object[] {null}));
assertTrue((Boolean) m.invoke(null, new Object[] {new String[0]}));
}

@Test
public void testStr() throws Exception {
Method m = CommandLine.class.getDeclaredMethod("str", String[].class, int.class);
m.setAccessible(true);

assertEquals("", m.invoke(null, null, 0));
assertEquals("", m.invoke(null, new String[0], 1));
}
}
20 changes: 20 additions & 0 deletions src/test/java/picocli/CompletionCandidatesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,24 @@ class EnumTest {
" javascript, frege, clojure%n");
assertEquals(expected, new CommandLine(new EnumTest()).getUsageMessage());
}

@Test
public void testDefaultCompletionCandidatesNull() {
class App {
@Option(names = "-x") int x;
}

CommandLine cmd = new CommandLine(new App());
Iterable<String> candidates = cmd.getCommandSpec().findOption('x').completionCandidates();
assertNull(candidates);
}

@Test(expected = UnsupportedOperationException.class)
public void testNoCompletionCandidatesThrowsUnsupportedOperation() throws Exception {
Class<Iterable<String>> c = (Class<Iterable<String>>) Class.forName("picocli.CommandLine$NoCompletionCandidates");

Iterable<String> iterable = CommandLine.defaultFactory().create(c);
assertNotNull(iterable);
iterable.iterator();
}
}

0 comments on commit 873b614

Please sign in to comment.