pub(crate) use super::*;
#[test]
fn test_apriori_new() {
let apriori = Apriori::new();
assert_eq!(apriori.min_support, 0.1);
assert_eq!(apriori.min_confidence, 0.5);
assert_eq!(apriori.frequent_itemsets.len(), 0);
assert_eq!(apriori.rules.len(), 0);
}
#[test]
fn test_apriori_with_min_support() {
let apriori = Apriori::new().with_min_support(0.3);
assert_eq!(apriori.min_support, 0.3);
}
#[test]
fn test_apriori_with_min_confidence() {
let apriori = Apriori::new().with_min_confidence(0.7);
assert_eq!(apriori.min_confidence, 0.7);
}
#[test]
fn test_apriori_fit_basic() {
let transactions = vec![
vec![1, 2, 3], vec![1, 2], vec![1, 3], vec![2, 3], vec![1, 2, 3, 4], ];
let mut apriori = Apriori::new()
.with_min_support(0.4) .with_min_confidence(0.6);
apriori.fit(&transactions);
assert!(!apriori.frequent_itemsets.is_empty());
}
#[test]
fn test_frequent_itemsets() {
let transactions = vec![vec![1, 2, 3], vec![1, 2], vec![1, 3], vec![2, 3]];
let mut apriori = Apriori::new().with_min_support(0.5); apriori.fit(&transactions);
let itemsets = apriori.get_frequent_itemsets();
assert!(itemsets.len() >= 6);
for i in 1..itemsets.len() {
assert!(itemsets[i - 1].1 >= itemsets[i].1);
}
}
#[test]
fn test_association_rules() {
let transactions = vec![vec![1, 2, 3], vec![1, 2], vec![1, 3], vec![2, 3]];
let mut apriori = Apriori::new()
.with_min_support(0.5)
.with_min_confidence(0.6);
apriori.fit(&transactions);
let rules = apriori.get_rules();
assert!(!rules.is_empty());
for rule in &rules {
assert!(rule.confidence >= 0.6);
}
for i in 1..rules.len() {
assert!(rules[i - 1].confidence >= rules[i].confidence);
}
}
#[test]
fn test_support_calculation() {
let transactions = vec![vec![1, 2, 3], vec![1, 2], vec![1, 3], vec![2, 3]];
let itemset: HashSet<usize> = vec![1, 2].into_iter().collect();
let support = Apriori::calculate_support(&itemset, &transactions);
assert!((support - 0.5).abs() < 1e-10);
let itemset: HashSet<usize> = vec![1].into_iter().collect();
let support = Apriori::calculate_support(&itemset, &transactions);
assert!((support - 0.75).abs() < 1e-10);
}
#[test]
fn test_confidence_calculation() {
let transactions = vec![vec![1, 2, 3], vec![1, 2], vec![1, 3], vec![2, 3]];
let mut apriori = Apriori::new()
.with_min_support(0.5)
.with_min_confidence(0.0);
apriori.fit(&transactions);
let rules = apriori.get_rules();
let rule = rules
.iter()
.find(|r| r.antecedent == vec![1] && r.consequent == vec![2])
.expect("Should have rule {1} => {2}");
assert!((rule.confidence - 0.6666666).abs() < 1e-5);
}
#[test]
fn test_lift_calculation() {
let transactions = vec![vec![1, 2, 3], vec![1, 2], vec![1, 3], vec![2, 3]];
let mut apriori = Apriori::new()
.with_min_support(0.5)
.with_min_confidence(0.0);
apriori.fit(&transactions);
let rules = apriori.get_rules();
let rule = rules
.iter()
.find(|r| r.antecedent == vec![1] && r.consequent == vec![2])
.expect("Should have rule {1} => {2}");
assert!((rule.lift - 0.8888888).abs() < 1e-5);
}
#[test]
fn test_min_support_filter() {
let transactions = vec![
vec![1, 2],
vec![1, 2],
vec![1, 2],
vec![3, 4], ];
let mut apriori = Apriori::new().with_min_support(0.5);
apriori.fit(&transactions);
let itemsets = apriori.get_frequent_itemsets();
for (itemset, support) in itemsets {
assert!(support >= 0.5, "All itemsets should meet min_support");
assert!(
!itemset.contains(&3) && !itemset.contains(&4),
"Infrequent items should be pruned"
);
}
}
#[test]
fn test_min_confidence_filter() {
let transactions = vec![vec![1, 2, 3], vec![1, 2], vec![1, 3], vec![1]];
let mut apriori = Apriori::new()
.with_min_support(0.25)
.with_min_confidence(0.8);
apriori.fit(&transactions);
let rules = apriori.get_rules();
for rule in &rules {
assert!(
rule.confidence >= 0.8,
"Rule {:?} => {:?} has confidence {:.2} < 0.8",
rule.antecedent,
rule.consequent,
rule.confidence
);
}
}
#[test]
fn test_empty_transactions() {
let transactions: Vec<Vec<usize>> = vec![];
let mut apriori = Apriori::new();
apriori.fit(&transactions);
let itemsets = apriori.get_frequent_itemsets();
assert_eq!(itemsets.len(), 0, "Should have no frequent itemsets");
let rules = apriori.get_rules();
assert_eq!(rules.len(), 0, "Should have no rules");
}
#[test]
fn test_single_item_transactions() {
let transactions = vec![vec![1], vec![2], vec![3], vec![4]];
let mut apriori = Apriori::new().with_min_support(0.25);
apriori.fit(&transactions);
let itemsets = apriori.get_frequent_itemsets();
assert_eq!(itemsets.len(), 4);
for (itemset, _) in itemsets {
assert_eq!(itemset.len(), 1);
}
let rules = apriori.get_rules();
assert_eq!(rules.len(), 0);
}
#[test]
fn test_get_rules_before_fit() {
let apriori = Apriori::new();
let rules = apriori.get_rules();
assert_eq!(rules.len(), 0, "Should have no rules before fit");
}
#[test]
fn test_get_itemsets_before_fit() {
let apriori = Apriori::new();
let itemsets = apriori.get_frequent_itemsets();
assert_eq!(itemsets.len(), 0, "Should have no itemsets before fit");
}