[Lore] Root层的最简实现与测试

26 阅读1分钟

预导入

use super::line::parse_line;
use super::line::Line;

每个 Root 包含若干 Line

pub struct Root<'f> {
    data: Vec<Line<'f>>,
}

借助 parse_line ,简洁地实现格式识别。

pub fn parse_root(raw_lines: Vec<&str>) -> Root<'_> {
    let data = raw_lines
        .into_iter()
        .map(parse_line)
        .collect();

    Root { data }
}

Root 实现 Display 以便测试。

impl<'f> std::fmt::Display for Root<'f> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        for line in &self.data {
            writeln!(f, "{}", line)?;
        }
        Ok(())
    }
}

测试模块如此。测试结果与预期一致。

#[cfg(test)]
mod tests {
    use super::super::content::Content;
    use super::*;

    #[test]
    fn test_parse_root_empty() {
        let root = parse_root(vec![]);
        assert_eq!(root.data.len(), 0);
    }

    #[test]
    fn test_parse_root_single_line() {
        let root = parse_root(vec!["simple line"]);
        assert_eq!(root.data.len(), 1);

        if let Content::Element(text) = &root.data[0].content {
            assert_eq!(*text, "simple line");
        } else {
            panic!("Expected Element variant");
        }
        assert_eq!(root.data[0].indent, 0);
    }

    #[test]
    fn test_parse_root_multiple_lines() {
        let lines = vec![
            "root element",
            "  indented element",
            "  + domain line",
            "    deeply nested",
        ];

        let root = parse_root(lines);
        assert_eq!(root.data.len(), 4);

        // 检查第一行
        assert!(matches!(root.data[0].content, Content::Element("root element")));
        assert_eq!(root.data[0].indent, 0);

        // 检查第二行
        assert!(matches!(root.data[1].content, Content::Element("indented element")));
        assert_eq!(root.data[1].indent, 1);

        // 检查第三行
        assert!(matches!(root.data[2].content, Content::Domain("domain line")));
        assert_eq!(root.data[2].indent, 1);

        // 检查第四行
        assert!(matches!(root.data[3].content, Content::Element("deeply nested")));
        assert_eq!(root.data[3].indent, 2);
    }

    #[test]
    fn test_parse_root_mixed_content() {
        let lines = vec![
            "+ domain at root",
            "normal element",
            "  + indented domain",
            "    normal indented",
        ];

        let root = parse_root(lines);
        assert_eq!(root.data.len(), 4);

        assert!(matches!(root.data[0].content, Content::Domain("domain at root")));
        assert!(matches!(root.data[1].content, Content::Element("normal element")));
        assert!(matches!(root.data[2].content, Content::Domain("indented domain")));
        assert!(matches!(root.data[3].content, Content::Element("normal indented")));
    }

    #[test]
    fn test_parse_root_with_empty_lines() {
        let lines = vec![
            "first line",
            "",
            "  indented line",
            "    ",
        ];

        let root = parse_root(lines);
        assert_eq!(root.data.len(), 4);

        // 空行应该被解析为 Element("")
        assert!(matches!(root.data[1].content, Content::Element("")));
        assert_eq!(root.data[1].indent, 0);

        // 只有空格的行
        assert!(matches!(root.data[3].content, Content::Element("")));
        assert_eq!(root.data[3].indent, 2);
    }

    #[test]
    fn test_root_display() {
        let lines = vec![
            "root",
            "  + domain",
            "    nested",
        ];

        let root = parse_root(lines);
        let output = format!("{}", root);
        let expected = "root\n  + domain\n    nested\n";

        assert_eq!(output, expected);
    }
}