use std::env;
use std::fmt::Write;
use insta::{assert_snapshot, glob};
use miette::{NamedSource, Report};
use react_build_hir::build;
use react_estree::{ModuleItem, Statement};
use react_hermes_parser::parse;
use react_hir::{inline_use_memo, Environment, Features, Print, Registry};
use react_optimization::constant_propagation;
use react_semantic_analysis::analyze;
use react_ssa::{eliminate_redundant_phis, enter_ssa};
#[test]
fn fixtures() {
glob!("fixtures/**.js", |path| {
println!("fixture {}", path.to_str().unwrap());
let input = std::fs::read_to_string(path).unwrap();
let ast = parse(&input, path.to_str().unwrap()).unwrap();
println!("ok parse");
let mut output = String::new();
let mut analysis = analyze(&ast, Default::default());
let diagnostics = analysis.diagnostics();
if !diagnostics.is_empty() {
for diagnostic in diagnostics {
eprintln!(
"{:?}",
Report::new(diagnostic)
.with_source_code(NamedSource::new(path.to_string_lossy(), input.clone(),))
);
}
}
let environment = Environment::new(
Features {
validate_frozen_lambdas: true,
},
Registry,
analysis,
);
for (ix, item) in ast.body.iter().enumerate() {
if let ModuleItem::Statement(stmt) = item {
if let Statement::FunctionDeclaration(fun) = stmt {
if ix != 0 {
output.push_str("\n\n");
}
match build(&environment, &fun.function) {
Ok(mut fun) => {
println!("ok build");
enter_ssa(&environment, &mut fun).unwrap();
println!("ok enter_ssa");
eliminate_redundant_phis(&environment, &mut fun);
println!("ok eliminate_redundant_phis");
constant_propagation(&environment, &mut fun).unwrap();
println!("ok constant_propagation");
inline_use_memo(&environment, &mut fun).unwrap();
println!("ok inline_use_memo");
fun.print(&fun.body, &mut output).unwrap();
println!("ok print");
}
Err(error) => {
write!(&mut output, "{}", error,).unwrap();
eprintln!(
"{:?}",
Report::new(error).with_source_code(NamedSource::new(
path.to_string_lossy(),
input.clone(),
))
);
continue;
}
};
}
}
}
let output = output.trim();
assert_snapshot!(format!("Input:\n{input}\n\nOutput:\n{output}"));
});
}