#![allow(clippy::all, unused_variables)]
use std::path::PathBuf;
use wootype::salsa::*;
#[test]
fn test_basic_type_inference() {
let db = IncrementalDb::new();
let body = FunctionBody {
statements: vec![],
return_expr: Some(Expression::IntLiteral(42)),
};
db.set_function("test".to_string(), body);
let result = db.infer_function("test");
assert_eq!(result.return_type.to_string(), "int");
assert!(result.errors.is_empty());
}
#[test]
fn test_incremental_function_update() {
let db = IncrementalDb::new();
db.set_function(
"f1".to_string(),
FunctionBody {
statements: vec![],
return_expr: Some(Expression::IntLiteral(1)),
},
);
db.set_function(
"f2".to_string(),
FunctionBody {
statements: vec![],
return_expr: Some(Expression::StringLiteral("hello".to_string())),
},
);
let r1_v1 = db.infer_function("f1");
let r2_v1 = db.infer_function("f2");
assert_eq!(r1_v1.return_type.to_string(), "int");
assert_eq!(r2_v1.return_type.to_string(), "string");
db.set_function(
"f1".to_string(),
FunctionBody {
statements: vec![],
return_expr: Some(Expression::FloatLiteral(3.14)),
},
);
let r1_v2 = db.infer_function("f1");
assert_eq!(r1_v2.return_type.to_string(), "float64");
let r2_v2 = db.infer_function("f2");
assert_eq!(r2_v2.return_type.to_string(), "string");
}
#[test]
fn test_input_manager_incremental_update() {
let manager = InputManager::new();
let path = PathBuf::from("test.go");
let initial = r#"package main
func main() {
x := 42
println(x)
}
"#;
manager.set_file(path.clone(), initial.to_string());
let change = IncrementalChange {
file: path.clone(),
range: ChangeRange {
start_line: 3,
start_col: 9,
end_line: 3,
end_col: 11,
},
new_text: "100".to_string(),
};
manager.apply_change(change).unwrap();
let updated = manager.get_file(&path).unwrap();
assert!(updated.contains("x := 100"));
assert!(!updated.contains("x := 42"));
}
#[test]
fn test_type_error_detection() {
let db = IncrementalDb::new();
let body = FunctionBody {
statements: vec![],
return_expr: Some(Expression::BinaryOp(
BinaryOp::Add,
Box::new(Expression::StringLiteral("hello".to_string())),
Box::new(Expression::IntLiteral(42)),
)),
};
db.set_function("bad_add".to_string(), body);
let result = db.infer_function("bad_add");
assert!(!result.errors.is_empty(), "Should detect type error");
}
#[test]
fn test_arithmetic_type_promotion() {
let db = IncrementalDb::new();
let body = FunctionBody {
statements: vec![],
return_expr: Some(Expression::BinaryOp(
BinaryOp::Add,
Box::new(Expression::IntLiteral(1)),
Box::new(Expression::FloatLiteral(2.0)),
)),
};
db.set_function("test".to_string(), body);
let result = db.infer_function("test");
assert_eq!(result.return_type.to_string(), "float64");
}
#[test]
fn test_db_stats() {
let db = IncrementalDb::new();
let stats = db.stats();
assert_eq!(stats.cached_queries, 0);
assert_eq!(stats.tracked_functions, 0);
for i in 0..10 {
db.set_function(
format!("func{}", i),
FunctionBody {
statements: vec![],
return_expr: Some(Expression::IntLiteral(i as i64)),
},
);
}
for i in 0..10 {
let _ = db.infer_function(&format!("func{}", i));
}
let stats = db.stats();
assert_eq!(stats.tracked_functions, 10);
assert_eq!(stats.cached_queries, 10);
}
#[test]
fn benchmark_incremental_vs_cold() {
use std::time::Instant;
let db = IncrementalDb::new();
for i in 0..100 {
db.set_function(
format!("func{}", i),
FunctionBody {
statements: vec![Statement::VarDecl(
"x".to_string(),
Expression::IntLiteral(i as i64),
)],
return_expr: Some(Expression::BinaryOp(
BinaryOp::Add,
Box::new(Expression::Identifier("x".to_string())),
Box::new(Expression::IntLiteral(1)),
)),
},
);
}
let start = Instant::now();
for i in 0..100 {
let _ = db.infer_function(&format!("func{}", i));
}
let cold_time = start.elapsed();
db.set_function(
"func50".to_string(),
FunctionBody {
statements: vec![],
return_expr: Some(Expression::FloatLiteral(3.14)),
},
);
let start = Instant::now();
let _ = db.infer_function("func50");
let incremental_time = start.elapsed();
println!("Cold check (100 funcs): {:?}", cold_time);
println!("Incremental check (1 func): {:?}", incremental_time);
assert!(
incremental_time < cold_time,
"Incremental should be faster than cold check"
);
}