mini-docs 0.5.0

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

struct MockProcessor;

impl MarkdownProcessor for MockProcessor {
    fn process(&self, body: &str, _frontmatter: &Value) -> Result<String, DocError> {
        Ok(format!("{}[PROCESSED]", body))
    }

    fn name(&self) -> &str {
        "mock"
    }
}

struct MockAnalyzer;

impl MarkdownAnalyzer for MockAnalyzer {
    fn analyze(&self, body: &str, _frontmatter: &Value) -> Result<Value, DocError> {
        Ok(serde_json::json!({
            "word_count": body.split_whitespace().count()
        }))
    }

    fn name(&self) -> &str {
        "mock_analyzer"
    }
}

#[test]
fn processor_trait_works() {
    let proc = MockProcessor;
    let body = "hello world";
    let fm = serde_json::json!({});
    let result = proc.process(body, &fm).unwrap();
    assert_eq!(result, "hello world[PROCESSED]");
    assert_eq!(proc.name(), "mock");
}

#[test]
fn analyzer_trait_works() {
    let analyzer = MockAnalyzer;
    let body = "one two three";
    let fm = serde_json::json!({});
    let result = analyzer.analyze(body, &fm).unwrap();
    assert_eq!(result["word_count"], 3);
    assert_eq!(analyzer.name(), "mock_analyzer");
}

#[test]
fn validate_identifier_accepts_valid_names() {
    assert!(validate_identifier("simple"));
    assert!(validate_identifier("snake_case"));
    assert!(validate_identifier("with123numbers"));
    assert!(validate_identifier("a"));
    assert!(validate_identifier("_underscore_start"));
}

#[test]
fn validate_identifier_rejects_invalid_names() {
    assert!(!validate_identifier(""));
    assert!(!validate_identifier("with space"));
    assert!(!validate_identifier("with-dash"));
    assert!(!validate_identifier("WithCaps"));
    assert!(!validate_identifier("with.dot"));
}