| /* |
| * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| package jdk.nashorn.api.tree.test; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.charset.Charset; |
| import java.nio.charset.StandardCharsets; |
| import java.nio.file.Files; |
| import jdk.nashorn.api.tree.Parser; |
| import jdk.nashorn.api.tree.SimpleTreeVisitorES5_1; |
| import jdk.nashorn.api.tree.Tree; |
| import org.testng.Assert; |
| import org.testng.annotations.Test; |
| |
| /** |
| * Test for nashorn Parser API (jdk.nashorn.api.tree.*) |
| * |
| * @test |
| * @run testng jdk.nashorn.api.tree.test.ParseAPITest |
| */ |
| public class ParseAPITest { |
| |
| private static final boolean VERBOSE = Boolean.valueOf(System.getProperty("parserapitest.verbose")); |
| private static final boolean TEST262 = Boolean.valueOf(System.getProperty("parserapitest.test262")); |
| |
| private static final String TEST_BASIC_DIR; |
| private static final String TEST_MAPTESTS_DIR; |
| private static final String TEST_SANDBOX_DIR; |
| private static final String TEST_TRUSTED_DIR; |
| private static final String TEST262_SUITE_DIR; |
| |
| static { |
| final String testSrc = System.getProperty("test.src"); |
| if (testSrc != null) { |
| final String testScriptDir = testSrc + "/../../../../../../script/"; |
| TEST_BASIC_DIR = testScriptDir + "basic"; |
| TEST_MAPTESTS_DIR = testScriptDir + "maptests"; |
| TEST_SANDBOX_DIR = testScriptDir + "sandbox"; |
| TEST_TRUSTED_DIR = testScriptDir + "trusted"; |
| TEST262_SUITE_DIR = testScriptDir + "external/test262/test/suite"; |
| } else { |
| TEST_BASIC_DIR = System.getProperty("test.basic.dir"); |
| TEST_MAPTESTS_DIR = System.getProperty("test.maptests.dir"); |
| TEST_SANDBOX_DIR = System.getProperty("test.sandbox.dir"); |
| TEST_TRUSTED_DIR = System.getProperty("test.trusted.dir"); |
| TEST262_SUITE_DIR = System.getProperty("test262.suite.dir"); |
| } |
| } |
| |
| interface TestFilter { |
| public boolean exclude(File file, String content); |
| } |
| |
| private void log(final String msg) { |
| org.testng.Reporter.log(msg, true); |
| } |
| |
| private static final String[] options = new String[] { |
| "-scripting", "--const-as-var" |
| }; |
| |
| @Test |
| public void parseAllTests() { |
| if (TEST262) { |
| parseTestSet(TEST262_SUITE_DIR, new TestFilter() { |
| @Override |
| public boolean exclude(final File file, final String content) { |
| return content.contains("@negative"); |
| } |
| }); |
| } |
| parseTestSet(TEST_BASIC_DIR, new TestFilter() { |
| @Override |
| public boolean exclude(final File file, final String content) { |
| return file.getParentFile().getName().equals("es6"); |
| } |
| }); |
| parseTestSet(TEST_MAPTESTS_DIR, null); |
| parseTestSet(TEST_SANDBOX_DIR, null); |
| parseTestSet(TEST_TRUSTED_DIR, null); |
| } |
| |
| private void parseTestSet(final String testSet, final TestFilter filter) { |
| passed = 0; |
| failed = 0; |
| skipped = 0; |
| |
| final File testSetDir = new File(testSet); |
| if (! testSetDir.isDirectory()) { |
| log("WARNING: " + testSetDir + " not found or not a directory"); |
| return; |
| } |
| log(testSetDir.getAbsolutePath()); |
| parseJSDirectory(testSetDir, filter); |
| |
| log(testSet + " parse API done!"); |
| log("parse API ok: " + passed); |
| log("parse API failed: " + failed); |
| log("parse API skipped: " + skipped); |
| if (failed != 0) { |
| Assert.fail(failed + " tests failed to parse in " + testSetDir.getAbsolutePath()); |
| } |
| } |
| |
| // number of scripts that parsed fine |
| private int passed; |
| // number of scripts resulting in parse failure |
| private int failed; |
| // scripts that were skipped - all tests with @negative are |
| // skipped for now. |
| private int skipped; |
| |
| private void parseJSDirectory(final File dir, final TestFilter filter) { |
| for (final File f : dir.listFiles()) { |
| if (f.isDirectory()) { |
| parseJSDirectory(f, filter); |
| } else if (f.getName().endsWith(".js")) { |
| parseJSFile(f, filter); |
| } |
| } |
| } |
| |
| private void parseJSFile(final File file, final TestFilter filter) { |
| if (VERBOSE) { |
| log("Begin parsing " + file.getAbsolutePath()); |
| } |
| |
| try { |
| final char[] buffer = readFully(file); |
| final String content = new String(buffer); |
| boolean excluded = false; |
| if (filter != null) { |
| excluded = filter.exclude(file, content); |
| } |
| |
| if (excluded) { |
| if (VERBOSE) { |
| log("Skipping " + file.getAbsolutePath()); |
| } |
| skipped++; |
| return; |
| } |
| |
| final Parser parser = Parser.create(options); |
| final Tree tree = parser.parse(file.getAbsolutePath(), content, null); |
| tree.accept(new SimpleTreeVisitorES5_1<Void, Void>(), null); |
| passed++; |
| } catch (final Throwable exp) { |
| log("Parse API failed: " + file.getAbsolutePath() + " : " + exp); |
| //if (VERBOSE) { |
| exp.printStackTrace(System.out); |
| //} |
| failed++; |
| } |
| |
| if (VERBOSE) { |
| log("Done parsing via parser API " + file.getAbsolutePath()); |
| } |
| } |
| |
| private static char[] byteToCharArray(final byte[] bytes) { |
| Charset cs = StandardCharsets.UTF_8; |
| int start = 0; |
| // BOM detection. |
| if (bytes.length > 1 && bytes[0] == (byte) 0xFE && bytes[1] == (byte) 0xFF) { |
| start = 2; |
| cs = StandardCharsets.UTF_16BE; |
| } else if (bytes.length > 1 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE) { |
| start = 2; |
| cs = StandardCharsets.UTF_16LE; |
| } else if (bytes.length > 2 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF) { |
| start = 3; |
| cs = StandardCharsets.UTF_8; |
| } else if (bytes.length > 3 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE && bytes[2] == 0 && bytes[3] == 0) { |
| start = 4; |
| cs = Charset.forName("UTF-32LE"); |
| } else if (bytes.length > 3 && bytes[0] == 0 && bytes[1] == 0 && bytes[2] == (byte) 0xFE && bytes[3] == (byte) 0xFF) { |
| start = 4; |
| cs = Charset.forName("UTF-32BE"); |
| } |
| |
| return new String(bytes, start, bytes.length - start, cs).toCharArray(); |
| } |
| |
| private static char[] readFully(final File file) throws IOException { |
| final byte[] buf = Files.readAllBytes(file.toPath()); |
| return byteToCharArray(buf); |
| } |
| } |