#[cfg(feature = "c-ast")]
const SIMPLE_C_FUNCTION: &str = r#"
#include <stdio.h>
// Simple function
int add(int a, int b) {
return a + b;
}
// Main function
int main() {
int result = add(5, 3);
printf("Result: %d\n", result);
return 0;
}
"#;
#[cfg(feature = "c-ast")]
const C_STRUCT_EXAMPLE: &str = r#"
#include <stdio.h>
#include <stdlib.h>
// Define a simple structure
struct Point {
int x;
int y;
};
// Function to create a new point
struct Point* createPoint(int x, int y) {
struct Point* p = (struct Point*)malloc(sizeof(struct Point));
p->x = x;
p->y = y;
return p;
}
// Calculate distance (simplified)
int distance(struct Point* p1, struct Point* p2) {
int dx = p2->x - p1->x;
int dy = p2->y - p1->y;
return dx*dx + dy*dy;
}
"#;
#[cfg(feature = "c-ast")]
const C_COMPLEX_EXAMPLE: &str = r#"
#include <stdio.h>
// Global variables
int globalValue = 10;
static int privateValue = 20;
// Typedef example
typedef unsigned long size_t;
typedef struct {
int value;
} Container;
// Enum example
enum Color {
RED,
GREEN,
BLUE
};
// Function with complex control flow
int complexFunction(int a, int b) {
int result = 0;
if (a > b) {
if (a > 10) {
result = a * 2;
} else {
result = a;
}
} else if (b > a) {
for (int i = 0; i < b; i++) {
result += i;
if (result > 100) {
break;
}
}
} else {
switch (a) {
case 0:
result = 0;
break;
case 1:
result = 1;
break;
default:
result = a + b;
break;
}
}
return result;
}
// Main function
int main() {
int x = 10;
int y = 20;
int result = complexFunction(x, y);
printf("Result: %d\n", result);
return 0;
}
"#;
#[cfg(feature = "c-ast")]
#[test]
fn test_simple_c_function_analysis() {
let visitor = CAstVisitor::new(Path::new("test.c"));
let items = visitor
.analyze_c_source(SIMPLE_C_FUNCTION)
.expect("Should parse C functions");
assert!(!items.is_empty(), "Should extract at least one AST item");
let function_items: Vec<_> = items
.iter()
.filter(|item| matches!(item, AstItem::Function { .. }))
.collect();
assert_eq!(function_items.len(), 2, "Should extract two functions");
let func_names: Vec<_> = function_items
.iter()
.filter_map(|item| match item {
AstItem::Function { name, .. } => Some(name.as_str()),
_ => None,
})
.collect();
assert!(func_names.contains(&"add"), "Should extract 'add' function");
assert!(
func_names.contains(&"main"),
"Should extract 'main' function"
);
}
#[cfg(feature = "c-ast")]
#[test]
fn test_c_struct_analysis() {
let visitor = CAstVisitor::new(Path::new("point.c"));
let items = visitor
.analyze_c_source(C_STRUCT_EXAMPLE)
.expect("Should parse C struct");
let struct_items: Vec<_> = items
.iter()
.filter(|item| matches!(item, AstItem::Struct { .. }))
.collect();
assert_eq!(struct_items.len(), 1, "Should extract one struct");
if let AstItem::Struct { name, .. } = &struct_items[0] {
assert_eq!(name, "Point", "Should extract correct struct name");
}
let function_items: Vec<_> = items
.iter()
.filter(|item| matches!(item, AstItem::Function { .. }))
.collect();
assert_eq!(function_items.len(), 2, "Should extract two functions");
}
#[cfg(feature = "c-ast")]
#[test]
fn test_c_complex_example() {
let visitor = CAstVisitor::new(Path::new("complex.c"));
let items = visitor
.analyze_c_source(C_COMPLEX_EXAMPLE)
.expect("Should parse complex C code");
let var_items: Vec<_> = items
.iter()
.filter(|item| matches!(item, AstItem::Struct { .. })) .collect();
assert!(!var_items.is_empty(), "Should extract global variables");
let enum_items: Vec<_> = items
.iter()
.filter(|item| matches!(item, AstItem::Enum { .. }))
.collect();
assert_eq!(enum_items.len(), 1, "Should extract one enum");
if let AstItem::Enum { name, .. } = &enum_items[0] {
assert_eq!(name, "Color", "Should extract correct enum name");
}
let typedef_items: Vec<_> = items
.iter()
.filter(|item| matches!(item, AstItem::Struct { .. })) .collect();
assert!(!typedef_items.is_empty(), "Should extract typedefs");
}
#[cfg(feature = "c-ast")]
#[test]
fn test_c_complexity_analysis() {
let mut analyzer = CComplexityAnalyzer::new();
let (cyclomatic, cognitive) = analyzer
.analyze_complexity(C_COMPLEX_EXAMPLE)
.expect("Should analyze C complexity");
assert!(
cyclomatic > 5,
"Cyclomatic complexity should be significant"
);
assert!(cognitive > 5, "Cognitive complexity should be significant");
}