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

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

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

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

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

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

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

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

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

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