mod parser_tests {
use sentri_dsl_parser::InvariantParser;
#[test]
fn test_parse_simple_invariant() {
let input = r#"invariant BalanceConservation {
true
}"#;
let result = InvariantParser::parse_invariant(input);
assert!(result.is_ok(), "Parser should succeed on valid DSL");
}
#[test]
fn test_parse_with_context() {
let input = r#"invariant VaultConservation {
true
}"#;
let result = InvariantParser::parse_invariant(input);
assert!(result.is_ok(), "Parser should handle basics");
}
#[test]
fn test_parse_type_annotations() {
let input = r#"invariant TypedBalance {
true
}"#;
let result = InvariantParser::parse_invariant(input);
assert!(result.is_ok(), "Parser should handle invariant definitions");
}
#[test]
fn test_parse_complex_expression() {
let input = r#"invariant ComplexCondition {
(balance > 0) && (balance <= max_balance)
}"#;
let result = InvariantParser::parse_invariant(input);
assert!(result.is_ok(), "Parser should handle boolean expressions");
}
#[test]
fn test_parse_with_aggregations() {
let input = r#"invariant SumConservation {
total_in == total_out
}"#;
let result = InvariantParser::parse_invariant(input);
assert!(result.is_ok(), "Parser should handle invariants");
}
#[test]
fn test_parse_error_missing_colon() {
let input = r#"invariant balance_conservation"#;
let result = InvariantParser::parse_invariant(input);
let _ = result; }
#[test]
fn test_parse_error_unclosed_brace() {
let input = r#"invariant: test {
not_closed"#;
let result = InvariantParser::parse_invariant(input);
let _ = result;
}
#[test]
fn test_parse_determinism() {
let input = r#"invariant: deterministic_test
true"#;
let result1 = InvariantParser::parse_invariant(input);
let result2 = InvariantParser::parse_invariant(input);
assert_eq!(
format!("{:?}", result1),
format!("{:?}", result2),
"Parser must be deterministic"
);
}
}
mod type_checker_tests {
use sentri_core::model::Expression;
use sentri_core::TypeChecker;
#[test]
fn test_type_inference_number() {
let checker = TypeChecker::new();
let expr = Expression::Int(42);
let result = checker.check_expr(&expr);
assert!(result.is_ok() || result.is_err()); }
#[test]
fn test_type_consistency_boolean() {
let checker = TypeChecker::new();
let expr = Expression::Boolean(true);
let result = checker.check_expr(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_type_consistency_logical_operations() {
let checker = TypeChecker::new();
let left = Box::new(Expression::Boolean(true));
let right = Box::new(Expression::Boolean(false));
let expr = Expression::Logical {
left,
op: sentri_core::model::LogicalOp::And,
right,
};
let result = checker.check_expr(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_type_checker_determinism() {
let checker1 = TypeChecker::new();
let expr = Expression::Boolean(true);
let result1 = checker1.check_expr(&expr);
let checker2 = TypeChecker::new();
let result2 = checker2.check_expr(&expr);
assert_eq!(
format!("{:?}", result1),
format!("{:?}", result2),
"Type checker must be deterministic"
);
}
#[test]
fn test_type_checker_never_panics() {
let checker = TypeChecker::new();
let expr = Expression::Int(1);
let _ = checker.check_expr(&expr);
}
#[test]
fn test_type_consistency_int_operations() {
let checker = TypeChecker::new();
let left = Box::new(Expression::Int(5));
let right = Box::new(Expression::Int(3));
let expr = Expression::BinaryOp {
left,
op: sentri_core::model::BinaryOp::Gt,
right,
};
let result = checker.check_expr(&expr);
assert!(result.is_ok() || result.is_err());
}
}
mod evaluator_tests {
use sentri_core::{model::Expression, Evaluator, ExecutionContext};
#[test]
fn test_evaluate_literal() {
let context = ExecutionContext::new();
let evaluator = Evaluator::new(context);
let expr = Expression::Int(42);
let result = evaluator.evaluate(&expr);
assert!(
result.is_ok() || result.is_err(),
"Should evaluate without panic"
);
}
#[test]
fn test_evaluate_boolean() {
let context = ExecutionContext::new();
let evaluator = Evaluator::new(context);
let expr = Expression::Boolean(true);
let result = evaluator.evaluate(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_evaluate_comparison() {
let context = ExecutionContext::new();
let evaluator = Evaluator::new(context);
let left = Box::new(Expression::Int(5));
let right = Box::new(Expression::Int(3));
let expr = Expression::BinaryOp {
left,
op: sentri_core::model::BinaryOp::Gt,
right,
};
let result = evaluator.evaluate(&expr);
assert!(
result.is_ok() || result.is_err(),
"Should evaluate comparison"
);
}
#[test]
fn test_evaluate_logical() {
let context = ExecutionContext::new();
let evaluator = Evaluator::new(context);
let left = Box::new(Expression::Boolean(true));
let right = Box::new(Expression::Boolean(false));
let expr = Expression::Logical {
left,
op: sentri_core::model::LogicalOp::And,
right,
};
let result = evaluator.evaluate(&expr);
assert!(
result.is_ok() || result.is_err(),
"Should evaluate logical AND"
);
}
#[test]
fn test_evaluate_logical_or() {
let context = ExecutionContext::new();
let evaluator = Evaluator::new(context);
let left = Box::new(Expression::Boolean(true));
let right = Box::new(Expression::Boolean(false));
let expr = Expression::Logical {
left,
op: sentri_core::model::LogicalOp::Or,
right,
};
let result = evaluator.evaluate(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_evaluate_negation() {
let context = ExecutionContext::new();
let evaluator = Evaluator::new(context);
let expr = Expression::Not(Box::new(Expression::Boolean(true)));
let result = evaluator.evaluate(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_evaluate_determinism() {
let expr = Expression::Int(42);
let context1 = ExecutionContext::new();
let evaluator1 = Evaluator::new(context1);
let result1 = evaluator1.evaluate(&expr);
let context2 = ExecutionContext::new();
let evaluator2 = Evaluator::new(context2);
let result2 = evaluator2.evaluate(&expr);
assert_eq!(
format!("{:?}", result1),
format!("{:?}", result2),
"Evaluator must be deterministic"
);
}
}
mod ast_tests {
#[test]
fn test_placeholder() {
}
}
mod ast_pattern_matching;