use super::*;
use std::fs;
use std::time::Duration;
use tempfile::TempDir;
use tokio::time::sleep;
#[tokio::test]
async fn source_folder_overlapping_output_dir_is_rejected() {
let root = TempDir::new().unwrap();
let result = Server::new(root.path())
.unwrap()
.with_source_folder(root.path());
assert!(
result.is_err(),
"a source folder equal to the output dir must be rejected"
);
}
#[tokio::test]
async fn source_folder_inside_output_dir_is_rejected() {
let root = TempDir::new().unwrap();
let nested = root.path().join("nested");
fs::create_dir(&nested).unwrap();
let result = Server::new(root.path())
.unwrap()
.with_source_folder(&nested);
assert!(
result.is_err(),
"a source folder nested in the output dir must be rejected"
);
}
#[tokio::test]
async fn output_dir_overlapping_source_folder_is_rejected() {
let root = TempDir::new().unwrap();
let source = TempDir::new().unwrap();
let server = Server::new(root.path())
.unwrap()
.with_source_folder(source.path())
.unwrap();
let result = server.with_output_dir(source.path());
assert!(
result.is_err(),
"an output dir equal to a source folder must be rejected"
);
}
#[tokio::test]
async fn css_bundle_creates_output_on_startup_with_live_reload() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
fs::write(src.path().join("style.css"), "body { margin: 0; }").unwrap();
let server = Server::new(out.path())
.unwrap()
.with_live_reload()
.with_source_folder(src.path())
.unwrap()
.with_css_tool(CssTool::TestEcho, CssOptions::new().bundle(true));
let (_port, handle) = server.run_ephemeral().await.unwrap();
sleep(Duration::from_millis(800)).await;
let bundle = out.path().join("styles.css");
assert!(
bundle.exists(),
"bundle should be written to the default <output>/styles.css"
);
let content = fs::read_to_string(&bundle).unwrap();
assert!(!content.is_empty(), "bundle should contain CSS");
handle.shutdown().await;
}
#[tokio::test]
async fn css_bundle_rebuilds_once_and_settles_when_source_css_changes() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
let src_path = src.path();
let bundle = out.path().join("styles.css");
fs::write(src_path.join("style.css"), "body { margin: 0; }").unwrap();
let server = Server::new(out.path())
.unwrap()
.with_live_reload()
.with_source_folder(src_path)
.unwrap()
.with_css_tool(CssTool::TestEcho, CssOptions::new().bundle(true));
let (_port, handle) = server.run_ephemeral().await.unwrap();
sleep(Duration::from_millis(800)).await;
assert!(bundle.exists());
fs::write(
src_path.join("style.css"),
"body { margin: 0; color: blue; }",
)
.unwrap();
sleep(Duration::from_millis(1500)).await;
let content_v2 = fs::read_to_string(&bundle).unwrap();
assert!(
content_v2.contains("color"),
"rebundle should contain the new color rule"
);
let mtime_after = fs::metadata(&bundle).unwrap().modified().unwrap();
sleep(Duration::from_millis(1200)).await;
let mtime_later = fs::metadata(&bundle).unwrap().modified().unwrap();
assert_eq!(
mtime_after, mtime_later,
"bundle mtime must settle after one rebuild — an ongoing loop would keep changing it"
);
handle.shutdown().await;
}
#[tokio::test]
async fn css_bundle_creates_output_on_startup_without_live_reload() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
fs::write(src.path().join("style.css"), "body { margin: 0; }").unwrap();
let server = Server::new(out.path())
.unwrap()
.with_source_folder(src.path())
.unwrap()
.with_css_tool(CssTool::TestEcho, CssOptions::new().bundle(true));
let (_port, handle) = server.run_ephemeral().await.unwrap();
sleep(Duration::from_millis(200)).await;
let bundle = out.path().join("styles.css");
assert!(
bundle.exists(),
"bundle should be created even without live_reload"
);
let content = fs::read_to_string(&bundle).unwrap();
assert!(!content.is_empty(), "bundle should contain CSS");
handle.shutdown().await;
}
#[tokio::test]
async fn css_bundle_concatenates_multiple_source_css_files() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
fs::write(src.path().join("reset.css"), "* { margin: 0; padding: 0; }").unwrap();
fs::write(src.path().join("theme.css"), "body { background: white; }").unwrap();
let server = Server::new(out.path())
.unwrap()
.with_live_reload()
.with_source_folder(src.path())
.unwrap()
.with_css_tool(CssTool::TestEcho, CssOptions::new().bundle(true));
let (_port, handle) = server.run_ephemeral().await.unwrap();
sleep(Duration::from_millis(800)).await;
let content = fs::read_to_string(out.path().join("styles.css")).unwrap();
assert!(
content.contains("margin"),
"output should contain reset CSS"
);
assert!(
content.contains("background"),
"output should contain theme CSS"
);
handle.shutdown().await;
}