Initial commit

This commit is contained in:
2025-11-06 22:34:14 +01:00
commit ebdbe60e04
21 changed files with 3449 additions and 0 deletions

150
tests/generator_tests.rs Normal file
View File

@@ -0,0 +1,150 @@
use anagram_generator::{
analyzer::PronounceabilityAnalyzer, generator::AnagramGenerator, generator::GenerationConfig,
};
use rand::SeedableRng;
use rand::rngs::StdRng;
use std::collections::HashSet;
#[test]
fn test_generation_produces_valid_anagrams() {
let rng = StdRng::seed_from_u64(42);
let scorer = PronounceabilityAnalyzer::with_defaults();
let mut generator = AnagramGenerator::new(rng, scorer);
let config = GenerationConfig::new(0, 100);
let anagrams = generator.generate("test", 5, &config);
assert!(!anagrams.is_empty());
// Verify all anagrams have the same letters as source
for anagram in &anagrams {
let mut source_chars: Vec<char> = "test".chars().collect();
let mut anagram_chars: Vec<char> = anagram.text().chars().collect();
source_chars.sort();
anagram_chars.sort();
assert_eq!(source_chars, anagram_chars);
}
}
#[test]
fn test_generation_respects_min_score() {
let rng = StdRng::seed_from_u64(42);
let scorer = PronounceabilityAnalyzer::with_defaults();
let mut generator = AnagramGenerator::new(rng, scorer);
let min_score = 70;
let config = GenerationConfig::new(min_score, 10000);
let anagrams = generator.generate("example", 10, &config);
for anagram in &anagrams {
assert!(anagram.score().value() >= min_score);
}
}
#[test]
fn test_generation_produces_unique_anagrams() {
let rng = StdRng::seed_from_u64(42);
let scorer = PronounceabilityAnalyzer::with_defaults();
let mut generator = AnagramGenerator::new(rng, scorer);
let config = GenerationConfig::new(0, 10000);
let anagrams = generator.generate("hello", 5, &config);
let unique_texts: HashSet<&str> = anagrams.iter().map(|a| a.text()).collect();
assert_eq!(unique_texts.len(), anagrams.len());
}
#[test]
fn test_anagrams_sorted_by_score() {
let rng = StdRng::seed_from_u64(42);
let scorer = PronounceabilityAnalyzer::with_defaults();
let mut generator = AnagramGenerator::new(rng, scorer);
let config = GenerationConfig::new(0, 10000);
let anagrams = generator.generate("world", 10, &config);
for i in 1..anagrams.len() {
assert!(anagrams[i - 1].score() >= anagrams[i].score());
}
}
#[test]
fn test_generation_config_builder() {
let config = GenerationConfig::default()
.with_min_score(60)
.with_max_attempts(5000);
assert_eq!(config.min_score.value(), 60);
assert_eq!(config.max_attempts_per_anagram, 5000);
}
#[test]
fn test_generation_excludes_original_word() {
let rng = StdRng::seed_from_u64(42);
let scorer = PronounceabilityAnalyzer::with_defaults();
let mut generator = AnagramGenerator::new(rng, scorer);
let source = "test";
let config = GenerationConfig::new(0, 10000);
let anagrams = generator.generate(source, 20, &config);
// None of the anagrams should be the original word
assert!(anagrams.iter().all(|a| a.text() != source));
}
#[test]
fn test_generation_normalizes_input() {
let rng = StdRng::seed_from_u64(42);
let scorer = PronounceabilityAnalyzer::with_defaults();
let mut generator = AnagramGenerator::new(rng, scorer);
let config = GenerationConfig::new(0, 100);
let anagrams = generator.generate("TeSt", 5, &config);
// All anagrams should be lowercase
for anagram in &anagrams {
assert_eq!(anagram.text(), anagram.text().to_lowercase());
// Verify the anagram contains the same letters as the normalized input
let mut source_chars: Vec<char> = "test".chars().collect();
let mut anagram_chars: Vec<char> = anagram.text().chars().collect();
source_chars.sort();
anagram_chars.sort();
assert_eq!(source_chars, anagram_chars);
}
}
#[test]
fn test_generation_with_long_word() {
let rng = StdRng::seed_from_u64(42);
let scorer = PronounceabilityAnalyzer::with_defaults();
let mut generator = AnagramGenerator::new(rng, scorer);
let config = GenerationConfig::new(50, 5000);
let anagrams = generator.generate("complexity", 10, &config);
assert!(!anagrams.is_empty());
for anagram in &anagrams {
assert_eq!(anagram.text().len(), "complexity".len());
}
}
#[test]
fn test_generation_with_repeated_letters() {
let rng = StdRng::seed_from_u64(42);
let scorer = PronounceabilityAnalyzer::with_defaults();
let mut generator = AnagramGenerator::new(rng, scorer);
let config = GenerationConfig::new(0, 1000);
let anagrams = generator.generate("balloon", 5, &config);
assert!(!anagrams.is_empty());
// Verify the letter counts are preserved
for anagram in &anagrams {
let mut source_chars: Vec<char> = "balloon".chars().collect();
let mut anagram_chars: Vec<char> = anagram.text().chars().collect();
source_chars.sort();
anagram_chars.sort();
assert_eq!(source_chars, anagram_chars);
}
}