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

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

            
19
    // Get paths
20
    let script_path = test_path.join("run.sh");
21
    assert!(
22
        script_path.exists(),
23
        "Test script not found: {script_path:?}"
24
    );
25
    let expected_output_path = test_path.join("stdout.expected");
26
    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
    let mut conjure_prefix = env::current_exe().unwrap();
32
    conjure_prefix.pop();
33
    conjure_prefix.pop();
34

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

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

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

            
50
    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
        let expected_output = if expected_output_path.exists() {
57
            fs::read_to_string(&expected_output_path)?
58
        } else {
59
            String::new()
60
        };
61
        let expected_error = if expected_error_path.exists() {
62
            fs::read_to_string(&expected_error_path)?
63
        } else {
64
            String::new()
65
        };
66

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

            
71
    Ok(())
72
}
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
fn assert_conjure_present() {
90
    conjure_cp_cli::find_conjure::conjure_executable().unwrap();
91
}
92

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