1
use std::collections::HashSet;
2
use std::error::Error;
3

            
4
use glob::glob;
5

            
6
/// Discovers test files with specific extensions and prints test cases for them
7
pub(crate) fn discover_tests() -> Result<(), Box<dyn Error>> {
8
    // Discover different types of test files
9
    discover_files_with_extension("mcrl2", "examples/mCRL2/**/*.mcrl2")?;
10
    discover_files_with_extension("mcf", "examples/mCRL2/**/*.mcf")?;
11
    discover_files_with_extension("dataspec", "examples/REC/**/*.dataspec")?;
12

            
13
    Ok(())
14
}
15

            
16
/// Discovers files matching a pattern and prints a `#[test_case]` annotation for each unique
17
/// filename. Errors if the pattern matches no files, since that usually indicates a typo.
18
fn discover_files_with_extension(ext_name: &str, pattern: &str) -> Result<(), Box<dyn Error>> {
19
    // Track seen filenames to avoid duplicates
20
    let mut seen_filenames = HashSet::new();
21

            
22
    for path_result in glob(pattern)? {
23
        let path = path_result?;
24

            
25
        // Normalize path separators to forward slashes for cross-platform compatibility.
26
        let normalized_path = path.to_string_lossy().replace('\\', "/");
27
        let filename = path.file_name().unwrap_or_default().to_string_lossy();
28

            
29
        // Replace spaces with underscores and convert to lowercase for consistent test naming.
30
        let sanitized_filename = filename.replace(' ', "_").to_lowercase();
31

            
32
        // Only generate a test case if this filename hasn't been seen before.
33
        if seen_filenames.insert(sanitized_filename.clone()) {
34
            println!(
35
                "#[test_case(include_str!(\"../../../{normalized_path}\"), \"tests/snapshot/result_{sanitized_filename}\" ; \"{sanitized_filename}\")]"
36
            );
37
        }
38
    }
39

            
40
    if seen_filenames.is_empty() {
41
        return Err(format!("No {ext_name} test files were discovered for pattern '{pattern}'").into());
42
    }
43

            
44
    Ok(())
45
}