package com.prezi.haxe.gradle;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.google.common.io.Resources;
import org.apache.commons.io.FileUtils;
import org.gradle.api.internal.ConventionTask;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.TaskAction;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.regex.Pattern;
public class MUnit extends ConventionTask {
private static final Pattern SUCCESSFUL_TEST_PATTERN = Pattern.compile("(?m)^PLATFORMS TESTED: \\d+, PASSED: \\d+, FAILED: 0, ERRORS: 0, TIME:");
private String targetPlatform;
private File inputFile;
private File workingDirectory;
@Input
public String getTargetPlatform() {
return targetPlatform;
}
public void setTargetPlatform(String targetPlatform) {
this.targetPlatform = targetPlatform;
}
public void targetPlatform(String targetPlatform) {
this.targetPlatform = targetPlatform;
}
@InputFile
public File getInputFile() {
return inputFile;
}
public void setInputFile(Object file) {
this.inputFile = getProject().file(file);
}
public void inputFile(Object file) {
setInputFile(file);
}
@TaskAction
public void munit() throws IOException, InterruptedException {
File workDir = getWorkingDirectory();
FileUtils.deleteDirectory(workDir);
FileUtils.forceMkdir(workDir);
prepareEnvironment(workDir);
if (getProject().hasProperty("munit.skiprunner")) {
return;
}
final List<String> cmd = getMUnitCommandLine();
CommandExecutor.execute(cmd, getWorkingDirectory(), new DefaultExecutionResultHandler(cmd) {
@Override
public void handleResult(int exitValue, String output) {
super.handleResult(exitValue, output);
if (!isTestSuccessful(output)) {
throw new RuntimeException("There are failing tests");
}
}
@Override
protected boolean shouldPrintResult(int exitValue, String output) {
return super.shouldPrintResult(exitValue, output) || !isTestSuccessful(output);
}
private boolean isTestSuccessful(String output) {
return SUCCESSFUL_TEST_PATTERN.matcher(output).find();
}
});
}
protected List<String> getMUnitCommandLine() {
return new MUnitCommandBuilder(getProject()).build();
}
protected void prepareEnvironment(File workDir) throws IOException {
final String testBinaryName = copyCompiledTest(workDir);
File testHxml = new File(workDir, "test.hxml");
Files.write("-" + getTargetPlatform() + " " + testBinaryName + "\n", testHxml, Charsets.UTF_8);
File munitConfig = new File(workDir, ".munit");
Files.write("bin=.\n"
+ "report=report\n"
+ "hxml=test.hxml\n"
+ "resources=.\n",
munitConfig, Charsets.UTF_8);
// Issue #1 -- Use UTF-8 compatible JS runner template
if (getTargetPlatform().equals("js")) {
Files.append("templates=templates\n", munitConfig, Charsets.UTF_8);
File templatesDir = new File(workDir, "templates");
FileUtils.forceMkdir(templatesDir);
File jsRunnerTemplate = new File(templatesDir, "js_runner-html.mtt");
Files.copy(Resources.newInputStreamSupplier(getMUnitJsHtmlTemplate()), jsRunnerTemplate);
}
}
protected String copyCompiledTest(File workDir) throws IOException {
String testBinaryName = getTargetPlatform() + "_test.js";
File testFile = new File(workDir, testBinaryName);
getLogger().debug("Copying test file from {} to {}", getInputFile(), testFile);
Files.copy(getInputFile(), testFile);
return ((String) (testBinaryName));
}
public File getWorkingDirectory() {
return workingDirectory;
}
public void setWorkingDirectory(Object workingDirectory) {
this.workingDirectory = getProject().file(workingDirectory);
}
public void workingDirectory(Object workingDirectory) {
setWorkingDirectory(workingDirectory);
}
protected URL getMUnitJsHtmlTemplate() {
return this.getClass().getResource("/js_runner-html.mtt");
}
public boolean shouldRunAutomatically() {
return getProject().hasProperty("munit.usebrowser") && !getProject().property("munit.usebrowser").equals("false");
}
}