diff --git a/crates/oxc_transformer/Cargo.toml b/crates/oxc_transformer/Cargo.toml index 2f870abb4266e..1446c8755d7af 100644 --- a/crates/oxc_transformer/Cargo.toml +++ b/crates/oxc_transformer/Cargo.toml @@ -22,7 +22,7 @@ oxc_allocator = { workspace = true } oxc_syntax = { workspace = true } oxc_semantic = { workspace = true } -serde = { workspace = true } +serde = { workspace = true, features = ["derive"] } [dev-dependencies] oxc_parser = { workspace = true } diff --git a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs index a0976a6f96615..ea074f7eb66f1 100644 --- a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs +++ b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs @@ -10,7 +10,7 @@ use crate::options::{TransformOptions, TransformTarget}; /// /// References: /// * -/// * +/// * pub struct LogicalAssignmentOperators<'a> { ast: Rc>, } diff --git a/tasks/transform_conformance/babel.snap.md b/tasks/transform_conformance/babel.snap.md index b49a37d33fe50..f6969425f1340 100644 --- a/tasks/transform_conformance/babel.snap.md +++ b/tasks/transform_conformance/babel.snap.md @@ -1,5 +1,11 @@ Passed: 104/1091 +# All Passed: +* babel-plugin-transform-optional-catch-binding +* babel-plugin-transform-shorthand-properties +* babel-plugin-transform-sticky-regex + + # babel-plugin-transform-unicode-sets-regex (0/4) * Failed: basic/basic/input.js * Failed: basic/string-properties/input.js @@ -583,8 +589,6 @@ Passed: 104/1091 * Failed: transparent-expr-wrappers/ts-as-member-expression/input.ts * Failed: transparent-expr-wrappers/ts-parenthesized-expression-member-call/input.ts -# babel-plugin-transform-optional-catch-binding (All passed) - # babel-plugin-transform-json-strings (2/4) * Failed: json-strings/directive-line-separator/input.js * Failed: json-strings/directive-paragraph-separator/input.js @@ -729,10 +733,6 @@ Passed: 104/1091 # babel-plugin-transform-exponentiation-operator (3/4) * Failed: regression/4349/input.js -# babel-plugin-transform-shorthand-properties (All passed) - -# babel-plugin-transform-sticky-regex (All passed) - # babel-plugin-transform-unicode-regex (1/4) * Failed: unicode-regex/basic/input.js * Failed: unicode-regex/negated-set/input.js diff --git a/tasks/transform_conformance/src/lib.rs b/tasks/transform_conformance/src/lib.rs index 0add5e4e89f4c..7d9795f49c671 100644 --- a/tasks/transform_conformance/src/lib.rs +++ b/tasks/transform_conformance/src/lib.rs @@ -40,6 +40,50 @@ fn root() -> PathBuf { project_root().join("tasks/coverage/babel/packages") } +const CASES: &[&str] = &[ + // ES2024 + "babel-plugin-transform-unicode-sets-regex", + // ES2022 + "babel-plugin-transform-class-properties", + "babel-plugin-transform-class-static-block", + "babel-plugin-transform-private-methods", + "babel-plugin-transform-private-property-in-object", + // [Syntax] "babel-plugin-transform-syntax-top-level-await", + // ES2021 + "babel-plugin-transform-logical-assignment-operators", + "babel-plugin-transform-numeric-separator", + // ES2020 + "babel-plugin-transform-export-namespace-from", + "babel-plugin-transform-dynamic-import", + "babel-plugin-transform-export-namespace-from", + "babel-plugin-transform-nullish-coalescing-operator", + "babel-plugin-transform-optional-chaining", + // [Syntax] "babel-plugin-transform-syntax-bigint", + // [Syntax] "babel-plugin-transform-syntax-dynamic-import", + // [Syntax] "babel-plugin-transform-syntax-import-meta", + // ES2019 + "babel-plugin-transform-optional-catch-binding", + "babel-plugin-transform-json-strings", + // ES2018 + "babel-plugin-transform-async-generator-functions", + "babel-plugin-transform-object-rest-spread", + // [Regex] "babel-plugin-transform-unicode-property-regex", + "babel-plugin-transform-dotall-regex", + // [Regex] "babel-plugin-transform-named-capturing-groups-regex", + // ES2017 + "babel-plugin-transform-async-to-generator", + // ES2016 + "babel-plugin-transform-exponentiation-operator", + // ES2015 + "babel-plugin-transform-shorthand-properties", + "babel-plugin-transform-sticky-regex", + "babel-plugin-transform-unicode-regex", + // TypeScript + "babel-plugin-transform-typescript", + // React + "babel-plugin-transform-react-jsx", +]; + impl TestRunner { pub fn new(options: TestRunnerOptions) -> Self { Self { options } @@ -48,57 +92,12 @@ impl TestRunner { /// # Panics pub fn run(self) { let root = root(); - - let cases = [ - // ES2024 - "babel-plugin-transform-unicode-sets-regex", - // ES2022 - "babel-plugin-transform-class-properties", - "babel-plugin-transform-class-static-block", - "babel-plugin-transform-private-methods", - "babel-plugin-transform-private-property-in-object", - // [Syntax] "babel-plugin-transform-syntax-top-level-await", - // ES2021 - "babel-plugin-transform-logical-assignment-operators", - "babel-plugin-transform-numeric-separator", - // ES2020 - "babel-plugin-transform-export-namespace-from", - "babel-plugin-transform-dynamic-import", - "babel-plugin-transform-export-namespace-from", - "babel-plugin-transform-nullish-coalescing-operator", - "babel-plugin-transform-optional-chaining", - // [Syntax] "babel-plugin-transform-syntax-bigint", - // [Syntax] "babel-plugin-transform-syntax-dynamic-import", - // [Syntax] "babel-plugin-transform-syntax-import-meta", - // ES2019 - "babel-plugin-transform-optional-catch-binding", - "babel-plugin-transform-json-strings", - // ES2018 - "babel-plugin-transform-async-generator-functions", - "babel-plugin-transform-object-rest-spread", - // [Regex] "babel-plugin-transform-unicode-property-regex", - "babel-plugin-transform-dotall-regex", - // [Regex] "babel-plugin-transform-named-capturing-groups-regex", - // ES2017 - "babel-plugin-transform-async-to-generator", - // ES2016 - "babel-plugin-transform-exponentiation-operator", - // ES2015 - "babel-plugin-transform-shorthand-properties", - "babel-plugin-transform-sticky-regex", - "babel-plugin-transform-unicode-regex", - // TypeScript - "babel-plugin-transform-typescript", - // React - "babel-plugin-transform-react-jsx", - ]; - let mut snapshot = String::new(); let mut total = 0; - let mut all_passed = 0; + let mut all_passed = vec![]; + let mut all_passed_count = 0; - // Get all fixtures - for case in cases { + for case in CASES { let root = root.join(case).join("test/fixtures"); let mut paths = WalkDir::new(&root) .into_iter() @@ -112,6 +111,7 @@ impl TestRunner { .map(walkdir::DirEntry::into_path) .collect::>(); paths.sort_unstable(); + let num_of_tests = paths.len(); total += num_of_tests; @@ -119,28 +119,34 @@ impl TestRunner { let (passed, failed): (Vec, Vec) = paths .into_iter() .partition(|path| TestCase::new(path).test(self.options.filter.as_deref())); - all_passed += passed.len(); + all_passed_count += passed.len(); // Snapshot - snapshot.push_str("# "); - snapshot.push_str(case); if failed.is_empty() { - snapshot.push_str(" (All passed)\n"); + all_passed.push(case); } else { + snapshot.push_str("# "); + snapshot.push_str(case); snapshot.push_str(&format!(" ({}/{})\n", passed.len(), num_of_tests)); - } - for path in failed { - snapshot.push_str("* Failed: "); - snapshot.push_str(&normalize_path(path.strip_prefix(&root).unwrap())); + for path in failed { + snapshot.push_str("* Failed: "); + snapshot.push_str(&normalize_path(path.strip_prefix(&root).unwrap())); + snapshot.push('\n'); + } snapshot.push('\n'); } - snapshot.push('\n'); } - let snapshot = format!("Passed: {all_passed}/{total}\n\n{snapshot}"); - let path = project_root().join("tasks/transform_conformance/babel.snap.md"); - let mut file = File::create(path).unwrap(); - file.write_all(snapshot.as_bytes()).unwrap(); + if self.options.filter.is_none() { + let all_passed = + all_passed.into_iter().map(|s| format!("* {s}")).collect::>().join("\n"); + let snapshot = format!( + "Passed: {all_passed_count}/{total}\n\n# All Passed:\n{all_passed}\n\n\n{snapshot}" + ); + let path = project_root().join("tasks/transform_conformance/babel.snap.md"); + let mut file = File::create(path).unwrap(); + file.write_all(snapshot.as_bytes()).unwrap(); + } } } @@ -187,22 +193,24 @@ impl TestCase { /// Test conformance by comparing the parsed babel code and transformed code. fn test(&self, filter: Option<&str>) -> bool { + let filtered = filter.is_some_and(|f| self.path.to_string_lossy().as_ref().contains(f)); + let output_path = self.path.parent().unwrap().read_dir().unwrap().find_map(|entry| { let path = entry.ok()?.path(); let file_stem = path.file_stem()?; (file_stem == "output").then_some(path) }); + + let allocator = Allocator::default(); let source_text = fs::read_to_string(&self.path).unwrap(); - let filtered = filter.is_some_and(|f| self.path.to_string_lossy().as_ref().contains(f)); + let source_type = SourceType::from_path(&self.path).unwrap(); if filtered { println!("input_path: {:?}", &self.path); println!("output_path: {output_path:?}"); + println!("input: {source_text}"); } - let allocator = Allocator::default(); - let source_type = SourceType::from_path(&self.path).unwrap(); - // Get expected code by parsing the source text, so we can get the same code generated result. let expected = output_path.and_then(|path| fs::read_to_string(path).ok()); let Some(expected) = &expected else { return false };