#![allow(dead_code)]
use scry_learn::dataset::Dataset;
use scry_learn::error::ScryLearnError;
fn empty_dataset() -> Dataset {
Dataset::new(Vec::new(), Vec::new(), Vec::new(), "t")
}
fn single_sample_clf() -> Dataset {
Dataset::new(vec![vec![1.0]], vec![0.0], vec!["f".into()], "t")
}
fn single_feature_clf() -> Dataset {
Dataset::new(
vec![vec![1.0, 2.0, 3.0, 4.0]],
vec![0.0, 1.0, 0.0, 1.0],
vec!["f".into()],
"t",
)
}
fn all_same_class() -> Dataset {
Dataset::new(
vec![vec![1.0, 2.0, 3.0, 4.0, 5.0], vec![5.0, 4.0, 3.0, 2.0, 1.0]],
vec![0.0, 0.0, 0.0, 0.0, 0.0],
vec!["f1".into(), "f2".into()],
"t",
)
}
fn nan_dataset() -> Dataset {
Dataset::new(
vec![vec![1.0, f64::NAN, 3.0], vec![4.0, 5.0, f64::NAN]],
vec![0.0, 1.0, 0.0],
vec!["f1".into(), "f2".into()],
"t",
)
}
fn inf_dataset() -> Dataset {
Dataset::new(
vec![
vec![1.0, f64::INFINITY, 3.0],
vec![4.0, f64::NEG_INFINITY, 6.0],
],
vec![0.0, 1.0, 0.0],
vec!["f1".into(), "f2".into()],
"t",
)
}
fn extreme_scale_dataset() -> Dataset {
Dataset::new(
vec![vec![1e-10, 1e10, 0.0, 1.0], vec![1e10, 1e-10, 1.0, 0.0]],
vec![0.0, 1.0, 0.0, 1.0],
vec!["f1".into(), "f2".into()],
"t",
)
}
fn regression_dataset() -> Dataset {
Dataset::new(
vec![vec![1.0, 2.0, 3.0, 4.0], vec![5.0, 6.0, 7.0, 8.0]],
vec![1.5, 2.5, 3.5, 4.5],
vec!["f1".into(), "f2".into()],
"t",
)
}
fn empty_regression() -> Dataset {
Dataset::new(Vec::new(), Vec::new(), Vec::new(), "t")
}
#[test]
fn linreg_empty() {
let data = empty_regression();
let mut model = scry_learn::linear::LinearRegression::new();
let result = model.fit(&data);
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), ScryLearnError::EmptyDataset));
}
#[test]
fn linreg_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::linear::LinearRegression::new();
let _result = model.fit(&data);
}
#[test]
fn linreg_extreme_scales() {
let data = Dataset::new(
vec![vec![1e-10, 1e10, 1.0, 0.5]],
vec![1.0, 2.0, 3.0, 4.0],
vec!["f".into()],
"t",
);
let mut model = scry_learn::linear::LinearRegression::new();
let _ = model.fit(&data); }
#[test]
fn logreg_empty() {
let data = empty_dataset();
let mut model = scry_learn::linear::LogisticRegression::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn logreg_single_sample() {
let data = single_sample_clf();
let mut model = scry_learn::linear::LogisticRegression::new().max_iter(10);
let _ = model.fit(&data); }
#[test]
fn logreg_all_same_class() {
let data = all_same_class();
let mut model = scry_learn::linear::LogisticRegression::new().max_iter(50);
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn logreg_extreme_scales() {
let data = extreme_scale_dataset();
let mut model = scry_learn::linear::LogisticRegression::new().max_iter(50);
let _ = model.fit(&data); }
#[test]
fn lasso_empty() {
let data = empty_regression();
let mut model = scry_learn::linear::LassoRegression::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn lasso_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::linear::LassoRegression::new();
let _ = model.fit(&data);
}
#[test]
fn elasticnet_empty() {
let data = empty_regression();
let mut model = scry_learn::linear::ElasticNet::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn elasticnet_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::linear::ElasticNet::new();
let _ = model.fit(&data);
}
#[test]
fn dtc_empty() {
let data = empty_dataset();
let mut model = scry_learn::tree::DecisionTreeClassifier::new();
let result = model.fit(&data);
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), ScryLearnError::EmptyDataset));
}
#[test]
fn dtc_single_sample() {
let data = single_sample_clf();
let mut model = scry_learn::tree::DecisionTreeClassifier::new();
model.fit(&data).unwrap();
let preds = model.predict(&[vec![1.0]]).unwrap();
assert_eq!(preds.len(), 1);
}
#[test]
fn dtc_single_feature() {
let data = single_feature_clf();
let mut model = scry_learn::tree::DecisionTreeClassifier::new();
model.fit(&data).unwrap();
let preds = model.predict(&data.feature_matrix()).unwrap();
assert_eq!(preds.len(), 4);
}
#[test]
fn dtc_all_same_class() {
let data = all_same_class();
let mut model = scry_learn::tree::DecisionTreeClassifier::new();
model.fit(&data).unwrap();
let preds = model.predict(&data.feature_matrix()).unwrap();
for p in &preds {
assert!((*p - 0.0).abs() < 0.5, "Expected class 0, got {p}");
}
}
#[test]
fn dtr_empty() {
let data = empty_regression();
let mut model = scry_learn::tree::DecisionTreeRegressor::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn dtr_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::tree::DecisionTreeRegressor::new();
model.fit(&data).unwrap();
let preds = model.predict(&[vec![1.0]]).unwrap();
assert!((preds[0] - 5.0).abs() < 1e-6);
}
#[test]
fn rfc_empty() {
let data = empty_dataset();
let mut model = scry_learn::tree::RandomForestClassifier::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn rfc_single_sample() {
let data = single_sample_clf();
let mut model = scry_learn::tree::RandomForestClassifier::new().n_estimators(3);
let _ = model.fit(&data); }
#[test]
fn rfc_all_same_class() {
let data = all_same_class();
let mut model = scry_learn::tree::RandomForestClassifier::new()
.n_estimators(5)
.seed(42);
model.fit(&data).unwrap();
let preds = model.predict(&data.feature_matrix()).unwrap();
for p in &preds {
assert!((*p - 0.0).abs() < 0.5, "Expected class 0, got {p}");
}
}
#[test]
fn rfr_empty() {
let data = empty_regression();
let mut model = scry_learn::tree::RandomForestRegressor::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn rfr_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::tree::RandomForestRegressor::new().n_estimators(3);
let _ = model.fit(&data);
}
#[test]
fn gbc_empty() {
let data = empty_dataset();
let mut model = scry_learn::tree::GradientBoostingClassifier::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn gbc_all_same_class() {
let data = all_same_class();
let mut model = scry_learn::tree::GradientBoostingClassifier::new()
.n_estimators(5)
.max_depth(2);
let result = model.fit(&data);
assert!(result.is_err(), "GBC should reject single-class data");
}
#[test]
fn gbr_empty() {
let data = empty_regression();
let mut model = scry_learn::tree::GradientBoostingRegressor::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn gbr_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::tree::GradientBoostingRegressor::new().n_estimators(3);
let _ = model.fit(&data);
}
#[test]
fn histgbc_empty() {
let data = empty_dataset();
let mut model = scry_learn::tree::HistGradientBoostingClassifier::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn histgbc_single_feature() {
let data = single_feature_clf();
let mut model = scry_learn::tree::HistGradientBoostingClassifier::new()
.n_estimators(5)
.max_depth(3);
let _ = model.fit(&data); }
#[test]
fn histgbr_empty() {
let data = empty_regression();
let mut model = scry_learn::tree::HistGradientBoostingRegressor::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn histgbr_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::tree::HistGradientBoostingRegressor::new().n_estimators(3);
let _ = model.fit(&data);
}
#[test]
fn knnc_empty() {
let data = empty_dataset();
let mut model = scry_learn::neighbors::KnnClassifier::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn knnc_single_sample() {
let data = single_sample_clf();
let mut model = scry_learn::neighbors::KnnClassifier::new().k(1);
model.fit(&data).unwrap();
let preds = model.predict(&[vec![1.0]]).unwrap();
assert_eq!(preds.len(), 1);
}
#[test]
fn knnc_all_same_class() {
let data = all_same_class();
let mut model = scry_learn::neighbors::KnnClassifier::new().k(3);
model.fit(&data).unwrap();
let preds = model.predict(&data.feature_matrix()).unwrap();
for p in &preds {
assert!((*p - 0.0).abs() < 0.5, "Expected class 0, got {p}");
}
}
#[test]
fn knnr_empty() {
let data = empty_regression();
let mut model = scry_learn::neighbors::KnnRegressor::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn knnr_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::neighbors::KnnRegressor::new().k(1);
model.fit(&data).unwrap();
let preds = model.predict(&[vec![1.0]]).unwrap();
assert!((preds[0] - 5.0).abs() < 1e-6);
}
#[test]
fn linearsvc_empty() {
let data = empty_dataset();
let mut model = scry_learn::svm::LinearSVC::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn linearsvc_single_sample() {
let data = single_sample_clf();
let mut model = scry_learn::svm::LinearSVC::new().max_iter(10);
let _ = model.fit(&data); }
#[test]
fn linearsvr_empty() {
let data = empty_regression();
let mut model = scry_learn::svm::LinearSVR::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn linearsvr_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::svm::LinearSVR::new().max_iter(10);
let _ = model.fit(&data);
}
#[cfg(feature = "experimental")]
#[test]
fn kernelsvc_empty() {
let data = empty_dataset();
let mut model = scry_learn::svm::KernelSVC::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[cfg(feature = "experimental")]
#[test]
fn kernelsvc_single_sample() {
let data = single_sample_clf();
let mut model = scry_learn::svm::KernelSVC::new().max_iter(10);
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
let _ = model.fit(&data);
}));
let _ = result;
}
#[test]
fn gaussiannb_empty() {
let data = empty_dataset();
let mut model = scry_learn::naive_bayes::GaussianNb::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn gaussiannb_single_sample() {
let data = single_sample_clf();
let mut model = scry_learn::naive_bayes::GaussianNb::new();
let _ = model.fit(&data); }
#[test]
fn gaussiannb_all_same_class() {
let data = all_same_class();
let mut model = scry_learn::naive_bayes::GaussianNb::new();
model.fit(&data).unwrap();
let preds = model.predict(&data.feature_matrix()).unwrap();
for p in &preds {
assert!((*p - 0.0).abs() < 0.5, "Expected class 0, got {p}");
}
}
#[test]
fn bernoullinb_empty() {
let data = empty_dataset();
let mut model = scry_learn::naive_bayes::BernoulliNB::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn bernoullinb_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![0.0], vec!["f".into()], "t");
let mut model = scry_learn::naive_bayes::BernoulliNB::new();
let _ = model.fit(&data);
}
#[test]
fn multinomialnb_empty() {
let data = empty_dataset();
let mut model = scry_learn::naive_bayes::MultinomialNB::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn multinomialnb_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![0.0], vec!["f".into()], "t");
let mut model = scry_learn::naive_bayes::MultinomialNB::new();
let _ = model.fit(&data);
}
#[test]
fn kmeans_empty() {
let data = empty_dataset();
let mut model = scry_learn::cluster::KMeans::new(3);
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn kmeans_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![0.0], vec!["f".into()], "t");
let mut model = scry_learn::cluster::KMeans::new(1).max_iter(10);
let _ = model.fit(&data);
}
#[test]
fn mini_batch_kmeans_empty() {
let data = empty_dataset();
let mut model = scry_learn::cluster::MiniBatchKMeans::new(3);
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn dbscan_empty() {
let data = empty_dataset();
let mut model = scry_learn::cluster::Dbscan::new(0.5, 2);
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn dbscan_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![0.0], vec!["f".into()], "t");
let mut model = scry_learn::cluster::Dbscan::new(0.5, 2);
let _ = model.fit(&data); }
#[test]
fn extreme_scale_dtc() {
let data = extreme_scale_dataset();
let mut model = scry_learn::tree::DecisionTreeClassifier::new().max_depth(3);
model.fit(&data).unwrap();
let _ = model.predict(&data.feature_matrix()).unwrap();
}
#[test]
fn extreme_scale_rfc() {
let data = extreme_scale_dataset();
let mut model = scry_learn::tree::RandomForestClassifier::new()
.n_estimators(3)
.seed(42)
.max_depth(3);
model.fit(&data).unwrap();
let _ = model.predict(&data.feature_matrix()).unwrap();
}
#[test]
fn extreme_scale_knn() {
let data = extreme_scale_dataset();
let mut model = scry_learn::neighbors::KnnClassifier::new().k(2);
model.fit(&data).unwrap();
let _ = model.predict(&data.feature_matrix()).unwrap();
}
#[test]
fn extreme_scale_gaussiannb() {
let data = extreme_scale_dataset();
let mut model = scry_learn::naive_bayes::GaussianNb::new();
model.fit(&data).unwrap();
let _ = model.predict(&data.feature_matrix()).unwrap();
}
#[test]
fn nan_linreg_no_panic() {
let data = nan_dataset();
let mut model = scry_learn::linear::LinearRegression::new();
let _ = model.fit(&data); }
#[test]
fn inf_linreg_no_panic() {
let data = inf_dataset();
let mut model = scry_learn::linear::LinearRegression::new();
let _ = model.fit(&data);
}
#[test]
fn nan_logreg_no_panic() {
let data = nan_dataset();
let mut model = scry_learn::linear::LogisticRegression::new().max_iter(10);
let _ = model.fit(&data);
}
#[test]
fn nan_dtc_no_panic() {
let data = nan_dataset();
let mut model = scry_learn::tree::DecisionTreeClassifier::new().max_depth(3);
let _ = model.fit(&data);
}
#[test]
fn nan_knn_no_panic() {
let data = nan_dataset();
let mut model = scry_learn::neighbors::KnnClassifier::new().k(1);
let err = model.fit(&data).unwrap_err();
assert!(matches!(
err,
scry_learn::error::ScryLearnError::InvalidData(_)
));
}
#[test]
fn nan_kmeans_no_panic() {
let data = nan_dataset();
let mut model = scry_learn::cluster::KMeans::new(2)
.max_iter(5)
.n_init(1)
.seed(42);
let _ = model.fit(&data);
}
#[test]
fn not_fitted_linreg() {
let model = scry_learn::linear::LinearRegression::new();
let result = model.predict(&[vec![1.0]]);
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), ScryLearnError::NotFitted));
}
#[test]
fn not_fitted_logreg() {
let model = scry_learn::linear::LogisticRegression::new();
let result = model.predict(&[vec![1.0]]);
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), ScryLearnError::NotFitted));
}
#[test]
fn not_fitted_dtc() {
let model = scry_learn::tree::DecisionTreeClassifier::new();
let result = model.predict(&[vec![1.0]]);
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), ScryLearnError::NotFitted));
}
#[test]
fn not_fitted_knn() {
let model = scry_learn::neighbors::KnnClassifier::new();
let result = model.predict(&[vec![1.0]]);
assert!(result.is_err());
}
#[test]
fn mlp_empty() {
let data = empty_dataset();
let mut model = scry_learn::neural::MLPClassifier::new()
.hidden_layers(&[4])
.max_iter(5);
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn mlp_single_sample() {
let data = single_sample_clf();
let mut model = scry_learn::neural::MLPClassifier::new()
.hidden_layers(&[4])
.max_iter(5)
.seed(42);
let _ = model.fit(&data); }
#[test]
fn mlp_extreme_scales() {
let data = extreme_scale_dataset();
let mut model = scry_learn::neural::MLPClassifier::new()
.hidden_layers(&[4])
.max_iter(5)
.learning_rate(0.001)
.seed(42);
let _ = model.fit(&data); }
#[test]
fn mlp_regressor_empty() {
let data = empty_regression();
let mut model = scry_learn::neural::MLPRegressor::new()
.hidden_layers(&[4])
.max_iter(5);
let result = model.fit(&data);
assert!(result.is_err());
}
#[test]
fn mlp_regressor_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::neural::MLPRegressor::new()
.hidden_layers(&[4])
.max_iter(5)
.seed(42);
let _ = model.fit(&data); }
#[test]
fn iforest_empty() {
let features: Vec<Vec<f64>> = Vec::new();
let mut model = scry_learn::anomaly::IsolationForest::new();
let result = model.fit(&features);
assert!(result.is_err());
}
#[test]
fn iforest_single_sample() {
let features = vec![vec![1.0]];
let mut model = scry_learn::anomaly::IsolationForest::new().n_estimators(5);
let _ = model.fit(&features); }
#[test]
fn iforest_extreme_scales() {
let features = vec![vec![1e-10, 1e10, 0.0, 1.0], vec![1e10, 1e-10, 1.0, 0.0]];
let mut model = scry_learn::anomaly::IsolationForest::new().n_estimators(5);
let _ = model.fit(&features); }
#[cfg(feature = "experimental")]
#[test]
fn kernel_svr_empty() {
let data = empty_regression();
let mut model = scry_learn::svm::KernelSVR::new();
let result = model.fit(&data);
assert!(result.is_err());
}
#[cfg(feature = "experimental")]
#[test]
fn kernel_svr_single_sample() {
let data = Dataset::new(vec![vec![1.0]], vec![5.0], vec!["f".into()], "t");
let mut model = scry_learn::svm::KernelSVR::new().max_iter(10);
let _ = model.fit(&data); }
#[test]
fn dimension_mismatch_dt() {
let data = Dataset::new(
vec![vec![1.0, 2.0, 3.0, 4.0], vec![5.0, 6.0, 7.0, 8.0]],
vec![0.0, 1.0, 0.0, 1.0],
vec!["f1".into(), "f2".into()],
"t",
);
let mut model = scry_learn::tree::DecisionTreeClassifier::new();
model.fit(&data).unwrap();
let result = model.predict(&[vec![1.0, 2.0, 3.0]]);
let _ = result;
}
#[test]
fn dimension_mismatch_knn() {
let data = Dataset::new(
vec![vec![1.0, 2.0, 3.0, 4.0], vec![5.0, 6.0, 7.0, 8.0]],
vec![0.0, 1.0, 0.0, 1.0],
vec!["f1".into(), "f2".into()],
"t",
);
let mut model = scry_learn::neighbors::KnnClassifier::new().k(2);
model.fit(&data).unwrap();
let result = model.predict(&[vec![1.0]]);
let _ = result;
}