package com.oracle.truffle.js.test.external.nashorn;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import com.oracle.truffle.js.test.external.suite.SuiteConfig;
import com.oracle.truffle.js.test.external.suite.TestFile;
import com.oracle.truffle.js.test.external.suite.TestRunnable;
import com.oracle.truffle.js.test.external.suite.TestSuite;
public class TestNashorn extends TestSuite {
private static final String SUITE_NAME = "testnashorn";
private static final String SUITE_DESCRIPTION = "Nashorn testsuite";
private static final String DEFAULT_LOC = "";
private static final String DEFAULT_CONFIG_LOC = Paths.get("..", "..", "test").toString();
private static final String TESTS_REL_LOC = Paths.get("test", "script").toString();
private static final String HARNESS_REL_LOC = "";
private static final String[] TEST_DIRS = new String[]{"basic", "error"};
private static final String TESTS_CONFIG_FILE = "testNashorn.json";
private static final String FAILED_TESTS_FILE = "testnashorn.failed";
private final PrintStream origOut;
private final PrintStream origErr;
private static final boolean isWindows = System.getProperty("os.name").startsWith("Windows");
private static Boolean useNashornDiffBat;
public TestNashorn(SuiteConfig config) {
super(config);
origOut = System.out;
origErr = System.err;
}
@Override
public String[] getPrequelFiles(int ecmaVersion) {
throw new UnsupportedOperationException();
}
@Override
public TestRunnable createTestRunnable(TestFile file) {
return new TestNashornRunnable(this, file);
}
@Override
protected File getTestsConfigFile() {
return Paths.get(getConfig().getSuiteConfigLoc(), TESTS_CONFIG_FILE).toFile();
}
@Override
protected File getUnexpectedlyFailedTestsFile() {
return new File(FAILED_TESTS_FILE);
}
@Override
protected String formatLogFailHTML(String filename, String failMessage, String reason) {
String linkSource = formatLink(getConfig().getSuiteTestsLoc() + filename, filename, false);
String linkExpected = formatLink(getConfig().getSuiteTestsLoc() + filename + ".EXPECTED", "EXPECTED", true);
StringBuilder html = new StringBuilder(200);
html.append(failMessage);
html.append(' ').append(linkSource);
html.append(' ').append(linkExpected);
if (getConfig().isSaveOutput()) {
String outputFileName = Paths.get(getConfig().getSuiteLoc(), "output", toFlatName(filename)).toString();
String linkDiff = formatLink(outputFileName + ".DIFF", "DIFF", false);
String linkResult = formatLink(outputFileName + ".RESULT", "RESULT", false);
html.append(' ').append(linkResult);
html.append(' ').append(linkDiff);
}
html.append(' ').append(reason);
return html.toString();
}
private static String formatLink(String fileName, String description, boolean checkFile) {
if (!checkFile || new File(fileName).exists()) {
return "<a href=\"" + fileName + "\">" + description + "</a>";
} else {
return description;
}
}
@Override
public String getHTMLFileName() {
return "testnashorn.htm";
}
@Override
public String getReportFileName() {
return "testnashorn.txt";
}
@Override
public Map<String, String> getCommonOptions() {
return Collections.emptyMap();
}
@Override
public List<String> getCommonExtLauncherOptions() {
return Collections.emptyList();
}
public static void writeResult(String name, String result) {
try {
String flatName = toFlatName(name);
String resultFileName = "output" + File.separator + flatName + ".RESULT";
String expectedFileName = "test" + File.separator + "script" + File.separator + name + ".EXPECTED";
String diffFileName = "output" + File.separator + flatName + ".DIFF";
try (FileWriter writer = new FileWriter(resultFileName)) {
writer.write(result);
}
String[] diffCmd;
if (isWindows) {
if (useNashornDiffBat == null) {
diffCmd = new String[]{"nashorndiff.bat", expectedFileName, resultFileName, diffFileName};
try {
Process p = Runtime.getRuntime().exec(diffCmd);
p.waitFor();
useNashornDiffBat = true;
} catch (IOException ioex) {
useNashornDiffBat = false;
}
return;
}
if (useNashornDiffBat) {
diffCmd = new String[]{"nashorndiff.bat", expectedFileName, resultFileName, diffFileName};
} else {
diffCmd = new String[]{"cmd", "/C", String.format("fc \"%s\" \"%s\" > \"%s\"", expectedFileName, resultFileName, diffFileName)};
}
} else {
diffCmd = new String[]{"bash", "-c", String.format("diff -u '%s' '%s' > '%s'", expectedFileName, resultFileName, diffFileName)};
}
Process p = Runtime.getRuntime().exec(diffCmd);
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
private static String toFlatName(String name) {
return name.replace("/", "_").replace("\\", "_");
}
private static void initializeSaveOutput() {
File outputDir = new File("output");
outputDir.mkdir();
File[] files = outputDir.listFiles();
if (files != null) {
for (File f : files) {
String name = f.getName();
if (name.endsWith(".DIFF") || name.endsWith(".RESULT")) {
f.delete();
}
}
}
}
@Override
protected void printSkippedFilesHTML(PrintStream stream, List<TestFile> skippedFiles) {
stream.println("<ul>");
for (TestFile testFile : skippedFiles) {
String filePath = testFile.getFilePath();
String linkSource = formatLink(getConfig().getSuiteTestsLoc() + filePath, filePath, false);
String linkExpected = formatLink(getConfig().getSuiteTestsLoc() + filePath + ".EXPECTED", "EXPECTED", true);
stream.println("<li>" + linkSource + " " + linkExpected + "</li>");
}
stream.println("</ul>");
}
private static void exit(int status) {
System.exit(status);
}
public static void main(String[] args) throws Exception {
SuiteConfig.Builder configBuilder = new SuiteConfig.Builder(SUITE_NAME, SUITE_DESCRIPTION, DEFAULT_LOC, DEFAULT_CONFIG_LOC, TESTS_REL_LOC, HARNESS_REL_LOC);
Locale.setDefault(Locale.US);
TimeZone pstZone = TimeZone.getTimeZone("PST");
TimeZone.setDefault(pstZone);
System.out.println("Checking your Javascript conformance. Using Nashorn testsuite.\n");
TestSuite.parseDefaultArgs(args, configBuilder);
if (configBuilder.getEndsWithFilter() != null) {
configBuilder.setSaveOutput(true);
configBuilder.setHtmlOutput(true);
}
SuiteConfig config = configBuilder.build();
if (config.isSaveOutput()) {
initializeSaveOutput();
}
TestNashorn suite = new TestNashorn(config);
exit(suite.runTestSuite(TEST_DIRS));
}
public PrintStream getOrigOut() {
return origOut;
}
public PrintStream getOrigErr() {
return origErr;
}
}