use super::*;
use tempfile::TempDir;
#[tokio::test]
async fn bundle_mode_concatenates_discovered_files_in_sorted_order() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
let output = out.path().join("styles.css");
fs::write(src.path().join("a.css"), "A").unwrap();
fs::write(src.path().join("b.css"), "B").unwrap();
let options = CssOptions::new().bundle(true).minify(true);
build_css_bundle(
CssTool::TestEcho,
&options,
&[src.path().to_path_buf()],
&output,
)
.await
.unwrap();
let content = fs::read_to_string(&output).unwrap();
assert_eq!(content, "AB", "files must concatenate in sorted path order");
}
#[tokio::test]
async fn bundle_false_minify_false_is_a_passthrough_copy() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
let output = out.path().join("styles.css");
fs::write(src.path().join("only.css"), "body{color:red}").unwrap();
let options = CssOptions::new();
build_css_bundle(
CssTool::TestMissing,
&options,
&[src.path().to_path_buf()],
&output,
)
.await
.unwrap();
assert_eq!(fs::read_to_string(&output).unwrap(), "body{color:red}");
}
#[tokio::test]
async fn no_css_files_is_an_error() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
let output = out.path().join("styles.css");
let result = build_css_bundle(
CssTool::TestEcho,
&CssOptions::new().bundle(true),
&[src.path().to_path_buf()],
&output,
)
.await;
assert!(matches!(result, Err(CssError::NoFilesFound(_))));
}
#[tokio::test]
async fn a_failing_tool_leaves_previous_bundle_output_untouched() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
let output = out.path().join("styles.css");
fs::write(&output, "/* previous good build */").unwrap();
fs::write(src.path().join("a.css"), "A").unwrap();
let result = build_css_bundle(
CssTool::TestMissing,
&CssOptions::new().bundle(true).minify(true),
&[src.path().to_path_buf()],
&output,
)
.await;
assert!(result.is_err());
assert_eq!(
fs::read_to_string(&output).unwrap(),
"/* previous good build */",
"a failed rebuild must not overwrite the previous good bundle"
);
}
#[tokio::test]
async fn per_file_mode_with_minify_false_copies_through_unchanged() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
let source = src.path().join("app.css");
let output = out.path().join("app.css");
fs::write(&source, "body{color:blue}").unwrap();
build_css_file(CssTool::TestMissing, &CssOptions::new(), &source, &output)
.await
.unwrap();
assert_eq!(fs::read_to_string(&output).unwrap(), "body{color:blue}");
}
#[tokio::test]
async fn per_file_mode_already_minified_skips_the_tool() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
let source = src.path().join("app.min.css");
let output = out.path().join("app.min.css");
fs::write(&source, "body{color:blue}").unwrap();
build_css_file(
CssTool::TestMissing,
&CssOptions::new().minify(true),
&source,
&output,
)
.await
.unwrap();
assert_eq!(fs::read_to_string(&output).unwrap(), "body{color:blue}");
}
#[tokio::test]
async fn per_file_mode_degrades_to_raw_copy_when_the_tool_fails() {
let src = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
let source = src.path().join("app.css");
let output = out.path().join("app.css");
fs::write(&source, "body{color:blue}").unwrap();
build_css_file(
CssTool::TestMissing,
&CssOptions::new().minify(true),
&source,
&output,
)
.await
.unwrap();
assert_eq!(
fs::read_to_string(&output).unwrap(),
"body{color:blue}",
"a failing tool must degrade to serving the raw source, not fail the pipeline"
);
}