mini-static 0.14.7

A secure, async static file server with streaming, traversal protection, and connection limits.
Documentation
use mini_static::bundle_directory_css;
use std::fs;
use tempfile::TempDir;

#[tokio::test]
async fn bundles_single_css_file() {
    let src = TempDir::new().unwrap();
    let out = TempDir::new().unwrap();
    let out_path = out.path().join("bundle.css");

    fs::write(src.path().join("style.css"), "body { margin: 0; }").unwrap();

    let result = bundle_directory_css(src.path(), &out_path).await;
    assert!(result.is_ok());
    assert!(out_path.exists());
    let content = fs::read_to_string(&out_path).unwrap();
    assert!(!content.is_empty());
}

#[tokio::test]
async fn bundles_multiple_css_files() {
    let src = TempDir::new().unwrap();
    let out = TempDir::new().unwrap();
    let out_path = out.path().join("bundle.css");

    fs::write(src.path().join("a.css"), "body { color: red; }").unwrap();
    fs::write(src.path().join("b.css"), ".class { color: blue; }").unwrap();

    let result = bundle_directory_css(src.path(), &out_path).await;
    assert!(result.is_ok());
    assert!(out_path.exists());
    let content = fs::read_to_string(&out_path).unwrap();
    assert!(content.contains("color"));
}

#[tokio::test]
async fn creates_output_directory_if_missing() {
    let src = TempDir::new().unwrap();
    let out = TempDir::new().unwrap();
    let nested_out = out.path().join("nested/deep/bundle.css");

    fs::write(src.path().join("style.css"), "body { margin: 0; }").unwrap();

    let result = bundle_directory_css(src.path(), &nested_out).await;
    assert!(result.is_ok());
    assert!(nested_out.exists());
}

#[tokio::test]
async fn bundles_css_in_subdirectories() {
    let src = TempDir::new().unwrap();
    let out = TempDir::new().unwrap();
    let out_path = out.path().join("bundle.css");

    fs::create_dir(src.path().join("subdir")).unwrap();
    fs::write(src.path().join("main.css"), "body { margin: 0; }").unwrap();
    fs::write(src.path().join("subdir/nested.css"), ".nested { color: green; }").unwrap();

    let result = bundle_directory_css(src.path(), &out_path).await;
    assert!(result.is_ok());
    let content = fs::read_to_string(&out_path).unwrap();
    assert!(content.contains("nested"));
}

#[tokio::test]
async fn handles_imports_in_non_first_files() {
    let src = TempDir::new().unwrap();
    let out = TempDir::new().unwrap();
    let out_path = out.path().join("bundle.css");

    fs::write(src.path().join("base.css"), "body { font-family: sans-serif; }").unwrap();
    fs::write(src.path().join("main.css"), "@import \"base.css\";\n.main { color: blue; }").unwrap();

    let result = bundle_directory_css(src.path(), &out_path).await;
    assert!(result.is_ok());

    let content = fs::read_to_string(&out_path).unwrap();
    assert!(content.contains("font-family"));
    assert!(content.contains("color"));
    assert!(!content.contains("@import"));

    let family_idx = content.find("font-family").unwrap();
    let main_idx = content.find("color").unwrap();
    assert!(family_idx < main_idx);
}

#[tokio::test]
async fn output_is_minified() {
    let src = TempDir::new().unwrap();
    let out = TempDir::new().unwrap();
    let out_path = out.path().join("bundle.css");

    let input = "body {\n  margin: 0;\n  padding: 0;\n}\n\n.class {\n  color: red;\n}";
    fs::write(src.path().join("style.css"), input).unwrap();

    let result = bundle_directory_css(src.path(), &out_path).await;
    assert!(result.is_ok());
    let content = fs::read_to_string(&out_path).unwrap();

    let line_count = content.lines().count();
    assert!(line_count <= 2, "got {} lines", line_count);
    assert!(!content.contains("{\n"));
    assert!(content.len() < input.len());
}

#[tokio::test]
async fn multiple_files_fully_minified() {
    let src = TempDir::new().unwrap();
    let out = TempDir::new().unwrap();
    let out_path = out.path().join("bundle.css");

    fs::write(src.path().join("a.css"), "body {\n  margin: 0;\n}").unwrap();
    fs::write(src.path().join("b.css"), ".class {\n  padding: 10px;\n}").unwrap();
    fs::write(src.path().join("c.css"), "#id {\n  color: blue;\n}").unwrap();

    let result = bundle_directory_css(src.path(), &out_path).await;
    assert!(result.is_ok());
    let content = fs::read_to_string(&out_path).unwrap();

    assert!(content.contains("margin"));
    assert!(content.contains("padding"));
    assert!(content.contains("color"));

    let line_count = content.lines().count();
    assert!(line_count <= 2, "got {} lines", line_count);
}