/** * Copyright 2013 Cloudera Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.kitesdk.cli; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import java.io.IOException; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; public class TestMain { private static class SomeException extends RuntimeException { private SomeException(String message) { super(message); } } @Parameters(commandDescription = "Test description") static class TestCommand implements Command { @Parameter(description = "<test dataset names>") List<String> datasets; @Parameter(names = "--throw-arg", description = "Causes an IllegalArugmentException", hidden = true) boolean throwArg = false; @Parameter(names = "--throw-state", description = "Causes an IllegalStateException", hidden = true) boolean throwState = false; @Parameter(names = "--throw-unknown", description = "Causes an unknown exception", hidden = true) boolean throwUnknown = false; @Override public int run() throws IOException { Preconditions.checkArgument(!throwArg, "--throw-arg was set"); Preconditions.checkState(!throwState, "--throw-state was set"); if (throwUnknown) { throw new SomeException("--throw-unknown was set"); } return 0; } @Override public List<String> getExamples() { return Lists.newArrayList("# this is a comment", "test dataset-name"); } } private Logger console; private Main main; @Before public void initializeMain() { this.console = mock(Logger.class); this.main = new Main(console); Command test = new TestCommand(); main.jc.addCommand("test", test); } @After public void tearDown() { // TODO: check line lengths < 80 } @Test public void testNoArgs() throws Exception { int rc = run(); verify(console).info( contains("Usage: {} [options] [command] [command options]"), eq(Main.DEFAULT_PROGRAM_NAME)); assertEquals(1, rc); } @Test public void testUnrecognizedCommand() throws Exception { int rc = run("unrecognizedcommand"); verify(console).error(startsWith("Expected a command, got unrecognizedcommand")); assertEquals(1, rc); } @Test public void testHelp() throws Exception { int rc = run("help"); verify(console).info( contains("Usage: {} [options] [command] [command options]"), eq(Main.DEFAULT_PROGRAM_NAME)); verify(console).info(contains("Options")); verify(console, times(2)).info(anyString(), any(Object[].class)); // -v, --version verify(console).info(contains("Commands")); verify(console).info(anyString(), eq("create"), anyString()); verify(console).info(anyString(), eq("delete"), anyString()); verify(console).info(anyString(), eq("help"), anyString()); verify(console).info(anyString(), eq("schema"), anyString()); verify(console).info(anyString(), eq("csv-schema"), anyString()); verify(console).info(anyString(), eq("test"), eq("Test description")); verify(console).info(contains("Examples")); verify(console).info(contains("{} help create"), eq(Main.DEFAULT_PROGRAM_NAME)); verify(console).info( contains("See '{} help <command>' for more information"), eq(Main.DEFAULT_PROGRAM_NAME)); assertEquals(0, rc); } @Test public void testHelpCommand() throws Exception { int rc = run("help", "test"); verify(console).info( "\nUsage: {} [general options] {} {} [command options]", new Object[]{ Main.DEFAULT_PROGRAM_NAME, "test", "<test dataset names>" }); verify(console).info(contains("Description")); verify(console).info(anyString(), contains("Test description")); verify(console).info(contains("Command options")); verify(console).info(contains("Examples")); verify(console).info(anyString(), contains("# this is a comment")); verify(console).info(anyString(), eq(new Object[] {Main.DEFAULT_PROGRAM_NAME, "test", "test dataset-name"})); assertEquals(0, rc); } @Test public void testCommandHelp() throws Exception { int rc = run("test", "--help"); verify(console).info( "\nUsage: {} [general options] {} {} [command options]", new Object[]{ Main.DEFAULT_PROGRAM_NAME, "test", "<test dataset names>" }); verify(console).info(contains("Description")); verify(console).info(anyString(), contains("Test description")); verify(console).info(contains("Command options")); verify(console).info(contains("Examples")); verify(console).info(anyString(), contains("this is a comment")); verify(console).info(anyString(), eq(new Object[] {Main.DEFAULT_PROGRAM_NAME, "test", "test dataset-name"})); assertEquals(0, rc); } @Test public void testCommandHelpWithDollarZero() throws Exception { int rc = run("--dollar-zero", "datasets", "test", "--help"); verify(console).info( "\nUsage: {} [general options] {} {} [command options]", new Object[]{ "datasets", "test", "<test dataset names>" }); verify(console).info(contains("Description")); verify(console).info(anyString(), contains("Test description")); verify(console).info(contains("Command options")); verify(console).info(contains("Examples")); verify(console).info(anyString(), contains("this is a comment")); verify(console).info(anyString(), eq(new Object[] {"datasets", "test", "test dataset-name"})); assertEquals(0, rc); } @Test public void testVersion() throws Exception { int rc = run("--version"); verify(console).info(contains("Kite version"), anyString()); assertEquals(0, rc); } @Test public void testUnknownCommand() throws Exception { int rc = run("help", "unknown"); verify(console).error( contains("Unknown command"), eq("unknown")); assertEquals(1, rc); } @Test public void testIllegalArguments() throws Exception { int rc = run("test", "--throw-arg"); verify(console).error( startsWith("Argument error"), eq("--throw-arg was set")); assertEquals(1, rc); } @Test public void testIllegalState() throws Exception { int rc = run("test", "--throw-state"); verify(console).error( startsWith("State error"), eq("--throw-state was set")); assertEquals(1, rc); } @Test public void testUnexpectedException() throws Exception { int rc = run("test", "--throw-unknown"); verify(console).error( startsWith("Unknown error"), eq("--throw-unknown was set")); assertEquals(1, rc); } @Test public void testUnexpectedExceptionWithDebug() throws Exception { int rc = run("--debug", "test", "--throw-unknown"); verify(console).error( startsWith("Unknown error"), isA(SomeException.class)); assertEquals(1, rc); } private int run(String... args) throws Exception { return main.run(args); } }