2021-06-23 13:50:27 +03:00
|
|
|
#![allow(unused)]
|
|
|
|
|
2021-08-13 13:03:04 +03:00
|
|
|
use anyhow::{Context, Error};
|
|
|
|
use std::{
|
|
|
|
env::temp_dir,
|
|
|
|
fs,
|
|
|
|
fs::{canonicalize, create_dir_all},
|
|
|
|
path::PathBuf,
|
|
|
|
process::{Command, Output},
|
|
|
|
sync::Arc,
|
|
|
|
};
|
2020-02-16 10:51:42 +03:00
|
|
|
use swc::{
|
|
|
|
config::{Options, SourceMapsConfig},
|
|
|
|
Compiler,
|
|
|
|
};
|
2021-08-13 13:03:04 +03:00
|
|
|
use testing::{assert_eq, NormalizedOutput, StdErr, Tester};
|
2021-04-16 21:09:38 +03:00
|
|
|
use walkdir::WalkDir;
|
2020-02-16 10:51:42 +03:00
|
|
|
|
|
|
|
fn file(f: &str) -> Result<(), StdErr> {
|
|
|
|
Tester::new().print_errors(|cm, handler| {
|
|
|
|
let path = canonicalize(f).expect("failed to canonicalize");
|
|
|
|
|
2021-08-13 10:05:40 +03:00
|
|
|
let c = Compiler::new(cm.clone());
|
2020-02-16 10:51:42 +03:00
|
|
|
|
|
|
|
let fm = cm.load_file(&path).expect("failed to load file");
|
|
|
|
let s = c
|
|
|
|
.process_js_file(
|
|
|
|
fm,
|
2021-08-13 10:05:40 +03:00
|
|
|
&handler,
|
2020-02-16 10:51:42 +03:00
|
|
|
&Options {
|
|
|
|
swcrc: true,
|
|
|
|
is_module: true,
|
|
|
|
source_maps: Some(SourceMapsConfig::Bool(true)),
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.expect("failed to process js file");
|
|
|
|
|
|
|
|
let js_path = path.parent().unwrap().join("index.g.js");
|
|
|
|
std::fs::write(&js_path, s.code.as_bytes()).unwrap();
|
|
|
|
|
|
|
|
let map_path = path.parent().unwrap().join("index.js.map");
|
|
|
|
std::fs::write(&map_path, s.map.unwrap().as_bytes()).unwrap();
|
|
|
|
|
|
|
|
let output = Command::new("node")
|
|
|
|
.arg("-e")
|
|
|
|
.arg(include_str!("source_map.js"))
|
|
|
|
.arg(js_path)
|
|
|
|
.arg(map_path)
|
|
|
|
.output()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
if output.status.success() {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
|
|
|
panic!(
|
|
|
|
"Validation failed: \n{}\n{}",
|
|
|
|
String::from_utf8_lossy(&output.stdout),
|
|
|
|
String::from_utf8_lossy(&output.stderr)
|
|
|
|
);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn issue_622() {
|
|
|
|
file("tests/srcmap/issue-622/index.js").unwrap();
|
|
|
|
}
|
2020-03-13 17:34:36 +03:00
|
|
|
|
|
|
|
fn inline(f: &str) -> Result<(), StdErr> {
|
|
|
|
Tester::new().print_errors(|cm, handler| {
|
|
|
|
let path = canonicalize(f).expect("failed to canonicalize");
|
|
|
|
|
2021-08-13 10:05:40 +03:00
|
|
|
let c = Compiler::new(cm.clone());
|
2020-03-13 17:34:36 +03:00
|
|
|
|
|
|
|
let fm = cm.load_file(&path).expect("failed to load file");
|
|
|
|
let s = c
|
|
|
|
.process_js_file(
|
|
|
|
fm,
|
2021-08-13 10:05:40 +03:00
|
|
|
&handler,
|
2020-03-13 17:34:36 +03:00
|
|
|
&Options {
|
|
|
|
swcrc: true,
|
|
|
|
is_module: true,
|
|
|
|
source_maps: Some(SourceMapsConfig::Str(String::from("inline"))),
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.expect("failed to process js file");
|
|
|
|
|
|
|
|
let js_path = path.parent().unwrap().join("index.g.js");
|
|
|
|
std::fs::write(&js_path, s.code.as_bytes()).unwrap();
|
|
|
|
|
|
|
|
let output = Command::new("node")
|
|
|
|
.arg("-e")
|
|
|
|
.arg(include_str!("source_map_inline.js"))
|
|
|
|
.arg(js_path)
|
|
|
|
.output()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
if output.status.success() {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
|
|
|
panic!(
|
|
|
|
"Validation failed: \n{}\n{}",
|
|
|
|
String::from_utf8_lossy(&output.stdout),
|
|
|
|
String::from_utf8_lossy(&output.stderr)
|
|
|
|
);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
fn issue_706() {
|
|
|
|
inline("tests/srcmap/issue-706/index.js").unwrap();
|
|
|
|
}
|
2021-04-16 21:09:38 +03:00
|
|
|
|
2021-06-23 13:50:27 +03:00
|
|
|
#[cfg(target_os = "node-16-breaks-the-test")]
|
2021-04-16 21:09:38 +03:00
|
|
|
#[testing::fixture("stacktrace/**/input/")]
|
|
|
|
fn stacktrace(input_dir: PathBuf) {
|
2021-06-18 14:34:17 +03:00
|
|
|
let dir = input_dir.parent().unwrap();
|
|
|
|
let output_dir = dir.join("output");
|
|
|
|
|
|
|
|
let _ = create_dir_all(&output_dir);
|
|
|
|
|
2021-04-16 21:09:38 +03:00
|
|
|
Tester::new()
|
|
|
|
.print_errors(|cm, handler| {
|
|
|
|
let c = Compiler::new(cm.clone(), Arc::new(handler));
|
|
|
|
|
|
|
|
for entry in WalkDir::new(&input_dir) {
|
|
|
|
let entry = entry.unwrap();
|
|
|
|
if entry.metadata().unwrap().is_dir() {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
println!("File: {}", entry.path().to_string_lossy());
|
|
|
|
|
2021-06-18 14:34:17 +03:00
|
|
|
if !entry.file_name().to_string_lossy().ends_with(".js") {
|
2021-04-16 21:09:38 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
let fm = cm.load_file(entry.path()).expect("failed to load file");
|
|
|
|
|
|
|
|
println!("-----Orig:\n{}\n-----", fm.src);
|
|
|
|
|
|
|
|
match c.process_js_file(
|
|
|
|
fm,
|
|
|
|
&Options {
|
|
|
|
swcrc: true,
|
|
|
|
is_module: true,
|
|
|
|
source_maps: Some(SourceMapsConfig::Str("inline".to_string())),
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
) {
|
|
|
|
Ok(v) => {
|
|
|
|
// We created a javascript file with inline source map.
|
|
|
|
assert_eq!(v.map, None, "Source maps should be inlined");
|
|
|
|
|
|
|
|
println!("-----Compiled:\n{}\n-----", v.code);
|
|
|
|
|
2021-06-18 14:34:17 +03:00
|
|
|
let stack_trace = node_stack_trace(&v.code)
|
2021-04-16 21:09:38 +03:00
|
|
|
.expect("failed to capture output of node -e 'generated code'");
|
|
|
|
|
2021-06-18 14:34:17 +03:00
|
|
|
stack_trace
|
|
|
|
.compare_to_file(output_dir.join("stacks.txt"))
|
|
|
|
.expect("wrong stack trace");
|
2021-04-16 21:09:38 +03:00
|
|
|
}
|
|
|
|
Err(err) => panic!("Error: {:?}", err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
})
|
|
|
|
.map(|_| ())
|
|
|
|
.expect("failed");
|
|
|
|
}
|
|
|
|
|
2021-06-18 14:34:17 +03:00
|
|
|
fn node_stack_trace(code: &str) -> Result<NormalizedOutput, Error> {
|
|
|
|
let thread = std::thread::current();
|
|
|
|
let test_name = thread.name().expect("test thread should have a name");
|
|
|
|
|
|
|
|
let dir = temp_dir().join(test_name);
|
|
|
|
|
|
|
|
let _ = create_dir_all(&dir);
|
|
|
|
|
|
|
|
let test_file = dir.join("eval.js");
|
|
|
|
fs::write(&test_file, code.as_bytes()).context("faailed to write to test js")?;
|
|
|
|
|
|
|
|
let stack = Command::new("node")
|
|
|
|
.arg("--enable-source-maps")
|
|
|
|
.arg(&test_file)
|
|
|
|
.output()
|
|
|
|
.map(extract_node_stack_trace)?;
|
|
|
|
|
|
|
|
Ok(stack)
|
|
|
|
}
|
|
|
|
|
2021-04-16 21:09:38 +03:00
|
|
|
/// Extract stack trace from output of `node -e 'code'`.
|
|
|
|
///
|
|
|
|
/// TODO: Use better type.
|
2021-06-18 14:34:17 +03:00
|
|
|
fn extract_node_stack_trace(output: Output) -> NormalizedOutput {
|
2021-04-16 21:09:38 +03:00
|
|
|
assert!(
|
|
|
|
!output.status.success(),
|
|
|
|
"Stack trace tests should fail with stack traces"
|
|
|
|
);
|
|
|
|
|
|
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
2021-06-23 13:50:27 +03:00
|
|
|
|
|
|
|
eprintln!("\n\n\nStderr: {}\n\n\n", stderr);
|
2021-04-16 21:09:38 +03:00
|
|
|
//
|
|
|
|
let stacks = stderr
|
|
|
|
.split(|c| c == '\n')
|
2021-06-18 14:34:17 +03:00
|
|
|
.map(|s| s.trim())
|
|
|
|
.filter(|s| s.starts_with("->"))
|
2021-04-16 21:09:38 +03:00
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
2021-06-18 14:34:17 +03:00
|
|
|
let stacks = stacks.join("\n");
|
|
|
|
// println!("{:?}", stacks);
|
2021-04-16 21:09:38 +03:00
|
|
|
|
2021-06-18 14:34:17 +03:00
|
|
|
stacks.into()
|
2021-04-16 21:09:38 +03:00
|
|
|
}
|