use debtmap::extraction::UnifiedFileExtractor;
use std::path::Path;
fn get_extraction(source: &str) -> debtmap::extraction::ExtractedFileData {
UnifiedFileExtractor::extract(Path::new("test.py"), source).expect("Failed to extract")
}
#[test]
fn test_python_cyclomatic_basic_control_flow() {
let source = r#"
def flow(x):
if x > 0: # +1
return 1
elif x < 0: # +1
return -1
else:
return 0
"#;
let data = get_extraction(source);
let func = &data.functions[0];
assert_eq!(func.cyclomatic, 3);
}
#[test]
fn test_python_cyclomatic_loops() {
let source = r#"
def loops(items):
for item in items: # +1
while item > 0: # +1
item -= 1
return items
"#;
let data = get_extraction(source);
let func = &data.functions[0];
assert_eq!(func.cyclomatic, 3);
}
#[test]
fn test_python_cyclomatic_boolean_ops() {
let source = r#"
def booleans(a, b, c):
if a and b or c: # +1 (if) + 1 (and) + 1 (or) = 3
return True
return False
"#;
let data = get_extraction(source);
let func = &data.functions[0];
assert_eq!(func.cyclomatic, 4);
}
#[test]
fn test_python_cognitive_nesting_penalty() {
let source = r#"
def nested(x, y):
if x > 0: # +1
if y > 0: # +2 (1 + 1 nesting)
for i in range(x): # +3 (1 + 2 nesting)
print(i)
return x + y
"#;
let data = get_extraction(source);
let func = &data.functions[0];
assert_eq!(func.cognitive, 6);
assert_eq!(func.nesting, 3);
}
#[test]
fn test_python_exception_handling_complexity() {
let source = r#"
def try_except():
try: # +1 (cyclomatic)
risky_op()
except ValueError: # +1 (cyclomatic)
handle_val_error()
except Exception as e: # +1 (cyclomatic)
handle_generic()
finally:
cleanup()
"#;
let data = get_extraction(source);
let func = &data.functions[0];
assert!(func.cyclomatic >= 2);
}
#[test]
fn test_python_conditional_expression() {
let source = r#"
def ternary(x):
return "pos" if x > 0 else "neg" # +1
"#;
let data = get_extraction(source);
let func = &data.functions[0];
assert_eq!(func.cyclomatic, 2);
}
#[test]
fn test_python_list_comprehension_complexity() {
let source = r#"
def comp(items):
return [x * 2 for x in items if x > 0] # +1 for 'if'
"#;
let data = get_extraction(source);
let func = &data.functions[0];
assert_eq!(func.cyclomatic, 2);
}
#[test]
fn test_python_match_statement() {
let source = r#"
def switch(status):
match status: # +1
case 200: # +1
return "OK"
case 404: # +1
return "Not Found"
case 500: # +1
return "Error"
case _: # +1
return "Unknown"
"#;
let data = get_extraction(source);
let func = &data.functions[0];
assert_eq!(func.cyclomatic, 6);
}