package net.raymanoz.migrate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;
import net.raymanoz.command.Command;
import net.raymanoz.command.CommandList;
import net.raymanoz.command.CommandNotFoundException;
import static net.raymanoz.command.UsageCommand.USAGE_COMMAND_STRING;
import org.junit.Test;
import org.junit.Before;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.times;
public class UMigrateTest {
private Command newScriptCommand = mock(Command.class);
private Command newScriptFromCommand = mock(Command.class);
private Command dropCommand = mock(Command.class);
private Command migrateCommand = mock(Command.class);
private Command listCommand = mock(Command.class);
private Command usageCommand = mock(Command.class);
private Command conditionHelpCommand = mock(Command.class);
private Command showConfigCommand = mock(Command.class);
private Command[] allCommands = new Command[]{
newScriptCommand, newScriptFromCommand, migrateCommand, listCommand, usageCommand, conditionHelpCommand, showConfigCommand, dropCommand
};
private CommandList commandList = mock(CommandList.class);
private UMigrate uMigrate = new UMigrate(commandList);
@Before
public void setup() throws CommandNotFoundException{
when(commandList.get("new")).thenReturn(newScriptCommand);
when(commandList.get("new-from")).thenReturn(newScriptFromCommand);
when(commandList.get("drop")).thenReturn(dropCommand);
when(commandList.get("migrate")).thenReturn(migrateCommand);
when(commandList.get("list")).thenReturn(listCommand);
when(commandList.get("usage")).thenReturn(usageCommand);
when(commandList.get("condition-help")).thenReturn(conditionHelpCommand);
when(commandList.get("show-config")).thenReturn(showConfigCommand);
}
private void validateRegisterCommands(InOrder inOrder){
ArgumentCaptor<Command> captorRegisterCommand = ArgumentCaptor.forClass(Command.class);
String[] expectedCmdSts = new String[]{"new","new-from","drop","migrate","list","usage","condition-help", "show-config"};
inOrder.verify(commandList, times(expectedCmdSts.length)).register(captorRegisterCommand.capture());
List<Command> commands = captorRegisterCommand.getAllValues();
assertEquals(expectedCmdSts.length, commands.size());
for (int idx = 0; idx < expectedCmdSts.length; idx++){
assertEquals(expectedCmdSts[idx], commands.get(idx).getCommandString());
}
}
private void assertCanRunCommand(Command expectedToExecute, String ... arguments) {
uMigrate.execute(arguments);
for(Command cmd:allCommands){
if (cmd != expectedToExecute){
verify(cmd, never()).execute(any(String[].class));
}
}
InOrder inOrder = inOrder(commandList, expectedToExecute);
validateRegisterCommands(inOrder);
try {
inOrder.verify(commandList).get(arguments[0]);
} catch (CommandNotFoundException e) {
throw new RuntimeException(e);
}
inOrder.verify(expectedToExecute).execute(arguments);
}
private void assertUsageCommandRun(String ... arguments) {
uMigrate.execute(arguments);
for(Command cmd:allCommands){
verify(cmd, never()).execute(any(String[].class));
if (cmd != usageCommand){
verify(cmd, never()).execute();
}
}
InOrder inOrder = inOrder(commandList, usageCommand);
validateRegisterCommands(inOrder);
try {
if (arguments.length > 0) inOrder.verify(commandList).get(arguments[0]);
if (arguments.length > 0) inOrder.verify(commandList).get(USAGE_COMMAND_STRING);
} catch (CommandNotFoundException e) {
throw new RuntimeException(e);
}
inOrder.verify(usageCommand).execute();
}
@Test
public void canRunNewScriptCommand() {
assertCanRunCommand(newScriptCommand, "new", "action", "account");
}
@Test
public void canRunGenerateDropScriptCommand() {
assertCanRunCommand(dropCommand, "drop", "table", "thistable", "myAccount");
}
@Test
public void canRunNewFromScriptCommand() {
assertCanRunCommand(newScriptFromCommand, "new-from", "filename", "account");
}
@Test
public void canRunMigrateCommand() {
assertCanRunCommand(migrateCommand, "migrate");
}
@Test
public void canRunUsageCommand() {
assertCanRunCommand(usageCommand, "usage");
}
@Test
public void canRunConditionHelp() {
assertCanRunCommand(conditionHelpCommand, "condition-help");
}
@Test
public void canRunShowConfiguration() {
assertCanRunCommand(showConfigCommand, "show-config");
}
@Test
public void usageCommandDisplayedForUnknownCommand() throws CommandNotFoundException {
final String unknownCommand = "This is an Unknown Command";
ByteArrayOutputStream output = new ByteArrayOutputStream();
when(commandList.get(unknownCommand)).thenThrow(new CommandNotFoundException(unknownCommand));
System.setOut(new PrintStream(output, true));
assertUsageCommandRun(unknownCommand);
assertTrue("Unknown command should have displayed error Message", output.toString().contains("Unknown Command: " + unknownCommand));
}
@Test
public void capturesProblemInScriptList() throws CommandNotFoundException {
final String theMessage = "A Test Message to check displayed";
ByteArrayOutputStream output = new ByteArrayOutputStream();
doThrow(new ProblemInScriptListNumbers(theMessage)).when(migrateCommand).execute(new String[]{"migrate"});
System.setOut(new PrintStream(output, true));
assertCanRunCommand(migrateCommand, "migrate");
assertTrue(output.toString().contains(theMessage));
}
@Test
public void usageCommandDisplayedForNoCommand() {
assertUsageCommandRun();
}
}