From 166b8581c226b127f5d503cd21c22c0a3a8c675c Mon Sep 17 00:00:00 2001 From: Levi Date: Tue, 8 Oct 2024 12:06:20 +1300 Subject: [PATCH] feat(es/testing): Parse test code as a `Program` instead of a `Module` (#9264) **Description:** This PR addresses the issue described in #8713 **BREAKING CHANGE:** This will break existing unit tests that use `fold_module`/`visit_module`/`visit_mut_module` if the visitor is intended to work for both modules and scripts, instead of using `fold_program`/`visit_program`/`visit_mut_program`. This will also break existing unit tests if they're testing with input code that gets parsed as a script in `parse_program` if the visitor expects a module (they will need to update their `test!` calls to add `module` as the first argument, or use a function like `apply_module_transform`) **Related issue:** - Closes https://github.com/swc-project/swc/issues/8713 --- .changeset/nine-trees-beam.md | 5 + .../swc_ecma_transforms/tests/decorators.rs | 17 + .../swc_ecma_transforms_module/tests/amd.rs | 5 +- .../tests/common_js.rs | 5 +- .../tests/path_node.rs | 6 +- .../tests/system_js.rs | 10 +- .../swc_ecma_transforms_module/tests/umd.rs | 4 +- .../src/inline_globals.rs | 15 +- .../src/simplify/inlining/mod.rs | 6 +- .../tests/decorator_evanw.rs | 4 +- .../tests/decorators.rs | 6 +- .../src/jsx/tests.rs | 62 +++- .../src/jsx_self/tests.rs | 1 + .../src/jsx_src/tests.rs | 1 + .../src/refresh/tests.rs | 35 ++ crates/swc_ecma_transforms_testing/src/lib.rs | 332 ++++++++++++++---- 16 files changed, 425 insertions(+), 89 deletions(-) create mode 100644 .changeset/nine-trees-beam.md diff --git a/.changeset/nine-trees-beam.md b/.changeset/nine-trees-beam.md new file mode 100644 index 000000000000..64e441083454 --- /dev/null +++ b/.changeset/nine-trees-beam.md @@ -0,0 +1,5 @@ +--- +swc_ecma_transforms_testing: breaking +--- + +feat(es/testing): Parse test code as a `Program` instead of a `Module` diff --git a/crates/swc_ecma_transforms/tests/decorators.rs b/crates/swc_ecma_transforms/tests/decorators.rs index de0063687985..e6635d31f084 100644 --- a/crates/swc_ecma_transforms/tests/decorators.rs +++ b/crates/swc_ecma_transforms/tests/decorators.rs @@ -91,6 +91,7 @@ fn transformation(t: &Tester) -> impl Fold { // transformation_declaration test!( + module, syntax(false), |t| transformation(t), transformation_declaration, @@ -101,6 +102,7 @@ class A {} ); // transformation_initialize_after_super_multiple test!( + module, syntax(false), |t| transformation(t), transformation_initialize_after_super_multiple, @@ -134,6 +136,7 @@ export default @dec() class {} ); // transformation_initialize_after_super_statement test!( + module, syntax(false), |t| transformation(t), transformation_initialize_after_super_statement, @@ -211,6 +214,7 @@ expect(A).toBe(C); ); // misc_method_name_not_shadow test!( + module, syntax(false), |t| tr(t), misc_method_name_not_shadow, @@ -320,6 +324,7 @@ expect(() => { ); // duplicated_keys_computed_keys_same_value test!( + module, syntax(false), |t| tr(t), duplicated_keys_computed_keys_same_value, @@ -395,6 +400,7 @@ expect(log).toEqual(numsFrom0to9); ); // transformation_initializer_after_super_bug_8808 test!( + module, syntax(false), |t| transformation(t), transformation_initiailzer_after_super_bug_8808, @@ -434,6 +440,7 @@ expect(A.prototype.method()).toBe(2); ); // transformation_arguments test!( + module, syntax(false), |t| transformation(t), transformation_arguments, @@ -532,6 +539,7 @@ expect(calls).toBe(1); // ordering // transformation_initialize_after_super_expression test!( + module, syntax(false), |t| transformation(t), transformation_initialize_after_super_expression, @@ -903,6 +911,7 @@ expect(Object.getOwnPropertyDescriptor(A.prototype, "foo")).toEqual({ ); // transformation_extends test!( + module, syntax(false), |t| transformation(t), transformation_extends, @@ -914,6 +923,7 @@ test!( // finishers // transformation_extends_await test!( + module, syntax(false), |t| transformation(t), transformation_extends_await, @@ -926,6 +936,7 @@ async function g() { ); // transformation_extends_yield test!( + module, syntax(false), |t| transformation(t), transformation_extends_yield, @@ -1092,6 +1103,7 @@ expect(i).toBe(2); ); // transformation_initialize_after_super_bug_8931 test!( + module, syntax(false), |t| transformation(t), transformation_initialize_after_super_bug_8931, @@ -1318,6 +1330,7 @@ expect(Foo.prototype.bar).toBe(value2); ); // transformation_expression test!( + module, syntax(false), |t| transformation(t), transformation_expression, @@ -1354,6 +1367,7 @@ expect(A.method()).toBe(2); // element_descriptors // duplicated_keys_computed_keys_same_ast test!( + module, syntax(false), |t| tr(t), duplicated_keys_computed_keys_same_ast, @@ -1503,6 +1517,7 @@ expect(desc.set()).toBe(2); // misc // transformation_extends_exec test_exec!( + module, syntax(false), |t| tr(t), transformation_extends_exec, @@ -1549,6 +1564,7 @@ expect(() => { ); // duplicated_keys_computed_keys_same_value_exec test_exec!( + module, syntax(false), |t| tr(t), duplicated_keys_computed_keys_same_value_exec, @@ -3882,6 +3898,7 @@ eval: function () { ); test!( + module, ts(), |_| decorators(Default::default()), issue_846_1, diff --git a/crates/swc_ecma_transforms_module/tests/amd.rs b/crates/swc_ecma_transforms_module/tests/amd.rs index 674a16c1307e..6a4603e4bdb8 100644 --- a/crates/swc_ecma_transforms_module/tests/amd.rs +++ b/crates/swc_ecma_transforms_module/tests/amd.rs @@ -5,7 +5,7 @@ use swc_ecma_parser::{Syntax, TsSyntax}; use swc_ecma_transforms_base::{feature::FeatureFlag, resolver}; use swc_ecma_transforms_compat::es2015::for_of; use swc_ecma_transforms_module::amd::{self, amd}; -use swc_ecma_transforms_testing::{test, test_fixture}; +use swc_ecma_transforms_testing::{test, test_module_fixture}; use swc_ecma_transforms_typescript::typescript; use swc_ecma_visit::Fold; @@ -60,7 +60,7 @@ fn esm_to_amd(input: PathBuf) { Err(..) => Default::default(), }; - test_fixture( + test_module_fixture( if is_ts { ts_syntax() } else { syntax() }, &|t| tr(config.clone(), is_ts, t.comments.clone()), &input, @@ -70,6 +70,7 @@ fn esm_to_amd(input: PathBuf) { } test!( + module, syntax(), |t| chain!( for_of(for_of::Config { diff --git a/crates/swc_ecma_transforms_module/tests/common_js.rs b/crates/swc_ecma_transforms_module/tests/common_js.rs index 6857f9fe44dc..18fd09107485 100644 --- a/crates/swc_ecma_transforms_module/tests/common_js.rs +++ b/crates/swc_ecma_transforms_module/tests/common_js.rs @@ -5,7 +5,7 @@ use swc_ecma_parser::{Syntax, TsSyntax}; use swc_ecma_transforms_base::{feature::FeatureFlag, resolver}; use swc_ecma_transforms_compat::es2015::for_of; use swc_ecma_transforms_module::common_js::{self, common_js}; -use swc_ecma_transforms_testing::{test, test_fixture, FixtureTestConfig}; +use swc_ecma_transforms_testing::{test, test_module_fixture, FixtureTestConfig}; use swc_ecma_transforms_typescript::typescript; use swc_ecma_visit::Fold; @@ -52,7 +52,7 @@ fn esm_to_cjs(input: PathBuf) { Err(..) => Default::default(), }; - test_fixture( + test_module_fixture( if is_ts { ts_syntax() } else { syntax() }, &|_| tr(config.clone(), is_ts), &input, @@ -65,6 +65,7 @@ fn esm_to_cjs(input: PathBuf) { } test!( + module, syntax(), |_| chain!( for_of(for_of::Config { diff --git a/crates/swc_ecma_transforms_module/tests/path_node.rs b/crates/swc_ecma_transforms_module/tests/path_node.rs index 435e648e4ce3..5e91c6086fd9 100644 --- a/crates/swc_ecma_transforms_module/tests/path_node.rs +++ b/crates/swc_ecma_transforms_module/tests/path_node.rs @@ -12,7 +12,7 @@ use swc_ecma_transforms_module::{ path::{ImportResolver, NodeImportResolver}, rewriter::import_rewriter, }; -use swc_ecma_transforms_testing::test_fixture; +use swc_ecma_transforms_testing::test_module_fixture; use testing::run_test2; type TestProvider = NodeImportResolver; @@ -43,7 +43,7 @@ fn issue_4730() { let input_dir = dir.join("input"); let output_dir = dir.join("output"); - test_fixture( + test_module_fixture( Syntax::default(), &|_| { let mut paths = IndexMap::new(); @@ -136,7 +136,7 @@ fn fixture(input_dir: PathBuf) { .canonicalize() .unwrap(); dbg!(&base_dir); - test_fixture( + test_module_fixture( Syntax::default(), &|_| { let rules = config.paths.clone().into_iter().collect(); diff --git a/crates/swc_ecma_transforms_module/tests/system_js.rs b/crates/swc_ecma_transforms_module/tests/system_js.rs index d07e2c4425dc..0a3597bc14cf 100644 --- a/crates/swc_ecma_transforms_module/tests/system_js.rs +++ b/crates/swc_ecma_transforms_module/tests/system_js.rs @@ -6,7 +6,7 @@ use swc_common::{chain, Mark}; use swc_ecma_parser::Syntax; use swc_ecma_transforms_base::resolver; use swc_ecma_transforms_module::system_js::{system_js, Config}; -use swc_ecma_transforms_testing::{test, test_fixture, Tester}; +use swc_ecma_transforms_testing::{test, test_module_fixture, Tester}; use swc_ecma_visit::Fold; fn syntax() -> Syntax { @@ -23,6 +23,7 @@ fn tr(_tester: &mut Tester<'_>, config: Config) -> impl Fold { } test!( + module, syntax(), |tester| tr(tester, Default::default()), allow_continuous_assignment, @@ -30,6 +31,7 @@ test!( ); test!( + module, syntax(), |tester| tr( tester, @@ -43,6 +45,7 @@ test!( ); test!( + module, syntax(), |tester| tr( tester, @@ -60,6 +63,7 @@ test!( ); test!( + module, syntax(), |tester| tr( tester, @@ -82,6 +86,7 @@ test!( ); test!( + module, syntax(), |tester| tr( tester, @@ -99,6 +104,7 @@ test!( ); test!( + module, syntax(), |tester| tr(tester, Default::default()), imports, @@ -117,7 +123,7 @@ fn fixture(input: PathBuf) { let output = dir.join("output.mjs"); - test_fixture( + test_module_fixture( syntax(), &|tester| tr(tester, Default::default()), &input, diff --git a/crates/swc_ecma_transforms_module/tests/umd.rs b/crates/swc_ecma_transforms_module/tests/umd.rs index 0512aa30635f..b56d0f2bde20 100644 --- a/crates/swc_ecma_transforms_module/tests/umd.rs +++ b/crates/swc_ecma_transforms_module/tests/umd.rs @@ -4,7 +4,7 @@ use swc_common::{chain, Mark}; use swc_ecma_parser::{Syntax, TsSyntax}; use swc_ecma_transforms_base::{feature::FeatureFlag, resolver}; use swc_ecma_transforms_module::umd::{umd, Config}; -use swc_ecma_transforms_testing::{test_fixture, Tester}; +use swc_ecma_transforms_testing::{test_module_fixture, Tester}; use swc_ecma_transforms_typescript::typescript; use swc_ecma_visit::Fold; @@ -58,7 +58,7 @@ fn esm_to_umd(input: PathBuf) { Err(..) => Default::default(), }; - test_fixture( + test_module_fixture( if is_ts { ts_syntax() } else { syntax() }, &|tester| tr(tester, config.clone(), is_ts), &input, diff --git a/crates/swc_ecma_transforms_optimization/src/inline_globals.rs b/crates/swc_ecma_transforms_optimization/src/inline_globals.rs index 8ddd29273162..70ed4693d592 100644 --- a/crates/swc_ecma_transforms_optimization/src/inline_globals.rs +++ b/crates/swc_ecma_transforms_optimization/src/inline_globals.rs @@ -202,7 +202,7 @@ impl VisitMut for InlineGlobals { #[cfg(test)] mod tests { use swc_ecma_transforms_testing::{test, Tester}; - use swc_ecma_utils::DropSpan; + use swc_ecma_utils::{DropSpan, StmtOrModuleItem}; use super::*; @@ -220,7 +220,7 @@ mod tests { (*v).into() }; - let mut v = tester + let v = tester .apply_transform( as_folder(DropSpan), "global.js", @@ -228,9 +228,14 @@ mod tests { &v, ) .unwrap(); - assert_eq!(v.body.len(), 1); - let v = match v.body.pop().unwrap() { - ModuleItem::Stmt(Stmt::Expr(ExprStmt { expr, .. })) => *expr, + + let v = match v { + Program::Module(mut m) => m.body.pop().and_then(|x| x.into_stmt().ok()), + Program::Script(mut s) => s.body.pop(), + }; + assert!(v.is_some()); + let v = match v.unwrap() { + Stmt::Expr(ExprStmt { expr, .. }) => *expr, _ => unreachable!(), }; diff --git a/crates/swc_ecma_transforms_optimization/src/simplify/inlining/mod.rs b/crates/swc_ecma_transforms_optimization/src/simplify/inlining/mod.rs index 90341b5f7e43..2157c7ae14d6 100644 --- a/crates/swc_ecma_transforms_optimization/src/simplify/inlining/mod.rs +++ b/crates/swc_ecma_transforms_optimization/src/simplify/inlining/mod.rs @@ -468,19 +468,19 @@ impl VisitMut for Inlining<'_> { self.visit_with_child(ScopeKind::Cond, &mut stmt.alt); } - fn visit_mut_module_items(&mut self, items: &mut Vec) { + fn visit_mut_program(&mut self, program: &mut Program) { let _tracing = span!(Level::ERROR, "inlining", pass = self.pass).entered(); let old_phase = self.phase; self.phase = Phase::Analysis; - items.visit_mut_children_with(self); + program.visit_mut_children_with(self); tracing::trace!("Switching to Inlining phase"); // Inline self.phase = Phase::Inlining; - items.visit_mut_children_with(self); + program.visit_mut_children_with(self); self.phase = old_phase; } diff --git a/crates/swc_ecma_transforms_proposal/tests/decorator_evanw.rs b/crates/swc_ecma_transforms_proposal/tests/decorator_evanw.rs index d077a1c645f4..77f48138ed49 100644 --- a/crates/swc_ecma_transforms_proposal/tests/decorator_evanw.rs +++ b/crates/swc_ecma_transforms_proposal/tests/decorator_evanw.rs @@ -2,7 +2,7 @@ use std::{fs, path::PathBuf}; use swc_ecma_parser::{EsSyntax, Syntax}; use swc_ecma_transforms_proposal::decorator_2022_03::decorator_2022_03; -use swc_ecma_transforms_testing::exec_tr; +use swc_ecma_transforms_testing::exec_module_tr; use swc_ecma_visit::as_folder; const HELPERS: &str = r###" @@ -57,7 +57,7 @@ fn fixture(input: PathBuf) { {code}" ); - exec_tr( + exec_module_tr( &input.file_name().unwrap().to_string_lossy(), Syntax::Es(EsSyntax { decorators: true, diff --git a/crates/swc_ecma_transforms_proposal/tests/decorators.rs b/crates/swc_ecma_transforms_proposal/tests/decorators.rs index fe10f8bbf0b6..bd27fc3d3ba7 100644 --- a/crates/swc_ecma_transforms_proposal/tests/decorators.rs +++ b/crates/swc_ecma_transforms_proposal/tests/decorators.rs @@ -10,7 +10,7 @@ use swc_common::{chain, comments::SingleThreadedComments, Mark}; use swc_ecma_parser::{EsSyntax, Syntax, TsSyntax}; use swc_ecma_transforms_base::{assumptions::Assumptions, resolver}; use swc_ecma_transforms_proposal::{decorator_2022_03::decorator_2022_03, DecoratorVersion}; -use swc_ecma_transforms_testing::{test_fixture, FixtureTestConfig}; +use swc_ecma_transforms_testing::{test_module_fixture, FixtureTestConfig}; use swc_ecma_visit::Fold; fn syntax_default() -> Syntax { @@ -39,7 +39,7 @@ fn exec(input: PathBuf) { fn exec_inner(input: PathBuf) { let code = std::fs::read_to_string(&input).unwrap(); - swc_ecma_transforms_testing::exec_tr( + swc_ecma_transforms_testing::exec_module_tr( "decorator", Syntax::Typescript(TsSyntax { decorators: true, @@ -65,7 +65,7 @@ fn fixture_inner(input: PathBuf) { input.extension().unwrap().to_string_lossy() )); - test_fixture( + test_module_fixture( if input.to_string_lossy().ends_with(".ts") { syntax_default_ts() } else { diff --git a/crates/swc_ecma_transforms_react/src/jsx/tests.rs b/crates/swc_ecma_transforms_react/src/jsx/tests.rs index c7461a3eba45..bcd74b4b2c47 100644 --- a/crates/swc_ecma_transforms_react/src/jsx/tests.rs +++ b/crates/swc_ecma_transforms_react/src/jsx/tests.rs @@ -13,7 +13,9 @@ use swc_ecma_transforms_compat::{ es2015::{arrow, classes}, es3::property_literals, }; -use swc_ecma_transforms_testing::{parse_options, test, test_fixture, FixtureTestConfig, Tester}; +use swc_ecma_transforms_testing::{ + parse_options, test, test_module_fixture, FixtureTestConfig, Tester, +}; use swc_ecma_visit::FoldWith; use testing::NormalizedOutput; @@ -108,6 +110,7 @@ fn integration_tr(t: &mut Tester, mut options: FixtureOptions) -> impl Fold { ) } test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -122,6 +125,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -140,6 +144,7 @@ var bar = function () { ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -164,6 +169,7 @@ var x = ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -179,6 +185,7 @@ Component = React.createClass({ ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -195,6 +202,7 @@ export default React.createClass({ ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -219,6 +227,7 @@ var Bar = React.createClass({ ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -236,6 +245,7 @@ exports = { ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -252,6 +262,7 @@ exports.Component = React.createClass({ ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -268,6 +279,7 @@ var Component = React.createClass({ ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -283,6 +295,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -300,6 +313,7 @@ var profile =
); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -319,6 +333,7 @@ var profile =
); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -343,6 +358,7 @@ var profile =
); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -353,6 +369,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -393,6 +410,7 @@ class App extends React.Component { ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -406,6 +424,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -416,6 +435,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -426,6 +446,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -436,6 +457,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -446,6 +468,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -469,6 +492,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -483,6 +507,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -498,6 +523,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -524,6 +550,7 @@ var x = ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -534,6 +561,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -544,6 +572,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -558,6 +587,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -579,6 +609,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -591,6 +622,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -615,6 +647,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -637,6 +670,7 @@ React.render( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -690,6 +726,7 @@ var x = ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -700,6 +737,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -710,6 +748,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -720,6 +759,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -730,6 +770,7 @@ test!( ); test!( + module, // Comments are currently stripped out ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, @@ -752,6 +793,7 @@ var x = ( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -762,6 +804,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -780,6 +823,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -790,6 +834,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -803,6 +848,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -813,6 +859,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -823,6 +870,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -833,6 +881,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -843,6 +892,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -853,6 +903,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -864,6 +915,7 @@ const b =
test
" ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -879,6 +931,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -890,6 +943,7 @@ test!( // https://github.com/swc-project/swc/issues/517 test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -912,6 +966,7 @@ fn jsx_text() { // https://github.com/swc-project/swc/issues/542 test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -966,6 +1021,7 @@ return ( ); test!( + module, Syntax::Es(EsSyntax { jsx: true, ..Default::default() @@ -998,7 +1054,7 @@ fn fixture(input: PathBuf) { output = input.with_file_name("output.mjs"); } - test_fixture( + test_module_fixture( Syntax::Es(EsSyntax { jsx: true, ..Default::default() @@ -1023,7 +1079,7 @@ fn integration(input: PathBuf) { output = input.with_file_name("output.mjs"); } - test_fixture( + test_module_fixture( Syntax::Es(EsSyntax { jsx: true, ..Default::default() diff --git a/crates/swc_ecma_transforms_react/src/jsx_self/tests.rs b/crates/swc_ecma_transforms_react/src/jsx_self/tests.rs index ad6b332311af..1315aecf2a64 100644 --- a/crates/swc_ecma_transforms_react/src/jsx_self/tests.rs +++ b/crates/swc_ecma_transforms_react/src/jsx_self/tests.rs @@ -7,6 +7,7 @@ fn tr() -> impl Fold { } test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() diff --git a/crates/swc_ecma_transforms_react/src/jsx_src/tests.rs b/crates/swc_ecma_transforms_react/src/jsx_src/tests.rs index f20fa8cb082e..9523617842f0 100644 --- a/crates/swc_ecma_transforms_react/src/jsx_src/tests.rs +++ b/crates/swc_ecma_transforms_react/src/jsx_src/tests.rs @@ -35,6 +35,7 @@ expect(actual).toBe(expected); ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() diff --git a/crates/swc_ecma_transforms_react/src/refresh/tests.rs b/crates/swc_ecma_transforms_react/src/refresh/tests.rs index f8012a87d33e..8d5c63c1d332 100644 --- a/crates/swc_ecma_transforms_react/src/refresh/tests.rs +++ b/crates/swc_ecma_transforms_react/src/refresh/tests.rs @@ -25,6 +25,7 @@ fn tr(t: &mut Tester) -> impl Fold { } test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -43,6 +44,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -68,6 +70,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -89,6 +92,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -105,6 +109,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -119,6 +124,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -140,6 +146,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -160,6 +167,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -186,6 +194,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -209,6 +218,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -219,6 +229,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -239,6 +250,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -253,6 +265,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -267,6 +280,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -283,6 +297,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -301,6 +316,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -336,6 +352,7 @@ test!( // A doesn't get registered because it's not declared locally. // Alias doesn't get registered because its definition is just an identifier. test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -393,6 +410,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -410,6 +428,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -426,6 +445,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -451,6 +471,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -480,6 +501,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -496,6 +518,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -513,6 +536,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -536,6 +560,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Typescript(::swc_ecma_parser::TsSyntax { tsx: true, ..Default::default() @@ -578,6 +603,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -602,6 +628,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Typescript(::swc_ecma_parser::TsSyntax { tsx: true, ..Default::default() @@ -629,6 +656,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -652,6 +680,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -668,6 +697,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -701,6 +731,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Typescript(::swc_ecma_parser::TsSyntax { tsx: true, ..Default::default() @@ -717,6 +748,7 @@ test!( ); test!( + module, Default::default(), tr, next_001, @@ -728,6 +760,7 @@ test!( ); test!( + module, Default::default(), tr, issue_2261, @@ -741,6 +774,7 @@ test!( ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() @@ -759,6 +793,7 @@ const a = (a) => { ); test!( + module, ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsSyntax { jsx: true, ..Default::default() diff --git a/crates/swc_ecma_transforms_testing/src/lib.rs b/crates/swc_ecma_transforms_testing/src/lib.rs index 9bda5e768e12..270df75e429f 100644 --- a/crates/swc_ecma_transforms_testing/src/lib.rs +++ b/crates/swc_ecma_transforms_testing/src/lib.rs @@ -58,6 +58,19 @@ pub struct Tester<'a> { pub comments: Rc, } +/// Used to determine how src for a test should be parsed. +#[derive(Debug, Clone, Copy)] +pub enum SrcType { + /// Parsed using `parse_program`. + Program, + + /// Parsed using `parse_module`. + Module, + + /// Parsed using `parse_script`. + Script, +} + impl<'a> Tester<'a> { pub fn run(op: F) -> Ret where @@ -162,42 +175,67 @@ impl<'a> Tester<'a> { Ok(stmts.pop().unwrap()) } - pub fn apply_transform( + /// Applies transform using [SrcType] to determine the parsed AST type. + fn apply_transform_with( &mut self, mut tr: T, name: &str, syntax: Syntax, src: &str, - ) -> Result { - let fm = self - .cm - .new_source_file(FileName::Real(name.into()).into(), src.into()); - - let module = { - let mut p = Parser::new_from(Lexer::new( + src_type: SrcType, + ) -> Result { + let program = + self.with_parser( + name, syntax, - EsVersion::latest(), - StringInput::from(&*fm), - Some(&self.comments), - )); - let res = p - .parse_module() - .map_err(|e| e.into_diagnostic(self.handler).emit()); - - for e in p.take_errors() { - e.into_diagnostic(self.handler).emit() - } + src, + |parser: &mut Parser| match src_type { + SrcType::Program => parser.parse_program(), + SrcType::Module => parser.parse_module().map(Program::Module), + SrcType::Script => parser.parse_script().map(Program::Script), + }, + )?; + + Ok(program.fold_with(&mut tr)) + } - res? - }; + /// Applies transform, parsing the given src as a [Program]. + pub fn apply_transform( + &mut self, + tr: T, + name: &str, + syntax: Syntax, + src: &str, + ) -> Result { + self.apply_transform_with(tr, name, syntax, src, SrcType::Program) + } - let module = Program::Module(module).fold_with(&mut tr); + /// Same as [apply_transform][`Self::apply_transform`], but parses the given + /// src as a [Module][Program::Module]. + pub fn apply_module_transform( + &mut self, + tr: T, + name: &str, + syntax: Syntax, + src: &str, + ) -> Result { + self.apply_transform_with(tr, name, syntax, src, SrcType::Module) + } - Ok(module.expect_module()) + /// Same as [apply_transform][`Self::apply_transform`], but parses the given + /// src as a [Script][Program::Script]. + pub fn apply_script_transform( + &mut self, + tr: T, + name: &str, + syntax: Syntax, + src: &str, + ) -> Result { + self.apply_transform_with(tr, name, syntax, src, SrcType::Script) } - pub fn print(&mut self, module: &Module, comments: &Rc) -> String { - to_code_default(self.cm.clone(), Some(comments), module) + pub fn print(&mut self, program: &Program, comments: &Rc) -> String { + to_code_default(self.cm.clone(), Some(comments), program) } } @@ -257,13 +295,8 @@ where } #[track_caller] -pub fn test_transform( - syntax: Syntax, - tr: F, - input: &str, - expected: &str, - _always_ok_if_code_eq: bool, -) where +fn test_transform_with(syntax: Syntax, src_type: SrcType, tr: F, input: &str, expected: &str) +where F: FnOnce(&mut Tester) -> P, P: Fold, { @@ -280,7 +313,7 @@ pub fn test_transform( println!("----- Actual -----"); let tr = make_tr(tr, tester); - let actual = tester.apply_transform(tr, "input.js", syntax, input)?; + let actual = tester.apply_transform_with(tr, "input.js", syntax, input, src_type)?; match ::std::env::var("PRINT_HYGIENE") { Ok(ref s) if s == "1" => { @@ -337,6 +370,41 @@ pub fn test_transform( }); } +/// Tests transform, parsing input as a [Program]. +#[track_caller] +pub fn test_transform( + syntax: Syntax, + tr: F, + input: &str, + expected: &str, + _always_ok_if_code_eq: bool, +) where + F: FnOnce(&mut Tester) -> P, + P: Fold, +{ + test_transform_with(syntax, SrcType::Program, tr, input, expected) +} + +/// Same as [test_transform], but parses input as a [Module][Program::Module]. +#[track_caller] +pub fn test_module_transform(syntax: Syntax, tr: F, input: &str, expected: &str) +where + F: FnOnce(&mut Tester) -> P, + P: Fold, +{ + test_transform_with(syntax, SrcType::Module, tr, input, expected) +} + +/// Same as [test_transform], but parses input as a [Script][Program::Script]. +#[track_caller] +pub fn test_script_transform(syntax: Syntax, tr: F, input: &str, expected: &str) +where + F: FnOnce(&mut Tester) -> P, + P: Fold, +{ + test_transform_with(syntax, SrcType::Script, tr, input, expected) +} + /// NOT A PUBLIC API. DO NOT USE. #[doc(hidden)] #[track_caller] @@ -350,9 +418,9 @@ where let expected = output; let expected_src = Tester::run(|tester| { - let expected_module = tester.apply_transform(noop(), "expected.js", syntax, expected)?; + let expected_program = tester.apply_transform(noop(), "expected.js", syntax, expected)?; - let expected_src = tester.print(&expected_module, &Default::default()); + let expected_src = tester.print(&expected_program, &Default::default()); println!( "----- {} -----\n{}", @@ -404,11 +472,14 @@ where ); } -/// NOT A PUBLIC API. DO NOT USE. -#[doc(hidden)] #[track_caller] -pub fn test_inlined_transform(test_name: &str, syntax: Syntax, tr: F, input: &str) -where +fn test_inlined_transform_with( + test_name: &str, + syntax: Syntax, + src_type: SrcType, + tr: F, + input: &str, +) where F: FnOnce(&mut Tester) -> P, P: Fold, { @@ -426,6 +497,7 @@ where test_fixture_inner( syntax, + src_type, Box::new(move |tester| Box::new(tr(tester))), input, &snapshot_dir.join(format!("{test_name}.js")), @@ -433,6 +505,39 @@ where ) } +/// NOT A PUBLIC API. DO NOT USE. +#[doc(hidden)] +#[track_caller] +pub fn test_inlined_transform(test_name: &str, syntax: Syntax, tr: F, input: &str) +where + F: FnOnce(&mut Tester) -> P, + P: Fold, +{ + test_inlined_transform_with(test_name, syntax, SrcType::Program, tr, input) +} + +/// NOT A PUBLIC API. DO NOT USE. +#[doc(hidden)] +#[track_caller] +pub fn test_inlined_module_transform(test_name: &str, syntax: Syntax, tr: F, input: &str) +where + F: FnOnce(&mut Tester) -> P, + P: Fold, +{ + test_inlined_transform_with(test_name, syntax, SrcType::Module, tr, input) +} + +/// NOT A PUBLIC API. DO NOT USE. +#[doc(hidden)] +#[track_caller] +pub fn test_inlined_script_transform(test_name: &str, syntax: Syntax, tr: F, input: &str) +where + F: FnOnce(&mut Tester) -> P, + P: Fold, +{ + test_inlined_transform_with(test_name, syntax, SrcType::Script, tr, input) +} + /// NOT A PUBLIC API. DO NOT USE. #[doc(hidden)] #[macro_export] @@ -500,6 +605,20 @@ macro_rules! test { } }; + (module, $syntax:expr, $tr:expr, $test_name:ident, $input:expr) => { + #[test] + fn $test_name() { + $crate::test_inlined_module_transform(stringify!($test_name), $syntax, $tr, $input) + } + }; + + (script, $syntax:expr, $tr:expr, $test_name:ident, $input:expr) => { + #[test] + fn $test_name() { + $crate::test_inlined_script_transform(stringify!($test_name), $syntax, $tr, $input) + } + }; + ($syntax:expr, $tr:expr, $test_name:ident, $input:expr, ok_if_code_eq) => { #[test] fn $test_name() { @@ -518,12 +637,12 @@ where Tester::run(|tester| { let tr = make_tr(tr, tester); - let module = tester.apply_transform(tr, "input.js", syntax, input)?; + let program = tester.apply_transform(tr, "input.js", syntax, input)?; match ::std::env::var("PRINT_HYGIENE") { Ok(ref s) if s == "1" => { let hygiene_src = tester.print( - &module.clone().fold_with(&mut HygieneVisualizer), + &program.clone().fold_with(&mut HygieneVisualizer), &tester.comments.clone(), ); println!("----- Hygiene -----\n{}", hygiene_src); @@ -531,14 +650,14 @@ where _ => {} } - let mut module = module + let mut program = program .fold_with(&mut hygiene::hygiene()) .fold_with(&mut fixer::fixer(Some(&tester.comments))); - let src_without_helpers = tester.print(&module, &tester.comments.clone()); - module = module.fold_with(&mut inject_helpers(Mark::fresh(Mark::root()))); + let src_without_helpers = tester.print(&program, &tester.comments.clone()); + program = program.fold_with(&mut inject_helpers(Mark::fresh(Mark::root()))); - let transformed_src = tester.print(&module, &tester.comments.clone()); + let transformed_src = tester.print(&program, &tester.comments.clone()); println!( "\t>>>>> Orig <<<<<\n{}\n\t>>>>> Code <<<<<\n{}", @@ -557,8 +676,7 @@ where }) } -/// Execute `jest` after transpiling `input` using `tr`. -pub fn exec_tr(_test_name: &str, syntax: Syntax, tr: F, input: &str) +fn exec_tr_with(syntax: Syntax, src_type: SrcType, tr: F, input: &str) where F: FnOnce(&mut Tester<'_>) -> P, P: Fold, @@ -566,7 +684,7 @@ where Tester::run(|tester| { let tr = make_tr(tr, tester); - let module = tester.apply_transform( + let program = tester.apply_transform_with( tr, "input.js", syntax, @@ -576,11 +694,12 @@ where }})", input ), + src_type, )?; match ::std::env::var("PRINT_HYGIENE") { Ok(ref s) if s == "1" => { let hygiene_src = tester.print( - &module.clone().fold_with(&mut HygieneVisualizer), + &program.clone().fold_with(&mut HygieneVisualizer), &tester.comments.clone(), ); println!("----- Hygiene -----\n{}", hygiene_src); @@ -588,14 +707,14 @@ where _ => {} } - let mut module = module + let mut program = program .fold_with(&mut hygiene::hygiene()) .fold_with(&mut fixer::fixer(Some(&tester.comments))); - let src_without_helpers = tester.print(&module, &tester.comments.clone()); - module = module.fold_with(&mut inject_helpers(Mark::fresh(Mark::root()))); + let src_without_helpers = tester.print(&program, &tester.comments.clone()); + program = program.fold_with(&mut inject_helpers(Mark::fresh(Mark::root()))); - let src = tester.print(&module, &tester.comments.clone()); + let src = tester.print(&program, &tester.comments.clone()); println!( "\t>>>>> {} <<<<<\n{}\n\t>>>>> {} <<<<<\n{}", @@ -609,6 +728,33 @@ where }) } +/// Execute `jest` after transpiling `input` using `tr`. +pub fn exec_tr(_test_name: &str, syntax: Syntax, tr: F, input: &str) +where + F: FnOnce(&mut Tester<'_>) -> P, + P: Fold, +{ + exec_tr_with(syntax, SrcType::Program, tr, input) +} + +/// Same as [exec_tr], but parses input as a [Module][Program::Module]. +pub fn exec_module_tr(_test_name: &str, syntax: Syntax, tr: F, input: &str) +where + F: FnOnce(&mut Tester<'_>) -> P, + P: Fold, +{ + exec_tr_with(syntax, SrcType::Module, tr, input) +} + +/// Same as [exec_tr], but parses input as a [Script][Program::Script]. +pub fn exec_script_tr(_test_name: &str, syntax: Syntax, tr: F, input: &str) +where + F: FnOnce(&mut Tester<'_>) -> P, + P: Fold, +{ + exec_tr_with(syntax, SrcType::Script, tr, input) +} + fn calc_hash(s: &str) -> String { let mut hasher = Sha256::new(); hasher.update(s.as_bytes()); @@ -693,6 +839,12 @@ fn stdout_of(code: &str) -> Result { /// Test transformation. #[macro_export] macro_rules! test_exec { + (@check) => { + if ::std::env::var("EXEC").unwrap_or(String::from("")) == "0" { + return; + } + }; + (ignore, $syntax:expr, $tr:expr, $test_name:ident, $input:expr) => { #[test] #[ignore] @@ -704,13 +856,26 @@ macro_rules! test_exec { ($syntax:expr, $tr:expr, $test_name:ident, $input:expr) => { #[test] fn $test_name() { - if ::std::env::var("EXEC").unwrap_or(String::from("")) == "0" { - return; - } - + test_exec!(@check); $crate::exec_tr(stringify!($test_name), $syntax, $tr, $input) } }; + + (module, $syntax:expr, $tr:expr, $test_name:ident, $input:expr) => { + #[test] + fn $test_name() { + test_exec!(@check); + $crate::exec_module_tr(stringify!($test_name), $syntax, $tr, $input) + } + }; + + (script, $syntax:expr, $tr:expr, $test_name:ident, $input:expr) => { + #[test] + fn $test_name() { + test_exec!(@check); + $crate::exec_script_tr(stringify!($test_name), $syntax, $tr, $input) + } + }; } /// Test transformation by invoking it using `node`. The code must print @@ -818,9 +983,10 @@ pub struct FixtureTestConfig { /// Defaults to false. pub allow_error: bool, } -/// You can do `UPDATE=1 cargo test` to update fixtures. -pub fn test_fixture

