#[cfg(feature = "boolean_ops")]
mod boolean_ops_tests {
use insign::compile;
#[test]
fn test_difference_operation_simple() {
let units = vec![
([0, 0, 0], "@base=rc([0,0,0],[4,4,4])".to_string()),
([0, 0, 0], "@hole=rc([1,1,1],[3,3,3])".to_string()),
([0, 0, 0], "@result=base-hole".to_string()),
];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result"));
let result_region = &dsl_map["result"];
let boxes = result_region.bounding_boxes.as_ref().unwrap();
assert!(!boxes.is_empty());
assert!(boxes.len() > 1);
}
#[test]
fn test_intersection_operation_simple() {
let units = vec![
([0, 0, 0], "@box1=rc([0,0,0],[4,4,4])".to_string()),
([0, 0, 0], "@box2=rc([2,2,2],[6,6,6])".to_string()),
([0, 0, 0], "@result=box1&box2".to_string()),
];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result"));
let result_region = &dsl_map["result"];
let boxes = result_region.bounding_boxes.as_ref().unwrap();
assert_eq!(boxes.len(), 1);
assert_eq!(boxes[0], ([2, 2, 2], [4, 4, 4])); }
#[test]
fn test_xor_operation_simple() {
let units = vec![
([0, 0, 0], "@box1=rc([0,0,0],[3,3,3])".to_string()),
([0, 0, 0], "@box2=rc([1,1,1],[4,4,4])".to_string()),
([0, 0, 0], "@result=box1^box2".to_string()),
];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result"));
let result_region = &dsl_map["result"];
let boxes = result_region.bounding_boxes.as_ref().unwrap();
assert!(boxes.len() > 1);
}
#[test]
fn test_operator_precedence() {
let units = vec![
([0, 0, 0], "@a=rc([0,0,0],[1,1,1])".to_string()),
([0, 0, 0], "@b=rc([2,2,2],[3,3,3])".to_string()),
([0, 0, 0], "@c=rc([2,2,2],[4,4,4])".to_string()),
([0, 0, 0], "@d=rc([0,0,0],[0,0,0])".to_string()),
([0, 0, 0], "@e=rc([5,5,5],[6,6,6])".to_string()),
([0, 0, 0], "@result=a+b&c-d^e".to_string()),
];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result"));
let result_region = &dsl_map["result"];
assert!(result_region.bounding_boxes.is_some());
}
#[test]
fn test_parentheses_override_precedence() {
let units = vec![
([0, 0, 0], "@a=rc([0,0,0],[1,1,1])".to_string()), ([0, 0, 0], "@b=rc([3,3,3],[6,6,6])".to_string()), ([0, 0, 0], "@c=rc([0,0,0],[4,4,4])".to_string()), ([0, 0, 0], "@result1=a+b&c".to_string()), ([0, 0, 0], "@result2=(a+b)&c".to_string()), ];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result1"));
assert!(dsl_map.contains_key("result2"));
let result1_boxes = dsl_map["result1"].bounding_boxes.as_ref().unwrap();
let result2_boxes = dsl_map["result2"].bounding_boxes.as_ref().unwrap();
assert_eq!(result1_boxes.len(), 2);
assert_eq!(result2_boxes.len(), 2);
assert!(result1_boxes.contains(&([0, 0, 0], [1, 1, 1]))); assert!(result2_boxes.contains(&([0, 0, 0], [1, 1, 1]))); assert!(result1_boxes.contains(&([3, 3, 3], [4, 4, 4]))); assert!(result2_boxes.contains(&([3, 3, 3], [4, 4, 4]))); }
#[test]
fn test_complex_boolean_expression() {
let units = vec![
([0, 0, 0], "@base=rc([0,0,0],[10,10,10])".to_string()),
([0, 0, 0], "@cut1=rc([2,2,2],[4,4,4])".to_string()),
([0, 0, 0], "@cut2=rc([6,6,6],[8,8,8])".to_string()),
([0, 0, 0], "@add=rc([5,5,5],[7,7,7])".to_string()),
([0, 0, 0], "@result=base-cut1+add&base-cut2".to_string()),
];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result"));
let result_region = &dsl_map["result"];
assert!(result_region.bounding_boxes.is_some());
let boxes = result_region.bounding_boxes.as_ref().unwrap();
assert!(!boxes.is_empty());
}
#[test]
fn test_no_intersection_result() {
let units = vec![
([0, 0, 0], "@box1=rc([0,0,0],[1,1,1])".to_string()),
([0, 0, 0], "@box2=rc([5,5,5],[6,6,6])".to_string()),
([0, 0, 0], "@result=box1&box2".to_string()),
];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result"));
let result_region = &dsl_map["result"];
let boxes = result_region.bounding_boxes.as_ref().unwrap();
assert_eq!(boxes.len(), 0);
}
#[test]
fn test_difference_no_overlap() {
let units = vec![
([0, 0, 0], "@base=rc([0,0,0],[2,2,2])".to_string()),
([0, 0, 0], "@subtract=rc([5,5,5],[6,6,6])".to_string()),
([0, 0, 0], "@result=base-subtract".to_string()),
];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result"));
let result_region = &dsl_map["result"];
let boxes = result_region.bounding_boxes.as_ref().unwrap();
assert_eq!(boxes.len(), 1);
assert_eq!(boxes[0], ([0, 0, 0], [2, 2, 2]));
}
#[test]
fn test_difference_complete_subtraction() {
let units = vec![
([0, 0, 0], "@small=rc([1,1,1],[2,2,2])".to_string()),
([0, 0, 0], "@large=rc([0,0,0],[3,3,3])".to_string()),
([0, 0, 0], "@result=small-large".to_string()),
];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result"));
let result_region = &dsl_map["result"];
let boxes = result_region.bounding_boxes.as_ref().unwrap();
assert_eq!(boxes.len(), 0);
}
#[test]
fn test_multiple_operators_associativity() {
let units = vec![
([0, 0, 0], "@a=rc([0,0,0],[4,4,4])".to_string()),
([0, 0, 0], "@b=rc([1,1,1],[2,2,2])".to_string()),
([0, 0, 0], "@c=rc([3,3,3],[3,3,3])".to_string()),
([0, 0, 0], "@result1=a-b-c".to_string()), ([0, 0, 0], "@result2=(a-b)-c".to_string()), ];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result1"));
assert!(dsl_map.contains_key("result2"));
let result1_boxes = dsl_map["result1"].bounding_boxes.as_ref().unwrap();
let result2_boxes = dsl_map["result2"].bounding_boxes.as_ref().unwrap();
assert_eq!(result1_boxes, result2_boxes);
}
#[test]
fn test_performance_with_many_boxes() {
let mut units = Vec::new();
units.push(([0, 0, 0], "@base=rc([0,0,0],[1,1,1])".to_string()));
for i in 1..20 {
units.push((
[0, 0, 0],
format!(
"@base=rc([{},{},{}],[{},{},{}])",
i,
i,
i,
i + 1,
i + 1,
i + 1
),
));
}
units.push(([0, 0, 0], "@other=rc([5,5,5],[6,6,6])".to_string()));
for i in 6..15 {
units.push((
[0, 0, 0],
format!(
"@other=rc([{},{},{}],[{},{},{}])",
i,
i,
i,
i + 1,
i + 1,
i + 1
),
));
}
units.push(([0, 0, 0], "@result=base&other".to_string()));
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
assert!(dsl_map.contains_key("result"));
}
#[test]
fn test_chained_operations() {
let units = vec![
([0, 0, 0], "@a=rc([0,0,0],[3,3,3])".to_string()),
([0, 0, 0], "@b=rc([1,1,1],[4,4,4])".to_string()),
([0, 0, 0], "@c=rc([2,2,2],[5,5,5])".to_string()),
([0, 0, 0], "@step1=a+b".to_string()), ([0, 0, 0], "@step2=step1&c".to_string()), ([0, 0, 0], "@step3=step2-a".to_string()), ([0, 0, 0], "@final=step3^b".to_string()), ];
let result = compile(&units);
assert!(result.is_ok());
let dsl_map = result.unwrap();
for region in ["step1", "step2", "step3", "final"] {
assert!(dsl_map.contains_key(region), "Missing region: {}", region);
assert!(dsl_map[region].bounding_boxes.is_some());
}
}
}