package org.approvaltests.reporters;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import com.spun.util.SystemUtils;
import com.spun.util.ThreadUtils;
import com.spun.util.io.FileUtils;
public class GenericDiffReporter implements EnvironmentAwareReporter
{
public static final String STANDARD_ARGUMENTS = "%s %s";
public static boolean REPORT_MISSING_FILES = false;
protected String diffProgram;
protected String arguments;
protected String diffProgramNotFoundMessage;
private List<String> validExtensions;
public static List<String> TEXT_FILE_EXTENSIONS = Arrays.asList(".txt", ".csv", ".htm", ".html", ".xml", ".eml",
".java", ".css", ".js", ".json");
public static List<String> IMAGE_FILE_EXTENSIONS = Arrays.asList(".png", ".gif", ".jpg", ".jpeg", ".bmp", ".tif",
".tiff");
public GenericDiffReporter(String diffProgram, String diffProgramNotFoundMessage)
{
this(diffProgram, STANDARD_ARGUMENTS, diffProgramNotFoundMessage);
}
private GenericDiffReporter(String diffProgram, String argumentsFormat, String diffProgramNotFoundMessage)
{
this(diffProgram, argumentsFormat, diffProgramNotFoundMessage, TEXT_FILE_EXTENSIONS);
}
public GenericDiffReporter(String diffProgram, String argumentsFormat, String diffProgramNotFoundMessage,
List<String> validFileExtensions)
{
this.diffProgram = diffProgram;
this.arguments = argumentsFormat;
this.diffProgramNotFoundMessage = diffProgramNotFoundMessage;
validExtensions = validFileExtensions;
}
public GenericDiffReporter(DiffInfo info)
{
this(info.diffProgram, info.parameters,
MessageFormat.format("Unable to find program at {0}", info.diffProgram), info.fileExtensions);
}
@Override
public void report(String received, String approved) throws Exception
{
if (!isWorkingInThisEnvironment(received)) { throw new RuntimeException(diffProgramNotFoundMessage); }
FileUtils.createIfNeeded(approved);
launch(received, approved);
}
private void launch(String received, String approved) throws IOException
{
ProcessBuilder builder = new ProcessBuilder(getCommandLine(received, approved));
preventProcessFromClosing(builder);
Process process = builder.start();
ThreadUtils.sleep(800); //Give program time to start
}
private void preventProcessFromClosing(ProcessBuilder builder)
{
if (!SystemUtils.isWindowsEnviroment())
{
File output = new File("/dev/null");
builder.redirectError(output).redirectOutput(output);
}
}
public String[] getCommandLine(String received, String approved)
{
String[] p = arguments.split(" ");
String r = String.format(p[0], received);
String a = String.format(p[1], approved);
String[] commands = new String[]{diffProgram, r, a};
System.out.println(Arrays.toString(commands));
return commands;
}
@Override
public boolean isWorkingInThisEnvironment(String forFile)
{
return checkFileExists() && isFileExtensionHandled(forFile);
}
public boolean checkFileExists()
{
boolean exists = new File(diffProgram).exists();
if (REPORT_MISSING_FILES && !exists)
{
System.out.println(String.format("%s can't find '%s'", this.getClass().getSimpleName(), diffProgram));
}
return exists;
}
public boolean isFileExtensionHandled(String forFile)
{
return isFileExtensionValid(forFile, validExtensions);
}
public static boolean isFileExtensionValid(String forFile, List<String> validExtensionsWithDot)
{
String extensionWithDot = FileUtils.getExtensionWithDot(forFile);
return validExtensionsWithDot.contains(extensionWithDot);
}
}