use std::fs;
use super::{build_app, scratch, write_files};
fn hashed_script_src(html: &str) -> Option<&str> {
let start = html.find(r#"src="/assets/"#)? + r#"src=""#.len();
let len = html[start..].find('"')?;
let src = &html[start..start + len];
src.ends_with(".js").then_some(src)
}
#[tokio::test]
async fn explicit_html_inputs_build_without_a_root_index_html() {
let root = scratch("multi-html-input");
write_files(
&root,
&[
("package.json", r#"{"name":"mh-app","version":"1.0.0"}"#),
(
"oj.config.json",
r#"{"build":{"manifest":true,"rolldownOptions":{"input":{"admin":"pages/admin/index.html","app":"pages/app/index.html"}}}}"#,
),
("pages/admin/admin.js", "document.title = \"admin\";\n"),
("pages/app/app.js", "document.title = \"app\";\n"),
(
"pages/admin/index.html",
r#"<!doctype html><html><head><title>admin</title></head><body><script type="module" src="./admin.js"></script></body></html>"#,
),
(
"pages/app/index.html",
r#"<!doctype html><html><head><title>app</title></head><body><script type="module" src="./app.js"></script></body></html>"#,
),
],
);
build_app(&root)
.await
.expect("explicit html inputs build without a root index.html");
let dist = root.join("dist");
let admin_html = fs::read_to_string(dist.join("pages/admin/index.html"))
.expect("admin page emitted at its root-relative path");
let app_html = fs::read_to_string(dist.join("pages/app/index.html"))
.expect("app page emitted at its root-relative path");
let admin_src = hashed_script_src(&admin_html)
.unwrap_or_else(|| panic!("admin html references a hashed chunk:\n{admin_html}"));
let app_src = hashed_script_src(&app_html)
.unwrap_or_else(|| panic!("app html references a hashed chunk:\n{app_html}"));
assert_ne!(admin_src, app_src, "each page has its own entry chunk");
for src in [admin_src, app_src] {
assert!(
dist.join(src.trim_start_matches('/')).exists(),
"chunk {src} exists"
);
}
let manifest = fs::read_to_string(dist.join(".vite/manifest.json")).expect("manifest written");
let manifest: serde_json::Value = serde_json::from_str(&manifest).expect("manifest is JSON");
let keys: Vec<&String> = manifest
.as_object()
.expect("manifest is an object")
.keys()
.collect();
assert!(
keys.iter().any(|k| k.contains("pages/admin/admin.js")),
"manifest keys the admin entry by its source path: {keys:?}"
);
assert!(
keys.iter().any(|k| k.contains("pages/app/app.js")),
"manifest keys the app entry by its source path: {keys:?}"
);
}