fsvalidator 0.3.0

A file structure validator
Documentation
use fsvalidator::model::{DirNode, FileNode, NodeName};
use fsvalidator::display::SYMBOLS;

#[test]
fn test_display_file_node() {
    // Create a file node
    let file_node = FileNode::new(NodeName::Literal("test.txt".to_string()), true);

    // Convert to string
    let output = format!("{}", file_node);

    // Check output - ignoring ANSI colors
    assert!(output.contains(SYMBOLS.file));
    assert!(output.contains("test.txt"));
    assert!(output.contains(SYMBOLS.required));
}

#[test]
fn test_display_dir_node() {
    // Create a directory node
    let dir_node = DirNode::new(
        NodeName::Literal("test_dir".to_string()),
        vec![],
        true,
        false,
        vec![],
    );

    // Convert to string
    let output = format!("{}", dir_node);

    // Check output - ignoring ANSI colors
    assert!(output.contains(SYMBOLS.directory));
    assert!(output.contains("test_dir"));
    assert!(output.contains(SYMBOLS.required));
    // No "restrict: yes" since allow_defined_only is false
    assert!(!output.contains("restrict: yes"));
}

#[test]
fn test_display_node_with_children() {
    // Create a file node
    let file_node = FileNode::new(NodeName::Literal("child.txt".to_string()), false);

    // Create a directory node with the file as a child
    let dir_node = DirNode::new(
        NodeName::Literal("parent".to_string()),
        vec![file_node],
        true,
        true,
        vec![],
    );

    // Convert to string
    let output = format!("{}", dir_node);

    // Check output - ignoring ANSI colors
    assert!(output.contains(SYMBOLS.directory));
    assert!(output.contains("parent"));
    assert!(output.contains("restrict: yes"));
    assert!(output.contains(SYMBOLS.file));
    assert!(output.contains("child.txt"));
    assert!(output.contains(SYMBOLS.optional));
}

#[test]
fn test_display_pattern_node() {
    // Create nodes with patterns
    let file_node = FileNode::new(NodeName::Pattern(".*\\.txt".to_string()), true);
    let dir_node = DirNode::new(
        NodeName::Pattern("test_\\d+".to_string()),
        vec![],
        false,
        false,
        vec![],
    );

    // Convert to strings
    let file_output = format!("{}", file_node);
    let dir_output = format!("{}", dir_node);

    // Check outputs - ignoring ANSI colors
    assert!(file_output.contains(SYMBOLS.file));
    assert!(file_output.contains("Pattern(.*\\.txt)"));
    assert!(dir_output.contains(SYMBOLS.directory));
    assert!(dir_output.contains("Pattern(test_\\d+)"));
}

#[test]
fn test_display_deep_nested_structure() {
    // Create a deep nested structure to test MAX_DEPTH handling
    let mut current = None;

    // Create 15 levels of nesting (beyond MAX_DEPTH)
    for i in (0..15).rev() {
        // Build from deepest to top level
        let name = format!("level_{}", i);
        let children = match current {
            Some(node) => vec![node],
            None => vec![],
        };

        current = Some(DirNode::new(
            NodeName::Literal(name),
            children,
            true,
            false,
            vec![],
        ));
    }

    if let Some(root) = current {
        // Convert to string
        let output = format!("{}", root);

        // Should contain truncation indicator
        assert!(output.contains("..."));
        assert!(output.contains("more items"));

        // Should contain first several levels
        assert!(output.contains("level_0"));
        assert!(output.contains("level_1"));
    } else {
        panic!("Failed to create test structure");
    }
}