diff --git a/crates/oxc_transformer/examples/transformer.rs b/crates/oxc_transformer/examples/transformer.rs index eb63ca05a..ff6571d6e 100644 --- a/crates/oxc_transformer/examples/transformer.rs +++ b/crates/oxc_transformer/examples/transformer.rs @@ -33,12 +33,11 @@ fn main() { println!("Original:\n"); println!("{printed}"); - let program = allocator.alloc(ret.program); - - let semantic = SemanticBuilder::new(&source_text, source_type).build(program).semantic; + let semantic = SemanticBuilder::new(&source_text, source_type).build(&ret.program).semantic; let (symbols, _scope_tree) = semantic.into_symbol_table_and_scope_tree(); let symbols = Rc::new(RefCell::new(symbols)); + let program = allocator.alloc(ret.program); let transform_options = TransformOptions { target: TransformTarget::ES2015, react: Some(TransformReactOptions::default()), diff --git a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs index 7e65c1d75..1272d01ce 100644 --- a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs +++ b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs @@ -255,3 +255,21 @@ fn gather_node_parts(expr: &Expression, parts: &mut std::vec::Vec) { _ => parts.push(Atom::from("ref")), } } + +#[test] +fn test() { + use crate::{ + options::{TransformOptions, TransformTarget}, + tester::Tester, + }; + + let options = + TransformOptions { target: TransformTarget::ES2015, ..TransformOptions::default() }; + + let tests = &[( + "let x = {}; let y = 0; let z = 0; x[z++] **= y;", + "var _ref; let x = {}; let y = 0; let z = 0; _ref = z++,x[_ref] = Math.pow(x[_ref], y);", + )]; + + Tester::new("test.js", options).test(tests); +} diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index e814379db..2d5f3ddf0 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -15,6 +15,8 @@ mod es2022; mod options; mod react_jsx; mod regexp; +#[cfg(test)] +mod tester; mod typescript; use std::{cell::RefCell, rc::Rc}; diff --git a/crates/oxc_transformer/src/tester.rs b/crates/oxc_transformer/src/tester.rs new file mode 100644 index 000000000..a5425666e --- /dev/null +++ b/crates/oxc_transformer/src/tester.rs @@ -0,0 +1,50 @@ +use std::{cell::RefCell, rc::Rc}; + +use oxc_allocator::Allocator; +use oxc_codegen::{Codegen, CodegenOptions}; +use oxc_parser::Parser; +use oxc_semantic::SemanticBuilder; +use oxc_span::SourceType; + +use crate::{TransformOptions, Transformer}; + +pub struct Tester { + source_type: SourceType, + + options: TransformOptions, + + allocator: Allocator, +} + +impl Tester { + pub fn new(filename: &str, options: TransformOptions) -> Self { + let source_type = SourceType::from_path(filename).unwrap(); + Self { source_type, options, allocator: Allocator::default() } + } + + pub fn test(&self, tests: &[(&str, &str)]) { + for (source_text, expected) in tests { + let transformed = self.transform(source_text); + let expected = self.codegen(expected); + assert_eq!(transformed, expected, "{source_text}"); + } + } + + fn transform(&self, source_text: &str) -> String { + let program = Parser::new(&self.allocator, source_text, self.source_type).parse().program; + + let semantic = SemanticBuilder::new(source_text, self.source_type).build(&program).semantic; + let (symbols, _scope_tree) = semantic.into_symbol_table_and_scope_tree(); + let symbols = Rc::new(RefCell::new(symbols)); + + let program = self.allocator.alloc(program); + Transformer::new(&self.allocator, self.source_type, &symbols, self.options.clone()) + .build(program); + Codegen::::new(source_text.len(), CodegenOptions).build(program) + } + + fn codegen(&self, source_text: &str) -> String { + let program = Parser::new(&self.allocator, source_text, self.source_type).parse().program; + Codegen::::new(source_text.len(), CodegenOptions).build(&program) + } +} diff --git a/tasks/transform_conformance/src/lib.rs b/tasks/transform_conformance/src/lib.rs index ec19a1444..451c7e8c9 100644 --- a/tasks/transform_conformance/src/lib.rs +++ b/tasks/transform_conformance/src/lib.rs @@ -15,6 +15,13 @@ use oxc_span::{SourceType, VALID_EXTENSIONS}; use oxc_tasks_common::{normalize_path, project_root}; use oxc_transformer::{TransformOptions, TransformReactOptions, TransformTarget, Transformer}; +#[test] +#[cfg(any(coverage, coverage_nightly))] +fn test() { + babel(&BabelOptions::default()); +} + +#[derive(Default)] pub struct BabelOptions { pub filter: Option, }