#[test]
fn test_rust_visitor_new() {
let visitor = RustVisitor::new("fn main() {}".to_string());
assert!(visitor.items.is_empty());
}
#[test]
fn test_rust_visitor_get_visibility_public() {
let visitor = RustVisitor::new(String::new());
let vis = syn::parse_quote!(pub);
assert_eq!(visitor.get_visibility(&vis), "pub");
}
#[test]
fn test_rust_visitor_get_visibility_private() {
let visitor = RustVisitor::new(String::new());
let vis = syn::Visibility::Inherited;
assert_eq!(visitor.get_visibility(&vis), "private");
}
#[test]
fn test_rust_visitor_get_visibility_restricted_crate() {
let visitor = RustVisitor::new(String::new());
let vis: syn::Visibility = syn::parse_quote!(pub(crate));
let result = visitor.get_visibility(&vis);
assert!(result.starts_with("pub("));
}
#[test]
fn test_rust_visitor_use_statement_path() {
use syn::parse_str;
let code = "use std::io;";
let syntax = parse_str::<syn::File>(code).unwrap();
let mut visitor = RustVisitor::new(code.to_string());
visitor.visit_file(&syntax);
assert_eq!(visitor.items.len(), 1);
if let AstItem::Use { path, .. } = &visitor.items[0] {
assert_eq!(path, "std");
} else {
panic!("Expected Use item");
}
}
#[test]
fn test_rust_visitor_use_statement_name() {
use syn::parse_str;
let code = "use io;";
let syntax = parse_str::<syn::File>(code).unwrap();
let mut visitor = RustVisitor::new(code.to_string());
visitor.visit_file(&syntax);
assert_eq!(visitor.items.len(), 1);
if let AstItem::Use { path, .. } = &visitor.items[0] {
assert_eq!(path, "io");
}
}
#[test]
fn test_rust_visitor_use_statement_glob() {
use syn::parse_str;
let code = "use std::prelude::*;";
let syntax = parse_str::<syn::File>(code).unwrap();
let mut visitor = RustVisitor::new(code.to_string());
visitor.visit_file(&syntax);
assert_eq!(visitor.items.len(), 1);
}
#[test]
fn test_rust_visitor_use_statement_rename() {
use syn::parse_str;
let code = "use std::io as stdio;";
let syntax = parse_str::<syn::File>(code).unwrap();
let mut visitor = RustVisitor::new(code.to_string());
visitor.visit_file(&syntax);
assert_eq!(visitor.items.len(), 1);
}
#[test]
fn test_rust_visitor_use_statement_group() {
use syn::parse_str;
let code = "use std::{io, fs};";
let syntax = parse_str::<syn::File>(code).unwrap();
let mut visitor = RustVisitor::new(code.to_string());
visitor.visit_file(&syntax);
assert_eq!(visitor.items.len(), 1);
}
#[test]
fn test_rust_visitor_impl_inherent() {
use syn::parse_str;
let code = r#"
impl MyStruct {
fn new() -> Self { Self {} }
}
"#;
let syntax = parse_str::<syn::File>(code).unwrap();
let mut visitor = RustVisitor::new(code.to_string());
visitor.visit_file(&syntax);
assert_eq!(visitor.items.len(), 1);
if let AstItem::Impl {
type_name,
trait_name,
..
} = &visitor.items[0]
{
assert_eq!(type_name, "MyStruct");
assert!(trait_name.is_none());
}
}
#[test]
fn test_rust_visitor_struct_unit() {
use syn::parse_str;
let code = "pub struct UnitStruct;";
let syntax = parse_str::<syn::File>(code).unwrap();
let mut visitor = RustVisitor::new(code.to_string());
visitor.visit_file(&syntax);
assert_eq!(visitor.items.len(), 1);
if let AstItem::Struct { fields_count, .. } = &visitor.items[0] {
assert_eq!(*fields_count, 0);
}
}
#[test]
fn test_rust_visitor_struct_tuple() {
use syn::parse_str;
let code = "pub struct TupleStruct(i32, String);";
let syntax = parse_str::<syn::File>(code).unwrap();
let mut visitor = RustVisitor::new(code.to_string());
visitor.visit_file(&syntax);
assert_eq!(visitor.items.len(), 1);
if let AstItem::Struct { fields_count, .. } = &visitor.items[0] {
assert_eq!(*fields_count, 2);
}
}
#[test]
fn test_ast_item_display_name_function() {
let item = AstItem::Function {
name: "my_func".to_string(),
visibility: "pub".to_string(),
is_async: false,
line: 1,
};
assert_eq!(item.display_name(), "my_func");
}
#[test]
fn test_ast_item_display_name_struct() {
let item = AstItem::Struct {
name: "MyStruct".to_string(),
visibility: "pub".to_string(),
fields_count: 3,
derives: vec![],
line: 1,
};
assert_eq!(item.display_name(), "MyStruct");
}
#[test]
fn test_ast_item_display_name_enum() {
let item = AstItem::Enum {
name: "MyEnum".to_string(),
visibility: "pub".to_string(),
variants_count: 5,
line: 1,
};
assert_eq!(item.display_name(), "MyEnum");
}
#[test]
fn test_ast_item_display_name_trait() {
let item = AstItem::Trait {
name: "MyTrait".to_string(),
visibility: "pub".to_string(),
line: 1,
};
assert_eq!(item.display_name(), "MyTrait");
}
#[test]
fn test_ast_item_display_name_impl() {
let item = AstItem::Impl {
type_name: "MyType".to_string(),
trait_name: Some("Display".to_string()),
line: 1,
};
assert_eq!(item.display_name(), "MyType");
}
#[test]
fn test_ast_item_display_name_module() {
let item = AstItem::Module {
name: "my_mod".to_string(),
visibility: "pub".to_string(),
line: 1,
};
assert_eq!(item.display_name(), "my_mod");
}
#[test]
fn test_ast_item_display_name_use() {
let item = AstItem::Use {
path: "std::io".to_string(),
line: 1,
};
assert_eq!(item.display_name(), "std::io");
}
#[test]
fn test_ast_item_display_name_import() {
let item = AstItem::Import {
module: "numpy".to_string(),
items: vec!["array".to_string()],
alias: Some("np".to_string()),
line: 1,
};
assert_eq!(item.display_name(), "numpy");
}
#[test]
fn test_ast_item_equality() {
let item1 = AstItem::Function {
name: "test".to_string(),
visibility: "pub".to_string(),
is_async: false,
line: 1,
};
let item2 = AstItem::Function {
name: "test".to_string(),
visibility: "pub".to_string(),
is_async: false,
line: 1,
};
assert_eq!(item1, item2);
}
#[test]
fn test_ast_item_inequality_different_type() {
let func = AstItem::Function {
name: "test".to_string(),
visibility: "pub".to_string(),
is_async: false,
line: 1,
};
let struct_item = AstItem::Struct {
name: "test".to_string(),
visibility: "pub".to_string(),
fields_count: 0,
derives: vec![],
line: 1,
};
assert_ne!(func, struct_item);
}
#[test]
fn test_format_module_item() {
let item = AstItem::Module {
name: "utils".to_string(),
visibility: "pub".to_string(),
line: 10,
};
let result = format_module_item(&item);
assert!(result.contains("pub mod utils"));
assert!(result.contains("line 10"));
}
#[test]
fn test_format_module_item_wrong_type() {
let item = AstItem::Function {
name: "func".to_string(),
visibility: "pub".to_string(),
is_async: false,
line: 1,
};
let result = format_module_item(&item);
assert!(result.is_empty());
}
#[test]
fn test_format_struct_item_with_derives() {
let item = AstItem::Struct {
name: "MyStruct".to_string(),
visibility: "pub".to_string(),
fields_count: 5,
derives: vec!["Debug".to_string(), "Clone".to_string()],
line: 20,
};
let result = format_struct_item(&item);
assert!(result.contains("pub struct MyStruct"));
assert!(result.contains("5 fields"));
assert!(result.contains("Debug"));
assert!(result.contains("Clone"));
}
#[test]
fn test_format_struct_item_no_derives() {
let item = AstItem::Struct {
name: "Simple".to_string(),
visibility: "pub".to_string(),
fields_count: 1,
derives: vec![],
line: 5,
};
let result = format_struct_item(&item);
assert!(result.contains("Simple"));
assert!(!result.contains("derives"));
}
#[test]
fn test_format_enum_item() {
let item = AstItem::Enum {
name: "Status".to_string(),
visibility: "pub".to_string(),
variants_count: 3,
line: 15,
};
let result = format_enum_item(&item);
assert!(result.contains("pub enum Status"));
assert!(result.contains("3 variants"));
}
#[test]
fn test_format_trait_item() {
let item = AstItem::Trait {
name: "Printable".to_string(),
visibility: "pub".to_string(),
line: 25,
};
let result = format_trait_item(&item);
assert!(result.contains("pub trait Printable"));
}
#[test]
fn test_format_function_item_async() {
let item = AstItem::Function {
name: "fetch_data".to_string(),
visibility: "pub".to_string(),
is_async: true,
line: 30,
};
let result = format_function_item(&item);
assert!(result.contains("async"));
assert!(result.contains("fetch_data"));
}
#[test]
fn test_format_function_item_sync() {
let item = AstItem::Function {
name: "process".to_string(),
visibility: "private".to_string(),
is_async: false,
line: 35,
};
let result = format_function_item(&item);
assert!(!result.contains("async"));
assert!(result.contains("private"));
}
#[test]
fn test_format_impl_item_with_trait() {
let item = AstItem::Impl {
type_name: "MyStruct".to_string(),
trait_name: Some("Display".to_string()),
line: 40,
};
let result = format_impl_item(&item);
assert!(result.contains("impl Display for MyStruct"));
}
#[test]
fn test_format_impl_item_inherent() {
let item = AstItem::Impl {
type_name: "MyStruct".to_string(),
trait_name: None,
line: 45,
};
let result = format_impl_item(&item);
assert!(result.contains("impl MyStruct"));
assert!(!result.contains("for"));
}