( + +fn test_fixture_with

( syntax: Syntax, + src_type: SrcType, tr: &dyn Fn(&mut Tester) -> P, input: &Path, output: &Path, @@ -832,6 +998,7 @@ pub fn test_fixture

( test_fixture_inner( syntax, + src_type, Box::new(|tester| Box::new(tr(tester))), &input, output, @@ -839,8 +1006,48 @@ pub fn test_fixture

( ); } +/// You can do `UPDATE=1 cargo test` to update fixtures. +pub fn test_fixture

( + syntax: Syntax, + tr: &dyn Fn(&mut Tester) -> P, + input: &Path, + output: &Path, + config: FixtureTestConfig, +) where + P: Fold, +{ + test_fixture_with(syntax, SrcType::Program, tr, input, output, config) +} + +/// Same as [test_fixture] but parses input as a [Module][SrcType::Module]. +pub fn test_module_fixture

( + syntax: Syntax, + tr: &dyn Fn(&mut Tester) -> P, + input: &Path, + output: &Path, + config: FixtureTestConfig, +) where + P: Fold, +{ + test_fixture_with(syntax, SrcType::Module, tr, input, output, config) +} + +/// Same as [test_fixture] but parses input as a [Script][SrcType::Script]. +pub fn test_script_fixture

( + syntax: Syntax, + tr: &dyn Fn(&mut Tester) -> P, + input: &Path, + output: &Path, + config: FixtureTestConfig, +) where + P: Fold, +{ + test_fixture_with(syntax, SrcType::Script, tr, input, output, config) +} + fn test_fixture_inner<'a>( syntax: Syntax, + src_type: SrcType, tr: Box Box>, input: &str, output: &Path, @@ -853,9 +1060,10 @@ fn test_fixture_inner<'a>( let expected = expected.unwrap_or_default(); let expected_src = Tester::run(|tester| { - let expected_module = tester.apply_transform(noop(), "expected.js", syntax, &expected)?; + let expected_program = + tester.apply_transform_with(noop(), "expected.js", syntax, &expected, src_type)?; - let expected_src = tester.print(&expected_module, &tester.comments.clone()); + let expected_src = tester.print(&expected_program, &tester.comments.clone()); println!( "----- {} -----\n{}", @@ -881,7 +1089,7 @@ fn test_fixture_inner<'a>( eprintln!("----- {} -----", Color::Green.paint("Actual")); - let actual = tester.apply_transform(tr, "input.js", syntax, input)?; + let actual = tester.apply_transform_with(tr, "input.js", syntax, input, src_type)?; eprintln!("----- {} -----", Color::Green.paint("Comments")); eprintln!("{:?}", tester.comments);