use mathhook_core::calculus::integrals::Integration;
use mathhook_core::{symbol, Expression};
#[test]
fn test_strategy_routes_to_basic_power_rule() {
let x = symbol!(x);
let expr = Expression::pow(Expression::symbol(x.clone()), Expression::integer(2));
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_strategy_routes_to_basic_constant() {
let x = symbol!(x);
let expr = Expression::integer(5);
let result = expr.integrate(x.clone(), 0);
if let Expression::Mul(factors) = result {
assert!(factors.iter().any(|f| matches!(f, Expression::Number(_))));
assert!(factors
.iter()
.any(|f| matches!(f, Expression::Symbol(s) if *s == x)));
} else {
panic!("Expected multiplication for constant integration");
}
}
#[test]
fn test_strategy_routes_to_registry_sin() {
let x = symbol!(x);
let expr = Expression::function("sin", vec![Expression::symbol(x.clone())]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_strategy_routes_to_registry_cos() {
let x = symbol!(x);
let expr = Expression::function("cos", vec![Expression::symbol(x.clone())]);
let result = expr.integrate(x, 0);
if let Expression::Function { name, .. } = result {
assert_eq!(name.as_ref(), "sin");
} else {
panic!("Expected sin function for cos integration");
}
}
#[test]
fn test_strategy_routes_to_registry_exp() {
let x = symbol!(x);
let expr = Expression::function("exp", vec![Expression::symbol(x.clone())]);
let result = expr.integrate(x, 0);
if let Expression::Function { name, .. } = result {
assert_eq!(name.as_ref(), "exp");
} else {
panic!("Expected exp function for exp integration");
}
}
#[test]
fn test_strategy_routes_to_by_parts_x_times_exp() {
let x = symbol!(x);
let expr = Expression::mul(vec![
Expression::symbol(x.clone()),
Expression::function("exp", vec![Expression::symbol(x.clone())]),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_strategy_routes_to_by_parts_x_times_sin() {
let x = symbol!(x);
let expr = Expression::mul(vec![
Expression::symbol(x.clone()),
Expression::function("sin", vec![Expression::symbol(x.clone())]),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_strategy_routes_to_basic_sum() {
let x = symbol!(x);
let expr = Expression::add(vec![Expression::symbol(x.clone()), Expression::integer(3)]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_strategy_routes_to_basic_product_with_constant() {
let x = symbol!(x);
let expr = Expression::mul(vec![Expression::integer(3), Expression::symbol(x.clone())]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_strategy_routes_to_basic_reciprocal() {
let x = symbol!(x);
let expr = Expression::pow(Expression::symbol(x.clone()), Expression::integer(-1));
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_strategy_symbolic_fallback_non_elementary() {
let x = symbol!(x);
let expr = Expression::function(
"exp",
vec![Expression::pow(
Expression::symbol(x.clone()),
Expression::integer(2),
)],
);
let result = expr.integrate(x, 0);
assert!(matches!(result, Expression::Calculus(_)));
}
#[test]
fn test_strategy_symbolic_fallback_unknown_function() {
let x = symbol!(x);
let expr = Expression::function("custom_fn", vec![Expression::symbol(x.clone())]);
let result = expr.integrate(x, 0);
assert!(matches!(result, Expression::Calculus(_)));
}
#[test]
fn test_strategy_handles_complex_product() {
let x = symbol!(x);
let expr = Expression::mul(vec![
Expression::symbol(x.clone()),
Expression::function("sin", vec![Expression::symbol(x.clone())]),
Expression::function("exp", vec![Expression::symbol(x.clone())]),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_strategy_handles_nested_functions() {
let x = symbol!(x);
let inner_sin = Expression::function("sin", vec![Expression::symbol(x.clone())]);
let expr = Expression::function("sin", vec![inner_sin]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_strategy_handles_division_by_variable_function() {
let x = symbol!(x);
let denominator = Expression::function("sin", vec![Expression::symbol(x.clone())]);
let expr = Expression::mul(vec![
Expression::integer(1),
Expression::pow(denominator, Expression::integer(-1)),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_regression_power_rule_x_squared() {
let x = symbol!(x);
let expr = Expression::pow(Expression::symbol(x.clone()), Expression::integer(2));
let result = expr.integrate(x.clone(), 0);
assert!(!result.is_zero());
let result_str = result.to_string();
assert!(result_str.contains("x") || result_str.contains(x.name()));
}
#[test]
fn test_regression_power_rule_x_cubed() {
let x = symbol!(x);
let expr = Expression::pow(Expression::symbol(x.clone()), Expression::integer(3));
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_regression_constant_multiple() {
let x = symbol!(x);
let expr = Expression::mul(vec![
Expression::integer(5),
Expression::pow(Expression::symbol(x.clone()), Expression::integer(2)),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_regression_sum_of_terms() {
let x = symbol!(x);
let expr = Expression::add(vec![
Expression::pow(Expression::symbol(x.clone()), Expression::integer(2)),
Expression::symbol(x.clone()),
Expression::integer(1),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_regression_sin_function() {
let x = symbol!(x);
let expr = Expression::function("sin", vec![Expression::symbol(x.clone())]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_layer_interaction_registry_then_basic() {
let x = symbol!(x);
let y = symbol!(y);
let expr = Expression::mul(vec![
Expression::symbol(y.clone()),
Expression::symbol(x.clone()),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_layer_interaction_product_of_functions() {
let x = symbol!(x);
let expr = Expression::mul(vec![
Expression::function("sin", vec![Expression::symbol(x.clone())]),
Expression::function("cos", vec![Expression::symbol(x.clone())]),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_layer_interaction_linear_substitution() {
let x = symbol!(x);
let inner = Expression::mul(vec![Expression::integer(2), Expression::symbol(x.clone())]);
let expr = Expression::function("sin", vec![inner]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_layer_interaction_sum_of_functions() {
let x = symbol!(x);
let expr = Expression::add(vec![
Expression::function("sin", vec![Expression::symbol(x.clone())]),
Expression::function("cos", vec![Expression::symbol(x.clone())]),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}
#[test]
fn test_layer_interaction_constant_times_function() {
let x = symbol!(x);
let expr = Expression::mul(vec![
Expression::integer(3),
Expression::function("sin", vec![Expression::symbol(x.clone())]),
]);
let result = expr.integrate(x, 0);
assert!(!result.is_zero());
}