#![allow(clippy::unwrap_used)]
#![allow(clippy::expect_used)]
#![allow(unused_imports)]
use super::super::*;
use crate::make_parser::ast::{MakeCondition, Span, VarFlavor};
#[test]
fn test_VAR_FLAVOR_001_mut_equals_detection() {
let makefile = "CC = gcc";
let result = parse_makefile(makefile);
assert!(result.is_ok(), "Must parse = as variable assignment");
let ast = result.unwrap();
assert_eq!(ast.items.len(), 1, "Must have exactly one item");
match &ast.items[0] {
MakeItem::Variable { name, flavor, .. } => {
assert_eq!(name, "CC");
assert_eq!(*flavor, VarFlavor::Recursive, "Must be Recursive flavor");
}
_ => panic!("Must be parsed as Variable, not other type"),
}
}
#[test]
fn test_VAR_FLAVOR_001_mut_operator_slicing() {
let makefile = "CFLAGS = -Wall -O2";
let result = parse_makefile(makefile);
assert!(result.is_ok());
let ast = result.unwrap();
match &ast.items[0] {
MakeItem::Variable { name, value, .. } => {
assert_eq!(name, "CFLAGS", "Name must be before =");
assert_eq!(value, "-Wall -O2", "Value must be after =");
assert!(!name.contains('='), "Name must not contain =");
assert!(!value.starts_with('='), "Value must not start with =");
}
_ => panic!("Expected Variable"),
}
}
#[test]
fn test_VAR_FLAVOR_001_mut_recursive_not_missed() {
let makefile = "VAR = value";
let result = parse_makefile(makefile);
assert!(result.is_ok(), "Must parse = assignment");
let ast = result.unwrap();
assert_eq!(ast.items.len(), 1, "Must parse one variable, not skip");
match &ast.items[0] {
MakeItem::Variable {
name,
value,
flavor,
..
} => {
assert_eq!(name, "VAR");
assert_eq!(value, "value");
assert_eq!(*flavor, VarFlavor::Recursive);
}
_ => panic!("Must parse as Variable"),
}
}
#[test]
fn test_VAR_FLAVOR_001_mut_not_confused_with_colon() {
let variable = "VAR = value";
let target = "target: prereq";
let var_result = parse_makefile(variable);
let target_result = parse_makefile(target);
assert!(var_result.is_ok());
assert!(target_result.is_ok());
let var_ast = var_result.unwrap();
let target_ast = target_result.unwrap();
match &var_ast.items[0] {
MakeItem::Variable { flavor, .. } => {
assert_eq!(*flavor, VarFlavor::Recursive);
}
MakeItem::Target { .. } => panic!("VAR = value must be Variable, not Target"),
_ => panic!("Unexpected item type"),
}
match &target_ast.items[0] {
MakeItem::Target { .. } => {
}
MakeItem::Variable { .. } => panic!("target: must be Target, not Variable"),
_ => panic!("Unexpected item type"),
}
}
#[test]
fn test_VAR_FLAVOR_001_mut_correct_flavor_enum_variant() {
let makefile = "TARGET = value";
let result = parse_makefile(makefile);
assert!(result.is_ok());
let ast = result.unwrap();
match &ast.items[0] {
MakeItem::Variable { flavor, .. } => {
assert!(
matches!(flavor, VarFlavor::Recursive),
"Must be VarFlavor::Recursive"
);
assert!(!matches!(flavor, VarFlavor::Simple), "Must NOT be Simple");
assert!(
!matches!(flavor, VarFlavor::Conditional),
"Must NOT be Conditional"
);
assert!(!matches!(flavor, VarFlavor::Append), "Must NOT be Append");
assert!(!matches!(flavor, VarFlavor::Shell), "Must NOT be Shell");
}
_ => panic!("Expected Variable"),
}
}
#[test]
fn test_SYNTAX_002_basic_line_continuation_in_variable() {
let makefile = "FILES = file1.c \\\n file2.c";
let result = parse_makefile(makefile);
assert!(result.is_ok(), "Parser should handle line continuation");
let ast = result.unwrap();
assert_eq!(ast.items.len(), 1, "Should parse one variable");
match &ast.items[0] {
MakeItem::Variable { name, value, .. } => {
assert_eq!(name, "FILES", "Variable name should be FILES");
assert_eq!(
value, "file1.c file2.c",
"Value should concatenate continued lines"
);
}
other => panic!("Expected Variable, got {:?}", other),
}
}
#[test]
fn test_SYNTAX_002_multiple_line_continuations() {
let makefile = "SOURCES = a.c \\\n b.c \\\n c.c";
let result = parse_makefile(makefile);
assert!(
result.is_ok(),
"Parser should handle multiple continuations"
);
let ast = result.unwrap();
assert_eq!(ast.items.len(), 1, "Should parse one variable");
match &ast.items[0] {
MakeItem::Variable { name, value, .. } => {
assert_eq!(name, "SOURCES", "Variable name should be SOURCES");
assert_eq!(
value, "a.c b.c c.c",
"Value should concatenate all continued lines"
);
}
other => panic!("Expected Variable, got {:?}", other),
}
}
#[test]
fn test_SYNTAX_002_line_continuation_preserves_order() {
let makefile = "ITEMS = first \\\n second \\\n third";
let result = parse_makefile(makefile);
assert!(result.is_ok());
let ast = result.unwrap();
match &ast.items[0] {
MakeItem::Variable { value, .. } => {
assert_eq!(
value, "first second third",
"Order should be preserved in continuation"
);
}
_ => panic!("Expected Variable"),
}
}
#[test]
fn test_SYNTAX_002_continuation_vs_no_continuation() {
let with_continuation = "VAR = a \\\n b";
let without_continuation = "VAR = a b";
let result1 = parse_makefile(with_continuation);
let result2 = parse_makefile(without_continuation);
assert!(result1.is_ok());
assert!(result2.is_ok());
let ast1 = result1.unwrap();
let ast2 = result2.unwrap();
match (&ast1.items[0], &ast2.items[0]) {
(MakeItem::Variable { value: v1, .. }, MakeItem::Variable { value: v2, .. }) => {
assert_eq!(
v1, v2,
"Continuation and non-continuation should be equivalent"
);
assert_eq!(v1, "a b");
}
_ => panic!("Expected Variables"),
}
}
#[cfg(test)]
#[path = "part2_tests_syntax_002.rs"]
mod tests_extracted;