1
use std::collections::BTreeSet;
2
use std::path::Path;
3

            
4
/// Returns whether a file name represents an expected golden artifact.
5
37101
fn is_expected_golden_file(file_name: &str) -> bool {
6
37101
    file_name.contains(".expected") || file_name.contains("-expected-")
7
37101
}
8

            
9
/// Lists expected snapshot files in `path` that are not present in `allowed_expected_files`.
10
1305
pub fn find_redundant_expected_files(
11
1305
    path: &Path,
12
1305
    allowed_expected_files: &BTreeSet<String>,
13
1305
) -> Result<Vec<String>, std::io::Error> {
14
1305
    let mut redundant = Vec::new();
15

            
16
37104
    for entry in std::fs::read_dir(path)? {
17
37104
        let entry = entry?;
18
37104
        if !entry.path().is_file() {
19
3
            continue;
20
37101
        }
21

            
22
37101
        let file_name = entry.file_name();
23
37101
        let file_name = file_name.to_string_lossy().to_string();
24

            
25
37101
        if is_expected_golden_file(&file_name) && !allowed_expected_files.contains(&file_name) {
26
            redundant.push(file_name);
27
37101
        }
28
    }
29

            
30
1305
    redundant.sort();
31
1305
    Ok(redundant)
32
1305
}
33

            
34
/// Builds a standardised error describing redundant golden files for a test directory.
35
pub fn redundant_golden_files_error(
36
    path: &Path,
37
    redundant_files: Vec<String>,
38
    context: Option<&str>,
39
) -> std::io::Error {
40
    let file_list = redundant_files
41
        .into_iter()
42
        .map(|file| format!("  - {file}"))
43
        .collect::<Vec<_>>()
44
        .join("\n");
45

            
46
    let context = context.map_or(String::new(), |context| format!(" {context}"));
47

            
48
    std::io::Error::other(format!(
49
        "Redundant golden files detected in {}{context}:\n{file_list}\nRun with ACCEPT=true to refresh snapshots.",
50
        path.display()
51
    ))
52
}
53

            
54
/// Fails when `path` contains any expected snapshot file not listed in `allowed_expected_files`.
55
1305
pub fn assert_no_redundant_expected_files(
56
1305
    path: &Path,
57
1305
    allowed_expected_files: &BTreeSet<String>,
58
1305
    context: Option<&str>,
59
1305
) -> Result<(), std::io::Error> {
60
1305
    let redundant = find_redundant_expected_files(path, allowed_expected_files)?;
61
1305
    if redundant.is_empty() {
62
1305
        return Ok(());
63
    }
64

            
65
    Err(redundant_golden_files_error(path, redundant, context))
66
1305
}