/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.v8; import static com.github.anba.es6draft.util.Resources.loadConfiguration; import static com.github.anba.es6draft.util.Resources.loadTests; import static org.junit.Assume.assumeTrue; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Iterator; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.configuration.Configuration; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; import org.junit.runner.RunWith; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; import org.junit.runners.Parameterized.UseParametersRunnerFactory; import com.github.anba.es6draft.util.NullConsole; import com.github.anba.es6draft.util.Parallelized; import com.github.anba.es6draft.util.ParameterizedRunnerFactory; import com.github.anba.es6draft.util.TestConfiguration; import com.github.anba.es6draft.util.TestGlobals; import com.github.anba.es6draft.util.TestInfo; import com.github.anba.es6draft.util.rules.ExceptionHandlers.ScriptExceptionHandler; import com.github.anba.es6draft.util.rules.ExceptionHandlers.StandardErrorHandler; /** * */ @RunWith(Parallelized.class) @UseParametersRunnerFactory(ParameterizedRunnerFactory.class) @TestConfiguration(name = "v8.test.mjsunit", file = "resource:/test-configuration.properties") public final class MiniJSUnitTest { private static final Configuration configuration = loadConfiguration(MiniJSUnitTest.class); @Parameters(name = "{0}") public static List<V8TestInfo> suiteValues() throws IOException { return loadTests(configuration, MiniJSUnitTest::createTest); } @BeforeClass public static void setUpClass() throws IOException { V8TestGlobalObject.testLoadInitializationScript(); } @ClassRule public static TestGlobals<V8TestGlobalObject, TestInfo> globals = new TestGlobals<>(configuration, V8TestGlobalObject::new); @Rule public Timeout maxTime = new Timeout(120, TimeUnit.SECONDS); @Rule public StandardErrorHandler errorHandler = new StandardErrorHandler(); @Rule public ScriptExceptionHandler exceptionHandler = new ScriptExceptionHandler(); @Parameter(0) public V8TestInfo test; private static final class V8TestInfo extends TestInfo { private boolean module = false; public V8TestInfo(Path basedir, Path file) { super(basedir, file); } @Override public boolean isModule() { return module; } } private V8TestGlobalObject global; @Before public void setUp() throws Throwable { assumeTrue("Test disabled", test.isEnabled()); global = globals.newGlobal(new NullConsole(), test); exceptionHandler.setExecutionContext(global.getRealm().defaultContext()); } @After public void tearDown() { globals.release(global); } @Test public void runTest() throws Throwable { if (test.isModule()) { global.eval(test.toModuleName()); } else { global.eval(test.getScript(), test.toFile()); } // Wait for pending tasks to finish global.getRealm().getWorld().runEventLoop(); } private static final Pattern FlagsPattern = Pattern.compile("\\s*//\\s*Flags:\\s*(.*)\\s*"); private static BiFunction<Path, Iterator<String>, V8TestInfo> createTest(Path basedir) { return (file, lines) -> { V8TestInfo test = new V8TestInfo(basedir, file); Pattern p = FlagsPattern; while (lines.hasNext()) { String line = lines.next(); Matcher m = p.matcher(line); if (m.matches()) { String[] flags = m.group(1).split("\\s+"); for (int i = 0, len = flags.length; i < len; ++i) { String flag = flags[i].replace('_', '-'); if (flag.startsWith("--expose-debug-as")) { if (flag.equals("--expose-debug-as")) { // two arguments form, consume next argument as well ++i; } // don't run debug-mode tests test.setEnabled(false); } else if (flag.startsWith("--expose-natives-as")) { // don't run tests with natives or lazy compilation if (flag.equals("--expose-natives-as")) { // two arguments form, consume next argument as well ++i; } test.setEnabled(false); } else if (flag.equals("--expose-externalize-string")) { // don't run tests with externalize-string test.setEnabled(false); } else if (flag.equals("--allow-natives-syntax") && containsNativeSyntax(test.toFile())) { // don't run tests with native syntax test.setEnabled(false); } else if (flag.equals("--lazy")) { // don't run tests with lazy compilation test.setEnabled(false); } else if (flag.equals("--expose-trigger-failure")) { // don't run tests with trigger-failure test.setEnabled(false); } else if (flag.equals("--mock-arraybuffer-allocator")) { // don't run tests with mock allocator test.setEnabled(false); } else { // ignore other flags } } } else if (line.equals("// MODULE")) { test.module = true; } } return test; }; } private static boolean containsNativeSyntax(Path p) { try { String content = new String(Files.readAllBytes(p), StandardCharsets.UTF_8); return content.indexOf('%') != -1; } catch (IOException e) { throw new UncheckedIOException(e); } } }