use crate::{App, INDEX_HTML};
const PLUGINS: &str = r#"export default [{
name: "bad-plugin",
resolveId(id) { return id === "virtual:boom" ? "\0boom" : null; },
load(id) { if (id === "\0boom") throw new Error("load exploded"); return null; },
transform(code, id) {
if (id.split("?")[0].endsWith("bad.js")) this.error({ message: "transform exploded", loc: { line: 2, column: 3 }, frame: "2 | export const C = 2;\n | ^\n" });
return null;
},
}];
"#;
#[tokio::test(flavor = "multi_thread")]
async fn throwing_transform_and_load_fail_the_module_with_the_plugin_error() {
let app = App::new(&[
("package.json", r#"{"name":"plugerr","version":"1.0.0"}"#),
(
"src/bad.js",
"export const B = \"RAW_SOURCE_MARKER\";\nexport const C = 2;\n",
),
(
"src/virt-user.js",
"import \"virtual:boom\";\nexport const V = 1;\n",
),
("src/fine.js", "export const F = 1;\n"),
(
"src/main.js",
"import \"./bad.js\";\nimport \"./fine.js\";\n",
),
("index.html", INDEX_HTML),
("oj.plugins.mjs", PLUGINS),
]);
let server = app.serve().await;
let bad = server.get("/src/bad.js").await;
assert_eq!(
bad.status, 500,
"throwing transform must 500:\n{}",
bad.body
);
assert!(
bad.body.contains("[plugin:bad-plugin] transform exploded"),
"error names the plugin:\n{}",
bad.body
);
assert!(
bad.body.contains("bad.js:2:3"),
"error carries the location:\n{}",
bad.body
);
assert!(
bad.body.contains("2 | export const C = 2;"),
"error carries the code frame:\n{}",
bad.body
);
assert!(
!bad.body.contains("RAW_SOURCE_MARKER"),
"raw source must not be served:\n{}",
bad.body
);
let vbody = server.text("/src/virt-user.js").await;
let virt_url = regex::Regex::new(r#"from\s+"([^"]+)""#)
.unwrap()
.captures(&vbody)
.or_else(|| {
regex::Regex::new(r#"import\s+"([^"]+)""#)
.unwrap()
.captures(&vbody)
})
.map(|c| c[1].to_string())
.unwrap_or_else(|| panic!("importer should reference the virtual module url:\n{vbody}"));
let vmod = server.get(&virt_url).await;
assert_eq!(vmod.status, 500, "throwing load must 500:\n{}", vmod.body);
assert!(
vmod.body.contains("[plugin:bad-plugin] load exploded"),
"load error names the plugin:\n{}",
vmod.body
);
let fine = server.get("/src/fine.js").await;
assert_eq!(
fine.status, 200,
"unaffected modules still serve:\n{}",
fine.body
);
}