Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tasks/coverage/snapshots/estree_acorn_jsx.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
commit: 389cb2a7
commit: a53e1b22

estree_acorn_jsx Summary:
AST Parsed : 39/39 (100.00%)
Expand Down
14 changes: 14 additions & 0 deletions tasks/coverage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,18 @@ pub struct MiscFile {
pub should_fail: bool,
}

pub struct AcornJsxFile {
pub path: PathBuf,
pub code: String,
pub should_fail: bool,
}

pub struct TestData {
pub test262: Vec<Test262File>,
pub babel: Vec<BabelFile>,
pub typescript: Vec<TypeScriptFile>,
pub misc: Vec<MiscFile>,
pub acorn_jsx: Vec<AcornJsxFile>,
}

// ================================
Expand Down Expand Up @@ -298,6 +305,7 @@ const TEST262_PATH: &str = "test262/test";
const BABEL_PATH: &str = "babel/packages/babel-parser/test/fixtures";
const TYPESCRIPT_PATH: &str = "typescript/tests/cases";
const MISC_PATH: &str = "misc";
const ESTREE_ACORN_JSX_PATH: &str = "estree-conformance/tests/acorn-jsx";

impl AppArgs {
pub fn run_all(&self) {
Expand Down Expand Up @@ -407,6 +415,12 @@ impl AppArgs {

pub fn run_estree(&self, data: &TestData) {
self.run_tool("estree_test262", TEST262_PATH, &data.test262, tools::run_estree_test262);
self.run_tool(
"estree_acorn_jsx",
ESTREE_ACORN_JSX_PATH,
&data.acorn_jsx,
tools::run_estree_acorn_jsx,
);
self.run_tool(
"estree_typescript",
TYPESCRIPT_PATH,
Expand Down
28 changes: 23 additions & 5 deletions tasks/coverage/src/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,22 @@ use rayon::prelude::*;
use walkdir::WalkDir;

use crate::{
BabelFile, MiscFile, Test262File, TestData, TypeScriptFile, babel, test262, typescript,
workspace_root,
AcornJsxFile, BabelFile, MiscFile, Test262File, TestData, TypeScriptFile, babel, test262,
typescript, workspace_root,
};

impl TestData {
pub fn load(filter: Option<&str>) -> Self {
let ((test262, babel), (typescript, misc)) = rayon::join(
let ((test262, babel), (typescript, (misc, acorn_jsx))) = rayon::join(
|| rayon::join(|| load_test262(filter), || load_babel(filter)),
|| rayon::join(|| load_typescript(filter), || load_misc(filter)),
|| {
rayon::join(
|| load_typescript(filter),
|| rayon::join(|| load_misc(filter), || load_acorn_jsx(filter)),
)
},
);
Self { test262, babel, typescript, misc }
Self { test262, babel, typescript, misc, acorn_jsx }
}
}

Expand Down Expand Up @@ -256,3 +261,16 @@ fn load_misc(filter: Option<&str>) -> Vec<MiscFile> {

files
}

fn load_acorn_jsx(filter: Option<&str>) -> Vec<AcornJsxFile> {
let skip_path = |path: &Path| path.extension().is_none_or(|ext| ext != "jsx");

walk_and_read(Path::new("estree-conformance/tests/acorn-jsx"), filter, skip_path)
.into_par_iter()
.map(|(path, code)| {
let should_fail =
path.parent().and_then(Path::file_name).is_some_and(|name| name == "fail");
AcornJsxFile { path, code, should_fail }
})
.collect()
}
73 changes: 65 additions & 8 deletions tasks/coverage/src/tools.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Tool runner functions for coverage testing

use std::{borrow::Cow, path::Path, sync::Arc};
use std::{borrow::Cow, fs, path::Path, sync::Arc};

use oxc::{
allocator::Allocator,
Expand All @@ -19,8 +19,9 @@ use oxc_formatter::{
use rayon::prelude::*;

use crate::{
BabelFile, CoverageResult, Driver, MiscFile, Test262File, TestResult, TypeScriptFile,
test262::TestFlag, typescript::constants::TS_IGNORE_SUPPRESSIBLE_ERRORS, workspace_root,
AcornJsxFile, BabelFile, CoverageResult, Driver, MiscFile, Test262File, TestResult,
TypeScriptFile, test262::TestFlag, typescript::constants::TS_IGNORE_SUPPRESSIBLE_ERRORS,
workspace_root,
};

// ================================
Expand Down Expand Up @@ -699,8 +700,6 @@ pub fn run_minifier_babel(files: &[BabelFile]) -> Vec<CoverageResult> {
// ESTree
// ================================

use std::fs;

pub fn run_estree_test262(files: &[Test262File]) -> Vec<CoverageResult> {
files
.par_iter()
Expand All @@ -714,7 +713,7 @@ pub fn run_estree_test262(files: &[Test262File]) -> Vec<CoverageResult> {
if f.path.starts_with("test262/test/language/comments/hashbang/") {
return false;
}
// Check if acorn json exists
// Skip tests where no Acorn JSON file
let acorn_path = workspace_root()
.join("estree-conformance/tests")
.join(&f.path)
Expand Down Expand Up @@ -758,8 +757,66 @@ pub fn run_estree_test262(files: &[Test262File]) -> Vec<CoverageResult> {
.collect()
}

pub fn run_estree_acorn_jsx(files: &[AcornJsxFile]) -> Vec<CoverageResult> {
files
.par_iter()
.map(|f| {
let source_type = SourceType::default().with_module(true).with_jsx(true);
let allocator = Allocator::new();
let ret = Parser::new(&allocator, &f.code, source_type).parse();
let is_parse_error = ret.panicked || !ret.errors.is_empty();

if is_parse_error {
let error =
ret.errors.first().map_or_else(|| "Panicked".to_string(), ToString::to_string);
let result = if f.should_fail {
TestResult::CorrectError(error, ret.panicked)
} else {
TestResult::ParseError(error, ret.panicked)
};
return CoverageResult { path: f.path.clone(), should_fail: f.should_fail, result };
}

if f.should_fail {
return CoverageResult {
path: f.path.clone(),
should_fail: true,
result: TestResult::IncorrectlyPassed,
};
}

let mut program = ret.program;
Utf8ToUtf16::new(&f.code).convert_program_with_ascending_order_checks(&mut program);

let acorn_json_path = workspace_root().join(&f.path).with_extension("json");
let acorn_json = match fs::read_to_string(&acorn_json_path) {
Ok(acorn_json) => acorn_json,
Err(error) => {
return CoverageResult {
path: f.path.clone(),
should_fail: false,
result: TestResult::GenericError(
"Error reading Acorn JSON",
error.to_string(),
),
};
}
};
let oxc_json = program.to_pretty_estree_js_json(false);

let result = if oxc_json == acorn_json {
TestResult::Passed
} else {
TestResult::Mismatch("Mismatch", oxc_json, acorn_json)
};

CoverageResult { path: f.path.clone(), should_fail: false, result }
})
.collect()
}

pub fn run_estree_typescript(files: &[TypeScriptFile]) -> Vec<CoverageResult> {
// Skip paths for TypeScript estree tests
// Skip paths for TypeScript ESTree tests
const SKIP_PATHS: &[&str] = &[
// Skip cases which are failing in parser conformance tests
"typescript/tests/cases/compiler/arrayFromAsync.ts",
Expand Down Expand Up @@ -788,7 +845,7 @@ pub fn run_estree_typescript(files: &[TypeScriptFile]) -> Vec<CoverageResult> {
if f.path.to_str().is_some_and(|p| SKIP_PATHS.contains(&p)) {
return false;
}
// Check if estree file exists
// Skip tests where no expected ESTree file exists
let ext = f.path.extension().and_then(|e| e.to_str()).unwrap_or("");
let estree_path = workspace_root()
.join("estree-conformance/tests")
Expand Down
Loading