use std::fs;
use tempfile::TempDir;
use crate::common::{setup_test_project, setup_cc_project, run_rsconstruct_with_env};
#[test]
fn rsconstructignore_excludes_tera_files() {
let temp_dir = setup_test_project();
let project_path = temp_dir.path();
fs::write(project_path.join("tera.templates/included.txt.tera"), "hello").unwrap();
fs::write(project_path.join("tera.templates/excluded.txt.tera"), "world").unwrap();
fs::write(
project_path.join(".rsconstructignore"),
"tera.templates/excluded.txt.tera\n"
).unwrap();
let output = run_rsconstruct_with_env(project_path, &["build", "-v"], &[("NO_COLOR", "1")]);
assert!(output.status.success(), "rsconstruct build failed: {}", String::from_utf8_lossy(&output.stderr));
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("included.txt"), "Included template should be processed");
assert!(!stdout.contains("excluded.txt"), "Excluded template should not be processed");
}
#[test]
fn rsconstructignore_glob_pattern() {
let temp_dir = setup_test_project();
let project_path = temp_dir.path();
fs::create_dir_all(project_path.join("tera.templates/subdir")).unwrap();
fs::write(project_path.join("tera.templates/keep.txt.tera"), "hello").unwrap();
fs::write(project_path.join("tera.templates/subdir/skip1.txt.tera"), "world1").unwrap();
fs::write(project_path.join("tera.templates/subdir/skip2.txt.tera"), "world2").unwrap();
fs::write(
project_path.join(".rsconstructignore"),
"# Exclude all files in subdir\ntera.templates/subdir/**\n"
).unwrap();
let output = run_rsconstruct_with_env(project_path, &["build", "-v"], &[("NO_COLOR", "1")]);
assert!(output.status.success(), "rsconstruct build failed: {}", String::from_utf8_lossy(&output.stderr));
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("keep.txt"), "keep.txt should be processed");
assert!(!stdout.contains("skip1.txt"), "subdir/skip1.txt should be excluded");
assert!(!stdout.contains("skip2.txt"), "subdir/skip2.txt should be excluded");
}
#[test]
fn rsconstructignore_no_file() {
let temp_dir = setup_test_project();
let project_path = temp_dir.path();
fs::write(project_path.join("tera.templates/normal.txt.tera"), "hello").unwrap();
let output = run_rsconstruct_with_env(project_path, &["build", "-v"], &[("NO_COLOR", "1")]);
assert!(output.status.success(), "rsconstruct build failed without .rsconstructignore: {}",
String::from_utf8_lossy(&output.stderr));
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("normal.txt"),
"Template should be processed when no .rsconstructignore exists: {}", stdout);
}
#[test]
fn rsconstructignore_comments_and_blank_lines() {
let temp_dir = setup_test_project();
let project_path = temp_dir.path();
fs::write(project_path.join("tera.templates/a.txt.tera"), "hello").unwrap();
fs::write(project_path.join("tera.templates/b.txt.tera"), "world").unwrap();
fs::write(
project_path.join(".rsconstructignore"),
"# This is a comment\n\n \n# Another comment\ntera.templates/b.txt.tera\n\n"
).unwrap();
let output = run_rsconstruct_with_env(project_path, &["build", "-v"], &[("NO_COLOR", "1")]);
assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("a.txt"), "a.txt should be processed");
assert!(!stdout.contains("b.txt"), "b.txt should be ignored");
}
#[test]
fn rsconstructignore_cc_processor() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let project_path = temp_dir.path();
setup_cc_project(project_path);
fs::write(
project_path.join("src/included.c"),
"int main() { return 0; }\n"
).unwrap();
fs::create_dir_all(project_path.join("src/excluded")).unwrap();
fs::write(
project_path.join("src/excluded/skip.c"),
"int main() { return 0; }\n"
).unwrap();
fs::write(
project_path.join(".rsconstructignore"),
"src/excluded/**\n"
).unwrap();
let output = run_rsconstruct_with_env(project_path, &["build"], &[("NO_COLOR", "1")]);
assert!(output.status.success(),
"Build failed: stdout={}, stderr={}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr));
assert!(project_path.join("out/cc_single_file/src/included.elf").exists(),
"included.c should be compiled");
assert!(!project_path.join("out/cc_single_file/src/excluded/skip.elf").exists(),
"excluded/skip.c should not be compiled");
}
#[test]
fn rsconstructignore_leading_slash() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let project_path = temp_dir.path();
setup_cc_project(project_path);
fs::write(
project_path.join("src/keep.c"),
"int main() { return 0; }\n"
).unwrap();
fs::create_dir_all(project_path.join("src/skip_dir")).unwrap();
fs::write(
project_path.join("src/skip_dir/skip.c"),
"int main() { return 0; }\n"
).unwrap();
fs::write(
project_path.join(".rsconstructignore"),
"/src/skip_dir/**\n"
).unwrap();
let output = run_rsconstruct_with_env(project_path, &["build"], &[("NO_COLOR", "1")]);
assert!(output.status.success(),
"Build failed: stdout={}, stderr={}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr));
assert!(project_path.join("out/cc_single_file/src/keep.elf").exists(),
"keep.c should be compiled");
assert!(!project_path.join("out/cc_single_file/src/skip_dir/skip.elf").exists(),
"skip_dir/skip.c should be excluded by /src/skip_dir/** pattern");
}
#[test]
fn rsconstructignore_trailing_slash() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let project_path = temp_dir.path();
setup_cc_project(project_path);
fs::write(
project_path.join("src/keep.c"),
"int main() { return 0; }\n"
).unwrap();
fs::create_dir_all(project_path.join("src/skipme")).unwrap();
fs::write(
project_path.join("src/skipme/deep.c"),
"int main() { return 0; }\n"
).unwrap();
fs::write(
project_path.join(".rsconstructignore"),
"/src/skipme/\n"
).unwrap();
let output = run_rsconstruct_with_env(project_path, &["build"], &[("NO_COLOR", "1")]);
assert!(output.status.success(),
"Build failed: stdout={}, stderr={}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr));
assert!(project_path.join("out/cc_single_file/src/keep.elf").exists(),
"keep.c should be compiled");
assert!(!project_path.join("out/cc_single_file/src/skipme/deep.elf").exists(),
"skipme/deep.c should be excluded by /src/skipme/ pattern");
}