mini-docs 0.7.0

A minimal, secure build-time Markdown to HTML generator for the mini-* family.
Documentation
use super::*;

/// Routes a `/`-written source path, so these tests read as paths rather than as
/// `PathBuf` construction.
fn routed(md: &str, pretty_urls: bool) -> (String, String) {
    let route = route(Path::new(md), pretty_urls);
    (to_url_path(&route.output_relative), route.url_relative)
}

#[test]
fn plain_urls_write_a_sibling_html_file_and_serve_it_by_name() {
    assert_eq!(
        routed("guide/setup.md", false),
        (
            "guide/setup.html".to_string(),
            "guide/setup.html".to_string()
        )
    );
}

#[test]
fn plain_urls_advertise_the_file_that_is_actually_written() {
    let route = route(Path::new("article.md"), false);

    assert_eq!(
        route.url_relative,
        to_url_path(&route.output_relative),
        "a URL that names a file other than the one written is a 404 by construction"
    );
}

#[test]
fn pretty_urls_write_a_directory_index_and_serve_the_bare_name() {
    assert_eq!(
        routed("guide/setup.md", true),
        (
            "guide/setup/index.html".to_string(),
            "guide/setup/".to_string()
        )
    );
}

#[test]
fn pretty_urls_resolve_through_the_directory_they_write() {
    let route = route(Path::new("guide/setup.md"), true);

    assert_eq!(
        format!("{}{DIRECTORY_INDEX}", route.url_relative),
        to_url_path(&route.output_relative),
        "the served URL must be the written file's directory"
    );
}

#[test]
fn an_index_source_never_gains_a_second_index_level() {
    assert_eq!(
        routed("guide/index.md", true).0,
        "guide/index.html",
        "index.md is already its directory's index"
    );
}

#[test]
fn a_pretty_index_source_is_served_as_its_directory() {
    assert_eq!(routed("guide/index.md", true).1, "guide/");
}

#[test]
fn a_pretty_index_at_the_root_is_served_as_the_root() {
    assert_eq!(
        routed("index.md", true),
        ("index.html".to_string(), String::new())
    );
}

#[test]
fn a_plain_index_source_keeps_its_name_in_the_url() {
    assert_eq!(
        routed("index.md", false),
        ("index.html".to_string(), "index.html".to_string())
    );
}

#[test]
fn a_nested_source_keeps_its_directories() {
    assert_eq!(routed("a/b/c/deep.md", true).0, "a/b/c/deep/index.html");
}

#[test]
fn plain_links_point_at_the_html_file() {
    assert_eq!(route_link("guide/setup", false), "guide/setup.html");
}

#[test]
fn pretty_links_point_at_the_directory_that_serves_the_page() {
    assert_eq!(route_link("guide/setup", true), "guide/setup/");
}

#[test]
fn a_pretty_link_to_an_index_points_at_its_directory() {
    assert_eq!(route_link("guide/index", true), "guide/");
}

#[test]
fn a_pretty_link_to_the_root_index_points_at_the_root() {
    assert_eq!(route_link("index", true), "");
}

/// Every pretty URL must name a directory, so no request is answered with a redirect
/// to the slashed form it should have asked for in the first place.
#[test]
fn every_pretty_url_ends_in_a_slash() {
    for md in [
        "article.md",
        "guide/setup.md",
        "a/b/c/deep.md",
        "guide/index.md",
    ] {
        let url = routed(md, true).1;

        assert!(url.ends_with('/'), "{md} routed to {url}, which would 301");
    }
}

#[test]
fn a_pretty_url_never_doubles_its_slash() {
    for md in ["index.md", "guide/index.md", "guide/setup.md"] {
        let url = routed(md, true).1;

        assert!(!url.contains("//"), "{md} routed to {url}");
    }
}

#[test]
fn a_relative_link_prefix_survives_routing() {
    assert_eq!(route_link("../guide/setup", true), "../guide/setup/");
    assert_eq!(route_link("../guide/setup", false), "../guide/setup.html");
}

#[test]
fn a_link_and_a_page_agree_on_the_url_they_name() {
    // The rewritten link in one page must land on the URL another page is served at,
    // or internal navigation breaks in exactly the way this module exists to prevent.
    for pretty_urls in [false, true] {
        let page = route(Path::new("guide/setup.md"), pretty_urls);
        let link = route_link("guide/setup", pretty_urls);

        assert_eq!(page.url_relative, link, "pretty_urls = {pretty_urls}");
    }
}