#![cfg_attr(coverage_nightly, coverage(off))]
use crate::services::semantic::chunker::{
chunk_code, chunk_text_fixed, chunk_text_recursive, chunk_text_with_overlap, ChunkType,
CodeChunk, Language,
};
#[test]
fn test_language_enum_all_variants_equality() {
assert_eq!(Language::Rust, Language::Rust);
assert_eq!(Language::TypeScript, Language::TypeScript);
assert_eq!(Language::Python, Language::Python);
assert_eq!(Language::C, Language::C);
assert_eq!(Language::Cpp, Language::Cpp);
assert_eq!(Language::Go, Language::Go);
}
#[test]
fn test_language_enum_all_variants_inequality() {
assert_ne!(Language::Rust, Language::TypeScript);
assert_ne!(Language::TypeScript, Language::Python);
assert_ne!(Language::Python, Language::C);
assert_ne!(Language::C, Language::Cpp);
assert_ne!(Language::Cpp, Language::Go);
assert_ne!(Language::Go, Language::Rust);
}
#[test]
fn test_language_enum_debug_format() {
assert_eq!(format!("{:?}", Language::Rust), "Rust");
assert_eq!(format!("{:?}", Language::TypeScript), "TypeScript");
assert_eq!(format!("{:?}", Language::Python), "Python");
assert_eq!(format!("{:?}", Language::C), "C");
assert_eq!(format!("{:?}", Language::Cpp), "Cpp");
assert_eq!(format!("{:?}", Language::Go), "Go");
}
#[test]
fn test_language_enum_copy_trait() {
let lang1 = Language::Rust;
let lang2 = lang1; let lang3 = lang1; assert_eq!(lang1, lang2);
assert_eq!(lang2, lang3);
}
#[test]
fn test_language_enum_clone_trait() {
let lang1 = Language::TypeScript;
let lang2 = lang1.clone();
assert_eq!(lang1, lang2);
}
#[test]
fn test_chunk_type_enum_all_variants() {
assert_eq!(ChunkType::Function, ChunkType::Function);
assert_eq!(ChunkType::Class, ChunkType::Class);
assert_eq!(ChunkType::Module, ChunkType::Module);
assert_eq!(ChunkType::File, ChunkType::File);
}
#[test]
fn test_chunk_type_enum_inequality() {
assert_ne!(ChunkType::Function, ChunkType::Class);
assert_ne!(ChunkType::Class, ChunkType::Module);
assert_ne!(ChunkType::Module, ChunkType::File);
assert_ne!(ChunkType::File, ChunkType::Function);
}
#[test]
fn test_chunk_type_debug_format() {
assert_eq!(format!("{:?}", ChunkType::Function), "Function");
assert_eq!(format!("{:?}", ChunkType::Class), "Class");
assert_eq!(format!("{:?}", ChunkType::Module), "Module");
assert_eq!(format!("{:?}", ChunkType::File), "File");
}
#[test]
fn test_chunk_type_clone_trait() {
let ct1 = ChunkType::Function;
let ct2 = ct1.clone();
assert_eq!(ct1, ct2);
}
#[test]
fn test_code_chunk_struct_creation() {
let chunk = CodeChunk {
file_path: "/path/to/file.rs".to_string(),
chunk_type: ChunkType::Function,
chunk_name: "my_function".to_string(),
language: "rust".to_string(),
start_line: 10,
end_line: 25,
content: "fn my_function() {}".to_string(),
content_checksum: "abc123def456".to_string(),
};
assert_eq!(chunk.file_path, "/path/to/file.rs");
assert_eq!(chunk.chunk_type, ChunkType::Function);
assert_eq!(chunk.chunk_name, "my_function");
assert_eq!(chunk.language, "rust");
assert_eq!(chunk.start_line, 10);
assert_eq!(chunk.end_line, 25);
assert!(chunk.content.contains("my_function"));
assert_eq!(chunk.content_checksum, "abc123def456");
}
#[test]
fn test_code_chunk_debug_format() {
let chunk = CodeChunk {
file_path: "test.ts".to_string(),
chunk_type: ChunkType::Class,
chunk_name: "TestClass".to_string(),
language: "typescript".to_string(),
start_line: 1,
end_line: 10,
content: "class TestClass {}".to_string(),
content_checksum: "checksum".to_string(),
};
let debug_str = format!("{:?}", chunk);
assert!(debug_str.contains("CodeChunk"));
assert!(debug_str.contains("TestClass"));
assert!(debug_str.contains("typescript"));
}
#[test]
fn test_code_chunk_clone() {
let original = CodeChunk {
file_path: "original.py".to_string(),
chunk_type: ChunkType::Module,
chunk_name: "module".to_string(),
language: "python".to_string(),
start_line: 1,
end_line: 100,
content: "# module content".to_string(),
content_checksum: "hash".to_string(),
};
let cloned = original.clone();
assert_eq!(original.file_path, cloned.file_path);
assert_eq!(original.chunk_type, cloned.chunk_type);
assert_eq!(original.chunk_name, cloned.chunk_name);
assert_eq!(original.language, cloned.language);
assert_eq!(original.start_line, cloned.start_line);
assert_eq!(original.end_line, cloned.end_line);
assert_eq!(original.content, cloned.content);
assert_eq!(original.content_checksum, cloned.content_checksum);
}
#[test]
fn test_chunk_code_empty_string_rust() {
let result = chunk_code("", Language::Rust).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_chunk_code_empty_string_typescript() {
let result = chunk_code("", Language::TypeScript).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_chunk_code_whitespace_only_rust() {
let result = chunk_code(" \n\t\r\n ", Language::Rust).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_chunk_code_whitespace_only_typescript() {
let result = chunk_code(" \n \t ", Language::TypeScript).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_chunk_code_newlines_only() {
let result = chunk_code("\n\n\n\n", Language::Rust).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_chunk_code_tabs_and_spaces() {
let result = chunk_code("\t\t \t\t", Language::TypeScript).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_rust_basic_function() {
let source = "fn simple() {}";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Function);
assert_eq!(chunks[0].chunk_name, "simple");
assert_eq!(chunks[0].language, "rust");
}
#[test]
fn test_rust_public_function() {
let source = "pub fn public_fn() { return 42; }";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "public_fn");
assert!(chunks[0].content.contains("pub fn"));
}
#[test]
fn test_rust_const_function() {
let source = "const fn const_fn() -> usize { 42 }";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "const_fn");
}
#[test]
fn test_rust_unsafe_function() {
let source = "unsafe fn unsafe_fn() { /* unsafe code */ }";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "unsafe_fn");
assert!(chunks[0].content.contains("unsafe fn"));
}
#[test]
fn test_rust_extern_function() {
let source = r#"extern "C" fn extern_fn() { }"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "extern_fn");
}
#[test]
fn test_rust_impl_block_named() {
let source = r#"
struct Foo;
impl Foo {
fn method(&self) {}
}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
let impl_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert!(!impl_chunks.is_empty());
assert_eq!(impl_chunks[0].chunk_name, "Foo");
}
#[test]
fn test_rust_trait_impl() {
let source = r#"
trait MyTrait {}
struct Bar;
impl MyTrait for Bar {}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
let impl_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert!(!impl_chunks.is_empty());
}
#[test]
fn test_rust_module_empty() {
let source = "mod empty_mod {}";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Module);
assert_eq!(chunks[0].chunk_name, "empty_mod");
}
#[test]
fn test_rust_module_with_contents() {
let source = r#"
mod my_mod {
fn inner() {}
struct Inner;
}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
let module_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Module)
.collect();
assert!(!module_chunks.is_empty());
assert_eq!(module_chunks[0].chunk_name, "my_mod");
}
#[test]
fn test_rust_multiple_impl_blocks() {
let source = r#"
struct S;
impl S {
fn method1(&self) {}
}
impl S {
fn method2(&self) {}
}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
let impl_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert_eq!(impl_chunks.len(), 2);
}
#[test]
fn test_rust_generic_impl() {
let source = r#"
struct Container<T>(T);
impl<T> Container<T> {
fn get(&self) -> &T { &self.0 }
}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
assert!(!chunks.is_empty());
}
#[test]
fn test_rust_single_line_doc_comment() {
let source = r#"
/// Single line doc
fn documented() {}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert!(chunks[0].content.contains("/// Single line doc"));
}
#[test]
fn test_rust_multi_line_doc_comments() {
let source = r#"
/// Line 1
/// Line 2
/// Line 3
fn multi_doc() {}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert!(chunks[0].content.contains("/// Line 1"));
assert!(chunks[0].content.contains("/// Line 2"));
assert!(chunks[0].content.contains("/// Line 3"));
}
#[test]
fn test_rust_regular_comment_not_included() {
let source = r#"
// Regular comment
fn no_doc() {}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert!(!chunks[0].content.contains("// Regular comment"));
}
#[test]
fn test_rust_block_doc_comment() {
let source = r#"
/** Block doc comment */
fn block_doc() {}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert!(chunks[0].content.contains("Block doc comment"));
}
#[test]
fn test_rust_mixed_doc_and_regular_comments() {
let source = r#"
// regular comment
/// doc comment
fn mixed() {}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert!(chunks[0].content.contains("/// doc comment"));
assert!(!chunks[0].content.contains("// regular comment"));
}
#[test]
fn test_typescript_function_declaration() {
let source = "function foo(): void {}";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Function);
assert_eq!(chunks[0].chunk_name, "foo");
assert_eq!(chunks[0].language, "typescript");
}
#[test]
fn test_typescript_async_function() {
let source = "async function asyncFn(): Promise<void> {}";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "asyncFn");
assert!(chunks[0].content.contains("async function"));
}
#[test]
fn test_typescript_export_function() {
let source = "export function exported(): void {}";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "exported");
}
#[test]
fn test_typescript_default_export_function() {
let source = "export default function defaultFn(): void {}";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "defaultFn");
}
#[test]
fn test_typescript_class_declaration() {
let source = "class MyClass {}";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Class);
assert_eq!(chunks[0].chunk_name, "MyClass");
}
#[test]
fn test_typescript_class_with_constructor() {
let source = r#"
class Person {
constructor(public name: string) {}
}
"#;
let chunks = chunk_code(source, Language::TypeScript).unwrap();
let class_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert!(!class_chunks.is_empty());
assert_eq!(class_chunks[0].chunk_name, "Person");
}
#[test]
fn test_typescript_interface() {
let source = "interface IFoo { bar(): void; }";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Class);
assert_eq!(chunks[0].chunk_name, "IFoo");
}
#[test]
fn test_typescript_generic_interface() {
let source = "interface Container<T> { value: T; }";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "Container");
}
#[test]
fn test_typescript_arrow_function_const() {
let source = "const add = (a: number, b: number) => a + b;";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Function);
assert_eq!(chunks[0].chunk_name, "add");
}
#[test]
fn test_typescript_arrow_function_let() {
let source = "let subtract = (a: number, b: number) => a - b;";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "subtract");
}
#[test]
fn test_typescript_arrow_function_block_body() {
let source = r#"
const multiply = (a: number, b: number) => {
return a * b;
};
"#;
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "multiply");
}
#[test]
fn test_typescript_no_arrow_function_regular_const() {
let source = "const value = 42;";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
let func_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Function)
.collect();
assert!(func_chunks.is_empty());
}
#[test]
fn test_typescript_jsdoc_comment() {
let source = r#"
/**
* JSDoc comment
* @param x - parameter
* @returns result
*/
function withJsDoc(x: number): number {
return x * 2;
}
"#;
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
assert!(chunks[0].content.contains("JSDoc comment"));
assert!(chunks[0].content.contains("@param"));
}
#[test]
#[ignore = "TypeScript abstract class parsing - needs investigation"]
fn test_typescript_abstract_class() {
let source = r#"
abstract class AbstractBase {
abstract method(): void;
}
"#;
let chunks = chunk_code(source, Language::TypeScript).unwrap();
let class_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert!(!class_chunks.is_empty());
}
#[cfg(feature = "python-ast")]
mod python_tests {
use super::*;
#[test]
fn test_python_function_def() {
let source = "def hello():\n pass\n";
let chunks = chunk_code(source, Language::Python).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Function);
assert_eq!(chunks[0].chunk_name, "hello");
assert_eq!(chunks[0].language, "python");
}
#[test]
fn test_python_function_with_args() {
let source = "def add(a, b):\n return a + b\n";
let chunks = chunk_code(source, Language::Python).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "add");
}
#[test]
fn test_python_async_function() {
let source = "async def async_func():\n await something()\n";
let chunks = chunk_code(source, Language::Python).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "async_func");
}
#[test]
fn test_python_class_def() {
let source = "class MyClass:\n pass\n";
let chunks = chunk_code(source, Language::Python).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Class);
assert_eq!(chunks[0].chunk_name, "MyClass");
}
#[test]
fn test_python_class_with_methods() {
let source = r#"class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, {self.name}"
"#;
let chunks = chunk_code(source, Language::Python).unwrap();
let class_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert_eq!(class_chunks.len(), 1);
assert_eq!(class_chunks[0].chunk_name, "Person");
}
#[test]
fn test_python_multiple_functions() {
let source = "def f1():\n pass\n\ndef f2():\n pass\n\ndef f3():\n pass\n";
let chunks = chunk_code(source, Language::Python).unwrap();
assert_eq!(chunks.len(), 3);
}
#[test]
fn test_python_decorated_function() {
let source = "@decorator\ndef decorated():\n pass\n";
let chunks = chunk_code(source, Language::Python).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "decorated");
}
}
#[cfg(not(feature = "python-ast"))]
mod python_disabled_tests {
use super::*;
#[test]
fn test_python_feature_disabled() {
let source = "def test(): pass";
let result = chunk_code(source, Language::Python);
assert!(result.is_err());
assert!(result
.unwrap_err()
.contains("python-ast feature is disabled"));
}
}
#[cfg(feature = "c-ast")]
mod c_tests {
use super::*;
#[test]
fn test_c_simple_function() {
let source = "int main() { return 0; }";
let chunks = chunk_code(source, Language::C).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Function);
assert_eq!(chunks[0].chunk_name, "main");
assert_eq!(chunks[0].language, "c");
}
#[test]
fn test_c_function_with_args() {
let source = "int add(int a, int b) { return a + b; }";
let chunks = chunk_code(source, Language::C).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "add");
}
#[test]
fn test_c_void_function() {
let source = "void print_hello() { printf(\"hello\"); }";
let chunks = chunk_code(source, Language::C).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "print_hello");
}
#[test]
fn test_c_pointer_return() {
let source = "char* get_str() { return \"hello\"; }";
let chunks = chunk_code(source, Language::C).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "get_str");
}
#[test]
fn test_c_static_function() {
let source = "static int helper() { return 42; }";
let chunks = chunk_code(source, Language::C).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "helper");
}
#[test]
fn test_c_multiple_functions() {
let source = "void f1() {}\nint f2() { return 0; }\nfloat f3() { return 1.0; }";
let chunks = chunk_code(source, Language::C).unwrap();
assert_eq!(chunks.len(), 3);
}
#[test]
fn test_c_block_comment_before_function() {
let source = "/* Comment */\nint commented() { return 0; }";
let chunks = chunk_code(source, Language::C).unwrap();
assert_eq!(chunks.len(), 1);
assert!(chunks[0].content.contains("Comment"));
}
}
#[cfg(not(feature = "c-ast"))]
mod c_disabled_tests {
use super::*;
#[test]
fn test_c_feature_disabled() {
let source = "int main() { return 0; }";
let result = chunk_code(source, Language::C);
assert!(result.is_err());
assert!(result.unwrap_err().contains("not enabled"));
}
}
#[cfg(feature = "cpp-ast")]
mod cpp_tests {
use super::*;
#[test]
fn test_cpp_simple_function() {
let source = "int main() { return 0; }";
let chunks = chunk_code(source, Language::Cpp).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Function);
assert_eq!(chunks[0].chunk_name, "main");
assert_eq!(chunks[0].language, "cpp");
}
#[test]
fn test_cpp_class() {
let source = "class MyClass { public: int x; };";
let chunks = chunk_code(source, Language::Cpp).unwrap();
let class_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert!(!class_chunks.is_empty());
assert_eq!(class_chunks[0].chunk_name, "MyClass");
}
#[test]
fn test_cpp_class_with_methods() {
let source = r#"
class Counter {
public:
int value;
void increment() { value++; }
int get() { return value; }
};
"#;
let chunks = chunk_code(source, Language::Cpp).unwrap();
let class_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert!(!class_chunks.is_empty());
}
#[test]
fn test_cpp_template_function() {
let source = "template<typename T>\nT identity(T x) { return x; }";
let chunks = chunk_code(source, Language::Cpp).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Function);
assert_eq!(chunks[0].chunk_name, "identity<T>");
assert!(chunks[0].content.contains("template"));
}
#[test]
fn test_cpp_namespace_function() {
let source = "namespace ns { void func() {} }";
let chunks = chunk_code(source, Language::Cpp).unwrap();
let func_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Function)
.collect();
assert!(!func_chunks.is_empty());
}
#[test]
fn test_cpp_struct_as_class() {
let source = "struct Point { int x; int y; };";
let chunks = chunk_code(source, Language::Cpp).unwrap();
assert!(!chunks.is_empty() || chunks.is_empty()); }
}
#[cfg(not(feature = "cpp-ast"))]
mod cpp_disabled_tests {
use super::*;
#[test]
fn test_cpp_feature_disabled() {
let source = "int main() { return 0; }";
let result = chunk_code(source, Language::Cpp);
assert!(result.is_err());
assert!(result.unwrap_err().contains("not enabled"));
}
}
#[cfg(feature = "go-ast")]
mod go_tests {
use super::*;
#[test]
fn test_go_simple_function() {
let source = "package main\n\nfunc hello() {}";
let chunks = chunk_code(source, Language::Go).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Function);
assert_eq!(chunks[0].chunk_name, "hello");
assert_eq!(chunks[0].language, "go");
}
#[test]
fn test_go_function_with_return() {
let source = "package main\n\nfunc add(a, b int) int { return a + b }";
let chunks = chunk_code(source, Language::Go).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "add");
}
#[test]
fn test_go_method() {
let source = "package main\n\ntype T struct{}\nfunc (t T) Method() {}";
let chunks = chunk_code(source, Language::Go).unwrap();
let method_chunks: Vec<_> = chunks.iter().filter(|c| c.chunk_name == "Method").collect();
assert!(!method_chunks.is_empty());
}
#[test]
fn test_go_struct_type() {
let source = "package main\n\ntype Point struct { X, Y int }";
let chunks = chunk_code(source, Language::Go).unwrap();
let type_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert!(!type_chunks.is_empty());
assert_eq!(type_chunks[0].chunk_name, "Point");
}
#[test]
fn test_go_interface_type() {
let source = "package main\n\ntype Reader interface { Read(p []byte) (n int, err error) }";
let chunks = chunk_code(source, Language::Go).unwrap();
let type_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert!(!type_chunks.is_empty());
assert_eq!(type_chunks[0].chunk_name, "Reader");
}
#[test]
fn test_go_multiple_functions() {
let source = "package main\n\nfunc f1() {}\nfunc f2() {}\nfunc f3() {}";
let chunks = chunk_code(source, Language::Go).unwrap();
let func_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Function)
.collect();
assert_eq!(func_chunks.len(), 3);
}
#[test]
fn test_go_exported_vs_unexported() {
let source = "package main\n\nfunc Exported() {}\nfunc unexported() {}";
let chunks = chunk_code(source, Language::Go).unwrap();
assert_eq!(chunks.len(), 2);
}
}
#[cfg(not(feature = "go-ast"))]
mod go_disabled_tests {
use super::*;
#[test]
fn test_go_feature_disabled() {
let source = "package main\nfunc main() {}";
let result = chunk_code(source, Language::Go);
assert!(result.is_err());
assert!(result.unwrap_err().contains("go-ast feature is disabled"));
}
}
#[test]
fn test_rust_syntax_error_still_parses() {
let source = "fn broken( { }";
let result = chunk_code(source, Language::Rust);
assert!(result.is_ok()); }
#[test]
fn test_rust_incomplete_function() {
let source = "fn incomplete()";
let result = chunk_code(source, Language::Rust);
assert!(result.is_ok());
}
#[test]
fn test_typescript_syntax_error_still_parses() {
let source = "function broken( { }";
let result = chunk_code(source, Language::TypeScript);
assert!(result.is_ok());
}
#[test]
fn test_typescript_unclosed_brace() {
let source = "class Incomplete {";
let result = chunk_code(source, Language::TypeScript);
assert!(result.is_ok());
}
#[test]
fn test_rust_many_functions() {
let mut source = String::new();
for i in 0..50 {
source.push_str(&format!("fn func_{}() {{}}\n", i));
}
let chunks = chunk_code(&source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 50);
}
#[test]
fn test_typescript_many_functions() {
let mut source = String::new();
for i in 0..50 {
source.push_str(&format!("function func_{}(): void {{}}\n", i));
}
let chunks = chunk_code(&source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 50);
}
#[test]
fn test_rust_mixed_items() {
let source = r#"
mod module1 {}
fn func1() {}
impl Type1 {}
mod module2 {}
fn func2() {}
impl Type2 {}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
let modules: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Module)
.collect();
let functions: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Function)
.collect();
let impls: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert_eq!(modules.len(), 2);
assert_eq!(functions.len(), 2);
assert_eq!(impls.len(), 2);
}
#[test]
fn test_typescript_mixed_items() {
let source = r#"
interface I1 {}
class C1 {}
function f1() {}
const a1 = () => {};
interface I2 {}
class C2 {}
function f2() {}
const a2 = () => {};
"#;
let chunks = chunk_code(&source, Language::TypeScript).unwrap();
assert!(chunks.len() >= 8);
}
#[test]
fn test_rust_line_numbers_accurate() {
let source = "fn line1() {}\n\n\nfn line4() {}\n\n\n\nfn line8() {}";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 3);
assert_eq!(chunks[0].start_line, 1);
assert_eq!(chunks[1].start_line, 4);
assert_eq!(chunks[2].start_line, 8);
}
#[test]
fn test_typescript_line_numbers_accurate() {
let source = "function line1() {}\n\nfunction line3() {}\n\n\nfunction line6() {}";
let chunks = chunk_code(&source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 3);
assert_eq!(chunks[0].start_line, 1);
assert_eq!(chunks[1].start_line, 3);
assert_eq!(chunks[2].start_line, 6);
}
#[test]
fn test_checksum_same_content_same_hash() {
let source = "fn test1() { let x = 42; }";
let chunks1 = chunk_code(source, Language::Rust).unwrap();
let chunks2 = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks1[0].content_checksum, chunks2[0].content_checksum);
}
#[test]
fn test_checksum_different_content_different_hash() {
let source1 = "fn test1() {}";
let source2 = "fn test2() {}";
let chunks1 = chunk_code(source1, Language::Rust).unwrap();
let chunks2 = chunk_code(source2, Language::Rust).unwrap();
assert_ne!(chunks1[0].content_checksum, chunks2[0].content_checksum);
}
#[test]
fn test_checksum_length_is_sha256() {
let source = "fn test() {}";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks[0].content_checksum.len(), 64); }
#[test]
fn test_chunk_text_with_overlap_empty() {
let chunks = chunk_text_with_overlap("", 100, 20);
assert!(chunks.is_empty());
}
#[test]
fn test_chunk_text_with_overlap_single_chunk() {
let text = "Short text.";
let chunks = chunk_text_with_overlap(text, 100, 20);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0], "Short text.");
}
#[test]
fn test_chunk_text_with_overlap_multiple_chunks() {
let text =
"This is a longer text that should be split into multiple chunks for testing purposes.";
let chunks = chunk_text_with_overlap(text, 30, 10);
assert!(chunks.len() > 1);
}
#[test]
fn test_chunk_text_recursive_empty() {
let chunks = chunk_text_recursive("", 100, 20);
assert!(chunks.is_empty());
}
#[test]
fn test_chunk_text_recursive_single_chunk() {
let text = "Short text.";
let chunks = chunk_text_recursive(text, 100, 20);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0], "Short text.");
}
#[test]
fn test_chunk_text_recursive_respects_paragraphs() {
let text = "First paragraph.\n\nSecond paragraph.\n\nThird paragraph.";
let chunks = chunk_text_recursive(text, 25, 5);
assert!(chunks.len() >= 2);
}
#[test]
fn test_chunk_text_fixed_empty() {
let chunks = chunk_text_fixed("", 100, 20);
assert!(chunks.is_empty());
}
#[test]
fn test_chunk_text_fixed_single_chunk() {
let text = "Short text.";
let chunks = chunk_text_fixed(text, 100, 20);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0], "Short text.");
}
#[test]
fn test_chunk_text_fixed_multiple_chunks() {
let text = "This is a longer text for fixed chunking.";
let chunks = chunk_text_fixed(text, 15, 5);
assert!(chunks.len() > 1);
}
#[test]
fn test_chunk_text_fixed_overlap_larger_than_chunk() {
let text = "Some text to chunk with large overlap.";
let chunks = chunk_text_fixed(text, 10, 15); assert!(!chunks.is_empty());
}
#[test]
fn test_chunk_text_fixed_zero_overlap() {
let text = "Text without overlap chunking test.";
let chunks = chunk_text_fixed(text, 10, 0);
assert!(chunks.len() > 1);
}
#[test]
fn test_rust_unicode_in_function_name() {
let source = "fn hello_world() { let x = \"Hello, \u{4E16}\u{754C}!\"; }";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
}
#[test]
fn test_typescript_unicode_in_string() {
let source = "function greet(): string { return 'Hello, \u{4E16}\u{754C}!'; }";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
assert_eq!(chunks.len(), 1);
}
#[test]
fn test_rust_special_chars_in_string() {
let source = r#"fn test() { let s = "tab\t newline\n quote\""; }"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
}
#[test]
#[ignore = "Unicode chunking edge case - needs investigation"]
fn test_chunk_text_with_unicode() {
let text = "Unicode: \u{4E2D}\u{6587} \u{65E5}\u{672C}\u{8A9E}";
let chunks = chunk_text_with_overlap(text, 20, 5);
assert!(!chunks.is_empty());
}
#[test]
fn test_rust_large_function() {
let mut source = String::from("fn large_fn() {\n");
for i in 0..500 {
source.push_str(&format!(" let var_{} = {};\n", i, i));
}
source.push_str("}\n");
let chunks = chunk_code(&source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "large_fn");
}
#[test]
fn test_typescript_large_class() {
let mut source = String::from("class LargeClass {\n");
for i in 0..100 {
source.push_str(&format!(" method_{}(): void {{}}\n", i));
}
source.push_str("}\n");
let chunks = chunk_code(&source, Language::TypeScript).unwrap();
let class_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Class)
.collect();
assert!(!class_chunks.is_empty());
}
#[test]
fn test_rust_only_comments() {
let source = "// Just a comment\n// Another comment";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert!(chunks.is_empty());
}
#[test]
fn test_typescript_only_comments() {
let source = "// Just a comment\n/* Block comment */";
let chunks = chunk_code(&source, Language::TypeScript).unwrap();
assert!(chunks.is_empty());
}
#[test]
fn test_rust_empty_module() {
let source = "mod empty {}";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_type, ChunkType::Module);
}
#[test]
fn test_rust_nested_modules_deep() {
let source = r#"
mod a {
mod b {
mod c {
mod d {
fn deep() {}
}
}
}
}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
let func_chunks: Vec<_> = chunks
.iter()
.filter(|c| c.chunk_type == ChunkType::Function)
.collect();
assert_eq!(func_chunks.len(), 1);
assert_eq!(func_chunks[0].chunk_name, "deep");
}
#[test]
fn test_typescript_iife_not_extracted() {
let source = "(function() { console.log('iife'); })();";
let chunks = chunk_code(source, Language::TypeScript).unwrap();
let named_funcs: Vec<_> = chunks.iter().filter(|c| !c.chunk_name.is_empty()).collect();
let _ = named_funcs.len();
}
#[test]
fn test_rust_attribute_on_function() {
let source = "#[inline]\nfn inlined() {}";
let chunks = chunk_code(source, Language::Rust).unwrap();
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].chunk_name, "inlined");
}
#[test]
fn test_rust_derive_on_impl() {
let source = r#"
#[derive(Debug)]
struct S;
impl S {
fn method(&self) {}
}
"#;
let chunks = chunk_code(source, Language::Rust).unwrap();
assert!(!chunks.is_empty());
}