use batless::ast_summarizer::AstSummarizer;
use batless::summary::SummaryLevel;
#[test]
fn test_python_ast_basic_summary() {
let code = r#"
import os
import sys
def main():
print("Hello")
class User:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, {self.name}"
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Standard);
println!("Summary: {:?}", summary);
assert!(summary.iter().any(|l| l.line.contains("def main")));
assert!(summary.iter().any(|l| l.line.contains("def __init__")));
assert!(summary.iter().any(|l| l.line.contains("def greet")));
assert!(summary.iter().any(|l| l.line.contains("class User")));
assert!(summary.iter().any(|l| l.line.contains("import os")));
assert!(summary.iter().any(|l| l.line.contains("import sys")));
assert!(!summary.iter().any(|l| l.line.contains("print(\"Hello\")")));
assert!(!summary.iter().any(|l| l.line.contains("self.name = name")));
}
#[test]
fn test_python_ast_minimal_level() {
let code = r#"
import os
def hello():
pass
class World:
pass
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Minimal);
assert!(summary.iter().any(|l| l.line.contains("def hello")));
assert!(summary.iter().any(|l| l.line.contains("class World")));
assert!(!summary.iter().any(|l| l.line.contains("import os")));
}
#[test]
fn test_python_ast_decorators() {
let code = r#"
@staticmethod
def static_method():
pass
@classmethod
def class_method(cls):
pass
@property
def my_property(self):
return self._value
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Standard);
println!("Decorator summary: {:?}", summary);
assert!(summary.iter().any(|l| l.line.contains("@staticmethod")));
assert!(summary.iter().any(|l| l.line.contains("@classmethod")));
assert!(summary.iter().any(|l| l.line.contains("@property")));
}
#[test]
fn test_python_ast_async_functions() {
let code = r#"
async def fetch_data():
await get_data()
async def process():
result = await fetch_data()
return result
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Standard);
println!("Async summary: {:?}", summary);
assert!(summary
.iter()
.any(|l| l.line.contains("async def fetch_data")));
assert!(summary.iter().any(|l| l.line.contains("async def process")));
assert!(!summary.iter().any(|l| l.line.contains("await get_data()")));
}
#[test]
fn test_python_ast_from_imports() {
let code = r#"
from os import path
from typing import List, Dict, Optional
from .models import User, Post
def process_user(user: User) -> Dict:
return user.to_dict()
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Standard);
println!("From import summary: {:?}", summary);
assert!(summary.iter().any(|l| l.line.contains("from os import")));
assert!(summary
.iter()
.any(|l| l.line.contains("from typing import")));
assert!(summary
.iter()
.any(|l| l.line.contains("from .models import")));
assert!(summary.iter().any(|l| l.line.contains("def process_user")));
}
#[test]
fn test_python_ast_nested_classes() {
let code = r#"
class Outer:
class Inner:
def inner_method(self):
pass
def outer_method(self):
pass
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Standard);
println!("Nested class summary: {:?}", summary);
assert!(summary.iter().any(|l| l.line.contains("class Outer")));
assert!(summary.iter().any(|l| l.line.contains("class Inner")));
assert!(summary.iter().any(|l| l.line.contains("def inner_method")));
assert!(summary.iter().any(|l| l.line.contains("def outer_method")));
}
#[test]
fn test_python_ast_lambda_ignored() {
let code = r#"
def regular_function():
mapper = lambda x: x * 2
return mapper
square = lambda x: x ** 2
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Standard);
assert!(summary
.iter()
.any(|l| l.line.contains("def regular_function")));
}
#[test]
fn test_python_ast_empty_file() {
let code = "";
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Standard);
assert!(summary.is_empty());
}
#[test]
fn test_python_ast_comments_ignored() {
let code = r#"
# This is a comment
def my_function():
# Another comment
pass
"""
This is a docstring
"""
class MyClass:
"""Class docstring"""
pass
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Standard);
assert!(summary.iter().any(|l| l.line.contains("def my_function")));
assert!(summary.iter().any(|l| l.line.contains("class MyClass")));
}
#[test]
fn test_python_ast_detailed_level() {
let code = r#"
import os
MAX_SIZE = 1000
def process():
global MAX_SIZE
local_var = 42
return local_var
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Detailed);
println!("Detailed summary: {:?}", summary);
assert!(summary.iter().any(|l| l.line.contains("import os")));
assert!(summary.iter().any(|l| l.line.contains("MAX_SIZE")));
assert!(summary.iter().any(|l| l.line.contains("def process")));
assert!(summary.iter().any(|l| l.line.contains("global MAX_SIZE")));
}
#[test]
fn test_python_ast_none_level() {
let code = r#"
def my_function():
pass
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::None);
assert!(summary.is_empty());
}
#[test]
fn test_python_ast_complex_decorators() {
let code = r#"
@app.route('/api/users')
@login_required
@cache(timeout=300)
def get_users():
return User.query.all()
@dataclass
@frozen
class Config:
debug: bool
port: int
"#;
let summary = AstSummarizer::extract_summary(code, Some("Python"), SummaryLevel::Standard);
println!("Complex decorator summary: {:?}", summary);
assert!(summary.iter().any(|l| l.line.contains("@app.route")));
assert!(summary.iter().any(|l| l.line.contains("def get_users")));
assert!(summary.iter().any(|l| l.line.contains("@dataclass")));
assert!(summary.iter().any(|l| l.line.contains("class Config")));
}