1
use pretty_assertions::assert_eq;
2
use std::borrow::Cow;
3
use std::env;
4
use std::error::Error;
5
use std::fs;
6
use std::path::PathBuf;
7
use std::process::Command;
8

            
9
24
pub fn custom_test(test_dir: &str) -> Result<(), Box<dyn Error>> {
10
24
    let accept = env::var("ACCEPT").unwrap_or("false".to_string()) == "true";
11

            
12
    // Convert test directory to a PathBuf
13
24
    let test_path = PathBuf::from(test_dir);
14
24
    assert!(
15
24
        test_path.exists(),
16
        "Test directory not found: {test_path:?}"
17
    );
18

            
19
    // Get paths
20
24
    let script_path = test_path.join("run.sh");
21
24
    assert!(
22
24
        script_path.exists(),
23
        "Test script not found: {script_path:?}"
24
    );
25
24
    let expected_output_path = test_path.join("stdout.expected");
26
24
    let expected_error_path = test_path.join("stderr.expected");
27

            
28
    // Get conjure-oxide binary path from test binary path:
29
    // The test binary is at target/XX/deps/TESTPROGNAME and conjure_oxide is at target/XX/conjure-oxide
30
    // so from test binary, need to go up two directories and add 'conjure-oxide'
31
24
    let mut conjure_prefix = env::current_exe().unwrap();
32
24
    conjure_prefix.pop();
33
24
    conjure_prefix.pop();
34

            
35
24
    let mut path_var = env::var("PATH").unwrap_or_else(|_| "".to_string());
36
24
    let conjure_dir = conjure_prefix.display();
37
24
    path_var = format!("{conjure_dir}:{path_var}");
38

            
39
    // Execute the test script in the correct directory
40
24
    let output = Command::new("sh")
41
24
        .arg("run.sh")
42
24
        .current_dir(test_path)
43
24
        .env("PATH", path_var)
44
24
        .output()?;
45

            
46
    // Convert captured output/error to string
47
24
    let actual_output = String::from_utf8_lossy(&output.stdout);
48
24
    let actual_error = String::from_utf8_lossy(&output.stderr);
49

            
50
24
    if accept {
51
        // Overwrite expected files
52
        update_file(expected_output_path, actual_output)?;
53
        update_file(expected_error_path, actual_error)?;
54
    } else {
55
        // Compare results
56
24
        let expected_output = if expected_output_path.exists() {
57
18
            fs::read_to_string(&expected_output_path)?
58
        } else {
59
6
            String::new()
60
        };
61
24
        let expected_error = if expected_error_path.exists() {
62
21
            fs::read_to_string(&expected_error_path)?
63
        } else {
64
3
            String::new()
65
        };
66

            
67
24
        assert_eq!(expected_error, actual_error, "Standard error mismatch");
68
24
        assert_eq!(expected_output, actual_output, "Standard output mismatch");
69
    }
70

            
71
24
    Ok(())
72
24
}
73

            
74
fn update_file(
75
    expected_file_path: PathBuf,
76
    actual_output: Cow<'_, str>,
77
) -> Result<(), Box<dyn Error>> {
78
    if expected_file_path.exists() {
79
        fs::remove_file(&expected_file_path)?;
80
    }
81
    if !actual_output.trim().is_empty() {
82
        fs::File::create(&expected_file_path)?;
83
        fs::write(&expected_file_path, actual_output.as_bytes())?;
84
    }
85
    Ok(())
86
}
87

            
88
#[test]
89
3
fn assert_conjure_present() {
90
3
    conjure_cp_cli::find_conjure::conjure_executable().unwrap();
91
3
}
92

            
93
include!(concat!(env!("OUT_DIR"), "/gen_tests_custom.rs"));