#[test]
fn test_PERFORMANCE_007_detect_expensive_wildcard() {
let makefile = r#"
clean:
rm -f *.o
rm -f *.a
rm -f *.so
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result
.report
.iter()
.any(|r| r.contains("combine") || r.contains("rm") || r.contains("performance")),
"Should suggest combining rm commands for better performance"
);
}
#[test]
fn test_PERFORMANCE_008_detect_simple_expansion_already_used() {
let makefile = r#"
CC := gcc
CFLAGS := -Wall -O2
build:
$(CC) $(CFLAGS) main.c -o app
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
let _ = result.transformations_applied; }
#[test]
fn test_PERFORMANCE_009_detect_pattern_rule_efficiency() {
let makefile = r#"
main.o: main.c
gcc -c main.c -o main.o
util.o: util.c
gcc -c util.c -o util.o
math.o: math.c
gcc -c math.c -o math.o
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result
.report
.iter()
.any(|r| r.contains("pattern") || r.contains("%.o") || r.contains("rule")),
"Should suggest using pattern rule for repeated compilation"
);
}
#[test]
fn test_PERFORMANCE_010_comprehensive_performance_check() {
let makefile = r#"
VERSION = $(shell git describe --tags)
CC = gcc
CFLAGS = -Wall -O2
all: app
app: main.o util.o
gcc main.o util.o -o app
main.o: main.c
mkdir -p obj
gcc -c main.c -o main.o
cp main.o obj/
util.o: util.c
mkdir -p obj
gcc -c util.c -o util.o
cp util.o obj/
clean:
rm -f *.o
rm -f *.a
rm -f app
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result.transformations_applied >= 2,
"Should detect multiple performance issues (shell expansion, multiple commands, etc.)"
);
}
#[test]
fn test_ERROR_HANDLING_001_detect_missing_error_handling() {
let makefile = r#"
build:
mkdir build
gcc -c main.c -o build/main.o
gcc build/main.o -o build/app
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result
.report
.iter()
.any(|r| r.contains("error") || r.contains("exit") || r.contains("handling")),
"Should recommend adding error handling (|| exit 1) for critical commands"
);
}
#[test]
fn test_ERROR_HANDLING_002_detect_silent_failures() {
let makefile = r#"
test:
@echo "Running tests..."
@./run-tests.sh
@echo "Tests complete"
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result
.report
.iter()
.any(|r| r.contains("@") || r.contains("silent") || r.contains("error")),
"Should detect @ prefix that may hide errors in critical commands"
);
}
#[test]
fn test_ERROR_HANDLING_003_recommend_delete_on_error() {
let makefile = r#"
build:
mkdir build
gcc -c main.c -o build/main.o
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result.report.iter().any(|r| r.contains(".DELETE_ON_ERROR")),
"Should recommend .DELETE_ON_ERROR when error handling issues are detected"
);
}
#[test]
fn test_ERROR_HANDLING_004_preserve_existing_delete_on_error() {
let makefile = r#"
.DELETE_ON_ERROR:
%.o: %.c
gcc -c $< -o $@
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
let _ = result.transformations_applied; }
#[test]
fn test_ERROR_HANDLING_005_detect_unchecked_command_substitution() {
let makefile = r#"
VERSION := $(shell git describe --tags)
build:
echo "Building version $(VERSION)"
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
let _ = result.transformations_applied; }
#[test]
fn test_ERROR_HANDLING_006_detect_missing_oneshell() {
let makefile = r#"
deploy:
cd /tmp
mkdir app
echo "Done"
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result
.report
.iter()
.any(|r| r.contains(".ONESHELL") || r.contains("multiline") || r.contains("shell")),
"Should recommend .ONESHELL or && for related commands across lines"
);
}
#[test]
fn test_ERROR_HANDLING_007_detect_unchecked_state_modification() {
let makefile = r#"
clean:
rm -rf build/*
rm -rf dist/*
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
let _ = result.transformations_applied; }
#[test]
fn test_ERROR_HANDLING_008_detect_missing_set_e() {
let makefile = r#"
test:
bash -c "echo test1; false; echo test2"
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result
.report
.iter()
.any(|r| r.contains("set -e") || r.contains("error") || r.contains("exit")),
"Should recommend 'set -e' for inline shell scripts"
);
}
#[test]
fn test_ERROR_HANDLING_009_detect_missing_error_handling_in_loops() {
let makefile = r#"
install:
for f in *.so; do cp $$f /usr/lib; done
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result
.report
.iter()
.any(|r| r.contains("loop") || r.contains("error") || r.contains("exit")),
"Should recommend error handling in for loops (|| exit 1)"
);
}
#[test]
fn test_ERROR_HANDLING_010_comprehensive_error_handling_check() {
let makefile = r#"
VERSION := $(shell git describe)
build:
@mkdir build
gcc -c main.c -o build/main.o
for f in *.c; do gcc -c $$f; done
bash -c "echo done"
"#;
let ast = crate::make_parser::parser::parse_makefile(makefile).unwrap();
let result = purify_makefile(&ast);
assert!(
result.transformations_applied >= 1,
"Should detect multiple error handling issues (@ prefix, missing ||, loops, etc.)"
);
}
#[test]
include!("tests_tests_PORTABILITY.rs");