File size: 3,762 Bytes
f14b4e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#[cfg(test)]
mod tests {
    use std::fs;
    use std::path::Path;

    use firm_lang::parser::dsl::parse_source;

    #[test]
    fn test_all_example_files_parse_without_errors() {
        let examples_dir = Path::new("examples");

        if !examples_dir.exists() {
            return;
        }

        let mut tested_files = 0;

        for entry in fs::read_dir(examples_dir).expect("Failed to read examples directory") {
            let entry = entry.expect("Failed to read directory entry");
            let path = entry.path();

            if path.extension().and_then(|s| s.to_str()) == Some("firm") {
                let filename = path.file_name().unwrap().to_str().unwrap();

                let source =
                    fs::read_to_string(&path).expect(&format!("Failed to read file: {}", filename));

                let parsed = parse_source(source, None)
                    .expect(&format!("Failed to parse file: {}", filename));

                assert!(
                    !parsed.has_error(),
                    "Example file {} should not have parse errors",
                    filename
                );
                tested_files += 1;
            }
        }

        assert!(
            tested_files > 0,
            "No .firm files found in examples directory"
        );
    }

    #[test]
    fn test_mixed_entities_and_schemas() {
        let source = r#"
            schema project {
                field {
                    name = "title"
                    type = "string"
                    required = true
                }
            }

            contact john_doe {
                name = "John Doe"
                email = "john@example.com"
            }

            schema invoice {
                field {
                    name = "amount"
                    type = "currency"
                    required = true
                }
            }

            role manager {
                name = "Manager"
                level = 5
            }
        "#;

        let parsed = parse_source(String::from(source), None).unwrap();
        assert!(!parsed.has_error());

        let entities = parsed.entities();
        let schemas = parsed.schemas();

        assert_eq!(entities.len(), 2);
        assert_eq!(schemas.len(), 2);

        // Verify entities
        let entity_types: Vec<_> = entities.iter().map(|e| e.entity_type().unwrap()).collect();
        assert!(entity_types.contains(&"contact"));
        assert!(entity_types.contains(&"role"));

        // Verify schemas
        let schema_names: Vec<_> = schemas.iter().map(|s| s.name().unwrap()).collect();
        assert!(schema_names.contains(&"project"));
        assert!(schema_names.contains(&"invoice"));
    }

    #[test]
    fn test_empty_source() {
        let source = "";
        let parsed = parse_source(String::from(source), None).unwrap();
        assert!(!parsed.has_error());
        assert_eq!(parsed.entities().len(), 0);
        assert_eq!(parsed.schemas().len(), 0);
    }

    #[test]
    fn test_comments_only_source() {
        let source = r#"
            // This is a comment
            /* This is a
               multi-line comment */
            // Another comment
        "#;

        let parsed = parse_source(String::from(source), None).unwrap();
        assert!(!parsed.has_error());
        assert_eq!(parsed.entities().len(), 0);
        assert_eq!(parsed.schemas().len(), 0);
    }

    #[test]
    fn test_syntax_error_detection() {
        let source = r#"
            contact john_doe {
                name = "John Doe"
                // Missing closing brace
        "#;

        let parsed = parse_source(String::from(source), None).unwrap();
        assert!(parsed.has_error());
    }
}