use std::env::{current_dir, set_current_dir, set_var, temp_dir};
use std::fs;
use std::path;
use std::sync::{Mutex, MutexGuard};
use super::*;
static API_TEST_MUTEX: Mutex<i32> = Mutex::new(0);
const TEST_DIR: &str = "lalrpop-test";
const CUSTOM_TEST_DIR: &str = "lalrpop-test2";
#[derive(Debug, PartialEq)]
enum GenFileLoc {
Src,
Other,
Root,
OutDir,
OutDirSlashOther,
CustomOut,
DoesntExist,
}
struct TestState {
orig_dir: path::PathBuf,
lock: MutexGuard<'static, i32>,
}
impl TestState {
fn new(orig_dir: path::PathBuf, lock: MutexGuard<'static, i32>) -> Self {
TestState { orig_dir, lock }
}
}
impl Drop for TestState {
fn drop(&mut self) {
remove_local_generated_files();
set_current_dir(&self.orig_dir).unwrap();
let out_dir = temp_dir().join(TEST_DIR);
fs::remove_dir_all(out_dir).unwrap();
}
}
fn setup() -> TestState {
let out_dir = temp_dir().join(TEST_DIR);
let lock = API_TEST_MUTEX.lock().unwrap_or_else(|e| {
if fs::exists(&out_dir).unwrap() {
panic!("This test was started in an unclean state because another test failed but didn't manage to clean up test state");
}
API_TEST_MUTEX.clear_poison();
e.into_inner()
});
let orig_dir = current_dir().unwrap();
set_current_dir(path::Path::new("./src/api/test_files")).unwrap();
if fs::exists(&out_dir).unwrap() {
fs::remove_dir_all(&out_dir).unwrap();
}
remove_local_generated_files();
fs::create_dir(&out_dir).unwrap();
unsafe {
set_var("OUT_DIR", out_dir);
}
TestState::new(orig_dir, lock)
}
fn remove_local_generated_files() {
for f in ["src.rs", "other.rs", "outer.rs"] {
for loc in [".", "src", "other"] {
let file_path = path::Path::new(loc).join(f);
if fs::exists(&file_path).unwrap() {
fs::remove_file(file_path).unwrap();
}
}
}
let custom_dir = temp_dir().join(CUSTOM_TEST_DIR);
if fs::exists(&custom_dir).unwrap() {
fs::remove_dir_all(&custom_dir).unwrap();
}
}
fn verify_file(filename: &str, expected_location: GenFileLoc) {
println!("Checking the location of {filename}");
assert_eq!(
fs::exists(path::Path::new("src").join(filename)).unwrap(),
expected_location == GenFileLoc::Src
);
assert_eq!(
fs::exists(path::Path::new("other").join(filename)).unwrap(),
expected_location == GenFileLoc::Other
);
assert_eq!(
fs::exists(filename).unwrap(),
expected_location == GenFileLoc::Root
);
if fs::exists(temp_dir().join(CUSTOM_TEST_DIR)).unwrap() {
assert_eq!(
fs::exists(temp_dir().join(CUSTOM_TEST_DIR).join(filename)).unwrap(),
expected_location == GenFileLoc::CustomOut
)
}
assert_eq!(
fs::exists(temp_dir().join(TEST_DIR).join(filename)).unwrap(),
expected_location == GenFileLoc::OutDir
);
assert_eq!(
fs::exists(
temp_dir()
.join(TEST_DIR)
.join(path::Path::new("other"))
.join(filename)
)
.unwrap(),
expected_location == GenFileLoc::OutDirSlashOther
);
}
#[test]
fn test_process_root() {
let _state = setup();
process_root().unwrap();
verify_file("src.rs", GenFileLoc::OutDir);
verify_file("other.rs", GenFileLoc::OutDirSlashOther);
verify_file("outer.rs", GenFileLoc::OutDir);
}
#[test]
fn test_process_src() {
let _state = setup();
process_src().unwrap();
verify_file("src.rs", GenFileLoc::OutDir);
verify_file("other.rs", GenFileLoc::DoesntExist);
verify_file("outer.rs", GenFileLoc::DoesntExist);
}
#[test]
fn test_process_file() {
let _state = setup();
Configuration::new()
.use_cargo_dir_conventions()
.process_file("../test_files/src/src.lalrpop")
.unwrap_err();
verify_file("src.rs", GenFileLoc::DoesntExist);
verify_file("other.rs", GenFileLoc::DoesntExist);
verify_file("outer.rs", GenFileLoc::DoesntExist);
}
#[test]
fn test_explicit_in_out() {
let _state = setup();
let custom_dir = temp_dir().join(CUSTOM_TEST_DIR);
fs::create_dir(&custom_dir).unwrap();
Configuration::new()
.set_in_dir("other")
.set_out_dir(custom_dir.to_str().unwrap())
.process()
.unwrap();
verify_file("src.rs", GenFileLoc::DoesntExist);
verify_file("other.rs", GenFileLoc::CustomOut);
verify_file("outer.rs", GenFileLoc::DoesntExist);
fs::remove_dir_all(&custom_dir).unwrap();
}
#[test]
fn test_cargo_dir_conventions() {
let _state = setup();
Configuration::new()
.use_cargo_dir_conventions()
.process()
.unwrap();
verify_file("src.rs", GenFileLoc::OutDir);
verify_file("other.rs", GenFileLoc::DoesntExist);
verify_file("outer.rs", GenFileLoc::DoesntExist);
}