#![cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
#[cfg(feature = "c-ast")]
mod c_ast_tests {
use crate::ast::core::{AstKind, ClassKind, NodeFlags};
use crate::ast::languages::c_cpp::c_cpp_strategy::CStrategy;
use crate::ast::languages::LanguageStrategy;
use std::path::PathBuf;
#[test]
fn test_c_parse_with_tree_sitter_simple_function() {
let strategy = CStrategy::new();
let code = "int main() { return 0; }";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_c_parse_with_tree_sitter_struct() {
let strategy = CStrategy::new();
let code = "struct Point { int x; int y; };";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_c_parse_with_tree_sitter_enum() {
let strategy = CStrategy::new();
let code = "enum Color { RED, GREEN, BLUE };";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_c_parse_with_tree_sitter_include() {
let strategy = CStrategy::new();
let code = "#include <stdio.h>\nint main() { return 0; }";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_c_convert_to_dag_function() {
let strategy = CStrategy::new();
let code = "int add(int a, int b) { return a + b; }";
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let has_function = dag
.nodes
.iter()
.any(|node| matches!(node.kind, AstKind::Function(_)));
assert!(has_function, "Should have a function node");
}
#[test]
fn test_c_convert_to_dag_struct() {
let strategy = CStrategy::new();
let code = "struct Person { char* name; int age; };";
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let has_struct = dag
.nodes
.iter()
.any(|node| matches!(node.kind, AstKind::Class(ClassKind::Struct)));
assert!(has_struct, "Should have a struct node");
}
#[test]
fn test_c_convert_to_dag_enum() {
let strategy = CStrategy::new();
let code = "enum Status { OK, ERROR, PENDING };";
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let has_enum = dag
.nodes
.iter()
.any(|node| matches!(node.kind, AstKind::Class(ClassKind::Enum)));
assert!(has_enum, "Should have an enum node");
}
#[test]
fn test_c_convert_to_dag_control_flow() {
let strategy = CStrategy::new();
let code = r#"
int foo(int x) {
if (x > 0) {
return x;
}
while (x < 10) {
x++;
}
return x;
}
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let control_flow_count = dag
.nodes
.iter()
.filter(|node| node.flags.has(NodeFlags::CONTROL_FLOW))
.count();
assert!(control_flow_count >= 2, "Should have control flow nodes");
}
#[test]
fn test_c_convert_to_dag_include() {
let strategy = CStrategy::new();
let code = "#include <stdio.h>";
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let has_import = dag
.nodes
.iter()
.any(|node| matches!(node.kind, AstKind::Import(_)));
assert!(has_import, "Should have an import node");
}
#[tokio::test]
async fn test_c_parse_file_success() {
let strategy = CStrategy::new();
let path = PathBuf::from("test.c");
let code = "int main() { return 0; }";
let result = strategy.parse_file(&path, code).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_c_parse_file_complex() {
let strategy = CStrategy::new();
let path = PathBuf::from("test.c");
let code = r#"
#include <stdio.h>
#include <stdlib.h>
struct Node {
int value;
struct Node* next;
};
enum ErrorCode {
SUCCESS = 0,
FAILURE = -1
};
int calculate(int x, int y) {
if (x > y) {
return x - y;
} else if (x < y) {
return y - x;
}
return 0;
}
int main() {
for (int i = 0; i < 10; i++) {
printf("%d\n", i);
}
return 0;
}
"#;
let result = strategy.parse_file(&path, code).await;
assert!(result.is_ok());
let dag = result.unwrap();
let functions = strategy.extract_functions(&dag);
let types = strategy.extract_types(&dag);
assert!(functions.len() >= 2);
assert!(types.len() >= 2);
}
#[test]
fn test_c_parse_empty_code() {
let strategy = CStrategy::new();
let code = "";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_c_parse_whitespace_only() {
let strategy = CStrategy::new();
let code = " \n\t \n ";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_c_parse_comment_only() {
let strategy = CStrategy::new();
let code = "// This is a comment\n/* Multi-line\ncomment */";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_c_convert_to_dag_empty() {
let strategy = CStrategy::new();
let code = "";
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
assert!(dag.nodes.is_empty());
}
#[test]
fn test_c_convert_to_dag_multiple_includes() {
let strategy = CStrategy::new();
let code = r#"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "myheader.h"
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let import_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Import(_)))
.count();
assert_eq!(import_count, 4);
}
#[test]
fn test_c_convert_to_dag_for_loop() {
let strategy = CStrategy::new();
let code = r#"
void loop_test() {
for (int i = 0; i < 10; i++) {
// body
}
}
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let control_flow_count = dag
.nodes
.iter()
.filter(|node| node.flags.has(NodeFlags::CONTROL_FLOW))
.count();
assert!(
control_flow_count >= 1,
"Should detect for loop as control flow"
);
}
#[test]
fn test_c_convert_to_dag_switch_statement() {
let strategy = CStrategy::new();
let code = r#"
int switch_test(int x) {
switch (x) {
case 0: return 0;
case 1: return 1;
default: return -1;
}
}
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let control_flow_count = dag
.nodes
.iter()
.filter(|node| node.flags.has(NodeFlags::CONTROL_FLOW))
.count();
assert!(
control_flow_count >= 1,
"Should detect switch as control flow"
);
}
#[test]
fn test_c_convert_to_dag_nested_control_flow() {
let strategy = CStrategy::new();
let code = r#"
void nested_test(int x) {
if (x > 0) {
while (x > 0) {
for (int i = 0; i < x; i++) {
if (i % 2 == 0) {
// even
}
}
x--;
}
}
}
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let control_flow_count = dag
.nodes
.iter()
.filter(|node| node.flags.has(NodeFlags::CONTROL_FLOW))
.count();
assert!(
control_flow_count >= 4,
"Should detect nested control flow structures"
);
}
#[test]
fn test_c_convert_to_dag_multiple_functions() {
let strategy = CStrategy::new();
let code = r#"
int func1() { return 1; }
int func2() { return 2; }
int func3() { return 3; }
int main() { return 0; }
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let function_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Function(_)))
.count();
assert!(function_count >= 4, "Should detect all 4 functions");
}
#[test]
fn test_c_convert_to_dag_multiple_structs() {
let strategy = CStrategy::new();
let code = r#"
struct Point { int x; int y; };
struct Line { struct Point start; struct Point end; };
struct Rectangle { struct Point topLeft; int width; int height; };
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let struct_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Class(ClassKind::Struct)))
.count();
assert!(struct_count >= 3, "Should detect all 3 structs");
}
#[test]
fn test_c_convert_to_dag_mixed_types() {
let strategy = CStrategy::new();
let code = r#"
struct Point { int x; int y; };
enum Color { RED, GREEN, BLUE };
typedef struct { float r; float g; float b; } RGB;
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let struct_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Class(ClassKind::Struct)))
.count();
let enum_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Class(ClassKind::Enum)))
.count();
assert!(struct_count >= 1, "Should detect struct");
assert!(enum_count >= 1, "Should detect enum");
}
#[tokio::test]
async fn test_c_parse_file_empty() {
let strategy = CStrategy::new();
let path = PathBuf::from("empty.c");
let code = "";
let result = strategy.parse_file(&path, code).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_c_parse_file_minimal() {
let strategy = CStrategy::new();
let path = PathBuf::from("minimal.c");
let code = "void f(){}";
let result = strategy.parse_file(&path, code).await;
assert!(result.is_ok());
let dag = result.unwrap();
let functions = strategy.extract_functions(&dag);
assert!(!functions.is_empty());
}
#[test]
fn test_c_complexity_integration() {
let strategy = CStrategy::new();
let code = r#"
int complex_function(int x, int y) {
if (x > 0) {
if (y > 0) {
return x + y;
}
}
while (x < y) {
for (int i = 0; i < 10; i++) {
x++;
}
}
switch (x) {
case 0: return 0;
case 1: return 1;
default: return -1;
}
}
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let (cyclomatic, cognitive) = strategy.calculate_complexity(&dag);
assert!(
cyclomatic > 1,
"Complex function should have high cyclomatic complexity"
);
assert!(
cognitive > 0,
"Complex function should have high cognitive complexity"
);
}
}
#[cfg(test)]
#[cfg(feature = "cpp-ast")]
mod cpp_ast_tests {
use crate::ast::core::{AstKind, ClassKind, NodeFlags};
use crate::ast::languages::c_cpp::c_cpp_strategy::CppStrategy;
use crate::ast::languages::LanguageStrategy;
use std::path::PathBuf;
#[test]
fn test_cpp_parse_with_tree_sitter_simple_function() {
let strategy = CppStrategy::new();
let code = "int main() { return 0; }";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_cpp_parse_with_tree_sitter_class() {
let strategy = CppStrategy::new();
let code = "class MyClass { public: void doSomething(); };";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_cpp_parse_with_tree_sitter_struct() {
let strategy = CppStrategy::new();
let code = "struct Point { int x; int y; };";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_cpp_convert_to_dag_class() {
let strategy = CppStrategy::new();
let code = r#"
class Rectangle {
public:
Rectangle(int w, int h) : width(w), height(h) {}
int area() { return width * height; }
private:
int width;
int height;
};
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let has_class = dag
.nodes
.iter()
.any(|node| matches!(node.kind, AstKind::Class(ClassKind::Regular)));
assert!(has_class, "Should have a class node");
}
#[test]
fn test_cpp_convert_to_dag_function() {
let strategy = CppStrategy::new();
let code = "int add(int a, int b) { return a + b; }";
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let has_function = dag
.nodes
.iter()
.any(|node| matches!(node.kind, AstKind::Function(_)));
assert!(has_function, "Should have a function node");
}
#[test]
fn test_cpp_convert_to_dag_control_flow() {
let strategy = CppStrategy::new();
let code = r#"
int foo(int x) {
if (x > 0) {
return x;
}
switch (x) {
case 0: return 0;
default: return -1;
}
}
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let control_flow_count = dag
.nodes
.iter()
.filter(|node| node.flags.has(NodeFlags::CONTROL_FLOW))
.count();
assert!(control_flow_count >= 2, "Should have control flow nodes");
}
#[tokio::test]
async fn test_cpp_parse_file_success() {
let strategy = CppStrategy::new();
let path = PathBuf::from("test.cpp");
let code = "int main() { return 0; }";
let result = strategy.parse_file(&path, code).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_cpp_parse_file_complex() {
let strategy = CppStrategy::new();
let path = PathBuf::from("test.cpp");
let code = r#"
#include <iostream>
#include <vector>
class Stack {
public:
void push(int value) {
data.push_back(value);
}
int pop() {
if (data.empty()) {
return -1;
}
int val = data.back();
data.pop_back();
return val;
}
bool isEmpty() const {
return data.empty();
}
private:
std::vector<int> data;
};
enum class Status {
OK,
ERROR,
PENDING
};
int main() {
Stack s;
for (int i = 0; i < 10; ++i) {
s.push(i);
}
while (!s.isEmpty()) {
std::cout << s.pop() << std::endl;
}
return 0;
}
"#;
let result = strategy.parse_file(&path, code).await;
assert!(result.is_ok());
let dag = result.unwrap();
let functions = strategy.extract_functions(&dag);
let types = strategy.extract_types(&dag);
assert!(functions.len() >= 3);
assert!(types.len() >= 1);
}
#[test]
fn test_cpp_parse_empty_code() {
let strategy = CppStrategy::new();
let code = "";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_cpp_parse_whitespace_only() {
let strategy = CppStrategy::new();
let code = " \n\t \n ";
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_cpp_parse_namespace() {
let strategy = CppStrategy::new();
let code = r#"
namespace MyNamespace {
class MyClass {
public:
void doSomething();
};
}
"#;
let result = strategy.parse_with_tree_sitter(code);
assert!(result.is_ok());
}
#[test]
fn test_cpp_convert_to_dag_empty() {
let strategy = CppStrategy::new();
let code = "";
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
assert!(dag.nodes.is_empty());
}
#[test]
fn test_cpp_convert_to_dag_multiple_classes() {
let strategy = CppStrategy::new();
let code = r#"
class Shape { public: virtual void draw() = 0; };
class Circle : public Shape { public: void draw() override {} };
class Rectangle : public Shape { public: void draw() override {} };
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let class_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Class(ClassKind::Regular)))
.count();
assert!(class_count >= 3, "Should detect all 3 classes");
}
#[test]
fn test_cpp_convert_to_dag_template() {
let strategy = CppStrategy::new();
let code = r#"
template<typename T>
class Container {
public:
void add(T item);
T get(int index);
};
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let has_class = dag
.nodes
.iter()
.any(|node| matches!(node.kind, AstKind::Class(_)));
assert!(has_class, "Should detect template class");
}
#[test]
fn test_cpp_convert_to_dag_enum_class() {
let strategy = CppStrategy::new();
let code = r#"
enum class Color { Red, Green, Blue };
enum class Direction : int { North = 0, South = 1, East = 2, West = 3 };
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let enum_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Class(ClassKind::Enum)))
.count();
assert!(enum_count >= 2, "Should detect enum classes");
}
#[test]
fn test_cpp_convert_to_dag_lambda() {
let strategy = CppStrategy::new();
let code = r#"
void lambda_test() {
auto lambda = [](int x) { return x * 2; };
auto capture = [&](int y) { return y + 1; };
}
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let has_function = dag
.nodes
.iter()
.any(|node| matches!(node.kind, AstKind::Function(_)));
assert!(has_function, "Should detect function with lambdas");
}
#[test]
fn test_cpp_convert_to_dag_nested_classes() {
let strategy = CppStrategy::new();
let code = r#"
class Outer {
public:
class Inner {
public:
void innerMethod();
};
void outerMethod();
};
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let class_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Class(ClassKind::Regular)))
.count();
assert!(class_count >= 2, "Should detect nested classes");
}
#[tokio::test]
async fn test_cpp_parse_file_empty() {
let strategy = CppStrategy::new();
let path = PathBuf::from("empty.cpp");
let code = "";
let result = strategy.parse_file(&path, code).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_cpp_parse_file_minimal() {
let strategy = CppStrategy::new();
let path = PathBuf::from("minimal.cpp");
let code = "void f(){}";
let result = strategy.parse_file(&path, code).await;
assert!(result.is_ok());
let dag = result.unwrap();
let functions = strategy.extract_functions(&dag);
assert!(!functions.is_empty());
}
#[test]
fn test_cpp_convert_to_dag_with_inheritance() {
let strategy = CppStrategy::new();
let code = r#"
class Base {
public:
virtual void method() {}
};
class Derived : public Base {
public:
void method() override {}
};
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let class_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Class(ClassKind::Regular)))
.count();
assert!(
class_count >= 2,
"Should detect both base and derived classes"
);
}
#[test]
fn test_cpp_complexity_integration() {
let strategy = CppStrategy::new();
let code = r#"
class Calculator {
public:
int compute(int x, int y) {
if (x > 0) {
if (y > 0) {
return x + y;
}
}
while (x < y) {
for (int i = 0; i < 10; i++) {
x++;
}
}
return 0;
}
};
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let (cyclomatic, cognitive) = strategy.calculate_complexity(&dag);
assert!(
cyclomatic > 1,
"Complex method should have high cyclomatic complexity"
);
assert!(
cognitive > 0,
"Complex method should have high cognitive complexity"
);
}
#[test]
fn test_cpp_convert_to_dag_multiple_includes() {
let strategy = CppStrategy::new();
let code = r#"
#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include "myheader.hpp"
"#;
let tree = strategy.parse_with_tree_sitter(code).unwrap();
let dag = strategy.convert_to_dag(&tree, code);
let import_count = dag
.nodes
.iter()
.filter(|node| matches!(node.kind, AstKind::Import(_)))
.count();
assert_eq!(import_count, 5);
}
}
#[cfg(test)]
#[cfg(any(feature = "c-ast", feature = "cpp-ast"))]
mod visitor_tests {
use crate::ast::core::{AstDag, AstKind, ClassKind, FunctionKind, Language};
use crate::ast::languages::c_cpp_visitor::CTreeSitterVisitor;
#[test]
fn test_visitor_new() {
let mut dag = AstDag::new();
let content = "int main() {}";
let visitor = CTreeSitterVisitor::new(&mut dag, content, Language::C);
assert!(visitor.current_parent.is_none());
}
#[test]
fn test_visitor_add_node() {
let mut dag = AstDag::new();
let content = "int main() {}";
let mut visitor = CTreeSitterVisitor::new(&mut dag, content, Language::C);
let key = visitor.add_node(AstKind::Function(FunctionKind::Regular));
assert_eq!(key, 0);
assert_eq!(dag.nodes.len(), 1);
let node = dag.nodes.get(key).unwrap();
assert_eq!(node.lang, Language::C);
}
#[test]
fn test_visitor_add_node_with_parent() {
let mut dag = AstDag::new();
let content = "struct Foo { void bar(); };";
let mut visitor = CTreeSitterVisitor::new(&mut dag, content, Language::Cpp);
let parent_key = visitor.add_node(AstKind::Class(ClassKind::Struct));
visitor.current_parent = Some(parent_key);
let child_key = visitor.add_node(AstKind::Function(FunctionKind::Method));
let child_node = dag.nodes.get(child_key).unwrap();
assert_eq!(child_node.parent, parent_key);
}
#[test]
fn test_visitor_with_cpp_language() {
let mut dag = AstDag::new();
let content = "class Foo {};";
let visitor = CTreeSitterVisitor::new(&mut dag, content, Language::Cpp);
assert_eq!(visitor.language, Language::Cpp);
assert!(visitor.current_parent.is_none());
}
#[test]
fn test_visitor_multiple_nodes() {
let mut dag = AstDag::new();
let content = "struct Foo {}; int bar();";
let mut visitor = CTreeSitterVisitor::new(&mut dag, content, Language::C);
let _ = visitor.add_node(AstKind::Class(ClassKind::Struct));
let _ = visitor.add_node(AstKind::Function(FunctionKind::Regular));
let _ = visitor.add_node(AstKind::Import(crate::ast::core::ImportKind::Module));
assert_eq!(dag.nodes.len(), 3);
}
#[test]
fn test_visitor_parent_chain() {
let mut dag = AstDag::new();
let content = "struct Outer { struct Inner {}; };";
let mut visitor = CTreeSitterVisitor::new(&mut dag, content, Language::C);
let outer_key = visitor.add_node(AstKind::Class(ClassKind::Struct));
visitor.current_parent = Some(outer_key);
let inner_key = visitor.add_node(AstKind::Class(ClassKind::Struct));
assert_eq!(dag.nodes.get(inner_key).unwrap().parent, outer_key);
}
#[test]
fn test_visitor_no_parent() {
let mut dag = AstDag::new();
let content = "int main() {}";
let mut visitor = CTreeSitterVisitor::new(&mut dag, content, Language::C);
let key = visitor.add_node(AstKind::Function(FunctionKind::Regular));
assert_eq!(dag.nodes.get(key).unwrap().parent, 0);
}
}
#[cfg(test)]
#[cfg(not(feature = "c-ast"))]
mod non_c_ast_tests {
use crate::ast::languages::c_cpp::c_cpp_strategy::CStrategy;
use crate::ast::languages::LanguageStrategy;
use std::path::PathBuf;
#[tokio::test]
async fn test_c_parse_file_without_feature() {
let strategy = CStrategy::new();
let path = PathBuf::from("test.c");
let code = "int main() { return 0; }";
let result = strategy.parse_file(&path, code).await;
assert!(result.is_err());
assert!(result.err().unwrap().to_string().contains("c-ast"));
}
}
#[cfg(test)]
#[cfg(not(feature = "cpp-ast"))]
mod non_cpp_ast_tests {
use crate::ast::languages::c_cpp::c_cpp_strategy::CppStrategy;
use crate::ast::languages::LanguageStrategy;
use std::path::PathBuf;
#[tokio::test]
async fn test_cpp_parse_file_without_feature() {
let strategy = CppStrategy::new();
let path = PathBuf::from("test.cpp");
let code = "int main() { return 0; }";
let result = strategy.parse_file(&path, code).await;
assert!(result.is_err());
assert!(result.err().unwrap().to_string().contains("cpp-ast"));
}
}