use selen::prelude::*;
use selen::core::SolverError;
#[test]
fn test_neq_constraint_basic() {
let mut m = Model::default();
let x = m.int(1, 5);
let y = m.int(1, 5);
m.new(x.ne(y));
let solution = m.solve().expect("Should find solution");
assert_ne!(solution[x], solution[y]);
}
#[test]
fn test_neq_constraint_assigned_values() {
let mut m = Model::default();
let x = m.int(3, 3); let y = m.int(1, 5);
m.new(x.ne(y));
let solution = m.solve().expect("Should find solution");
assert_eq!(solution[x].as_int(), Some(3));
assert_ne!(solution[y].as_int(), Some(3));
}
#[test]
fn test_neq_constraint_both_assigned_equal() {
let mut m = Model::default();
let x = m.int(3, 3); let y = m.int(3, 3);
m.new(x.ne(y));
let result = m.solve();
assert!(matches!(result, Err(SolverError::NoSolution { .. })));
}
#[test]
fn test_neq_constraint_non_overlapping_domains() {
let mut m = Model::default();
let x = m.int(1, 3);
let y = m.int(5, 7);
m.new(x.ne(y));
let solution = m.solve().expect("Should find solution");
assert_ne!(solution[x], solution[y]);
}
#[test]
fn test_neq_float_assigned() {
let mut m = Model::default();
let x = m.float(2.5, 2.5); let y = m.float(1.0, 5.0);
m.new(x.ne(y));
let solution = m.solve().expect("Should find solution");
let x_val = solution[x].as_float().expect("x should be float");
let y_val = solution[y].as_float().expect("y should be float");
assert!((x_val - 2.5).abs() < 1e-5);
assert!((y_val - 2.5).abs() > 1e-5);
}
#[test]
fn test_error_no_solution_display() {
let err = SolverError::NoSolution {
context: Some("test context".to_string()),
variable_count: Some(10),
constraint_count: Some(5),
};
let display = format!("{}", err);
assert!(display.contains("No solution"));
}
#[test]
fn test_error_timeout_display() {
let err = SolverError::Timeout {
elapsed_seconds: Some(5.5),
operation: Some("solving".to_string()),
};
let display = format!("{}", err);
assert!(display.contains("timed out"));
}
#[test]
fn test_error_invalid_constraint_display() {
let err = SolverError::InvalidConstraint {
message: "Mismatched lengths".to_string(),
constraint_name: Some("lin_eq".to_string()),
variables: Some(vec!["x".to_string(), "y".to_string()]),
};
let display = format!("{}", err);
assert!(display.contains("Invalid constraint"));
}
#[test]
fn test_error_equality() {
let err1 = SolverError::NoSolution {
context: Some("test".to_string()),
variable_count: Some(5),
constraint_count: Some(3),
};
let err2 = SolverError::NoSolution {
context: Some("test".to_string()),
variable_count: Some(5),
constraint_count: Some(3),
};
let err3 = SolverError::Timeout {
elapsed_seconds: Some(1.0),
operation: None,
};
assert_eq!(err1, err2);
assert_ne!(err1, err3);
}
#[test]
fn test_error_clone() {
let err = SolverError::MemoryLimit {
usage_mb: Some(1024),
limit_mb: Some(512),
};
let cloned = err.clone();
assert_eq!(err, cloned);
}