use obadh_engine::{
AutocorrectConfig, AutocorrectEngine, CorrectionRequest, CorrectionSource, Lexicon,
LexiconEntry, ObadhEngine,
};
#[test]
fn autocorrect_preserves_exact_obadh_output() {
let obadh = ObadhEngine::new();
let autocorrect = AutocorrectEngine::from_entries([LexiconEntry::new("বিজ্ঞান", 10_000)]);
let request = obadh.autocorrect_request("biggan");
let decision = autocorrect.decide(request.clone());
assert_eq!(request.current, "বিজ্ঞান");
assert_eq!(request.roman_input.as_deref(), Some("biggan"));
assert_eq!(request.obadh_output.as_deref(), Some("বিজ্ঞান"));
assert_eq!(decision.replacement, None);
assert_eq!(decision.candidates[0].source, CorrectionSource::NoChange);
}
#[test]
fn autocorrect_can_fix_simple_bangla_vowel_typos() {
let autocorrect = AutocorrectEngine::from_entries([
LexiconEntry::new("আমি", 50_000),
LexiconEntry::new("আম", 500),
]);
let decision = autocorrect.decide(CorrectionRequest::new("আমী"));
assert_eq!(
decision
.replacement
.as_ref()
.map(|candidate| candidate.text.as_str()),
Some("আমি")
);
}
#[test]
fn autocorrect_uses_suggestions_when_margin_is_low() {
let autocorrect = AutocorrectEngine::with_config(
Lexicon::new([LexiconEntry::new("আমি", 1)]),
AutocorrectConfig {
autocorrect_margin: 1_000,
..AutocorrectConfig::default()
},
);
let decision = autocorrect.decide(CorrectionRequest::new("আমী"));
assert!(decision
.candidates
.iter()
.any(|candidate| candidate.text == "আমি"));
assert_eq!(decision.replacement, None);
}
#[test]
fn autocorrect_candidate_list_is_bounded() {
let autocorrect = AutocorrectEngine::with_config(
Lexicon::new([
LexiconEntry::new("আমি", 10),
LexiconEntry::new("আম", 9),
LexiconEntry::new("আমার", 8),
LexiconEntry::new("আমরা", 7),
]),
AutocorrectConfig {
max_candidates: 2,
max_edit_cost: 8,
max_skeleton_candidates: 0,
..AutocorrectConfig::default()
},
);
let decision = autocorrect.decide(CorrectionRequest::new("আমী"));
assert_eq!(decision.candidates.len(), 2);
assert_eq!(decision.candidates[0].text, "আমি");
assert!(decision
.candidates
.iter()
.all(|candidate| candidate.source == CorrectionSource::LexiconEdit));
}
#[test]
fn autocorrect_features_mark_obadh_baseline_candidate() {
let autocorrect = AutocorrectEngine::from_entries([LexiconEntry::new("আমি", 50_000)]);
let decision = autocorrect.decide(CorrectionRequest::new("আমী").with_obadh_output("আমী"));
let keep = decision
.candidates
.iter()
.find(|candidate| candidate.source == CorrectionSource::NoChange)
.expect("no-change candidate should be present");
let correction = decision
.candidates
.iter()
.find(|candidate| candidate.text == "আমি")
.expect("lexicon correction should be present");
assert!(keep.features.obadh_baseline);
assert!(!correction.features.obadh_baseline);
assert!(!correction.features.input_known);
assert!(correction.features.candidate_known);
assert_eq!(correction.features.as_i16_array()[0], 1);
}
#[test]
fn autocorrect_suggests_prefix_completions_from_lexicon_frequency() {
let autocorrect = AutocorrectEngine::with_config(
Lexicon::new([
LexiconEntry::new("কেমন", 225),
LexiconEntry::new("কেমনি", 11),
LexiconEntry::new("কেমনে", 10),
LexiconEntry::new("যেমন", 247),
]),
AutocorrectConfig {
max_candidates: 8,
max_prefix_candidates: 4,
max_skeleton_candidates: 0,
max_edit_cost: 0,
..AutocorrectConfig::default()
},
);
let decision = autocorrect.decide(CorrectionRequest::new("কেম"));
let completions = decision
.candidates
.iter()
.filter(|candidate| candidate.source == CorrectionSource::PrefixCompletion)
.map(|candidate| candidate.text.as_str())
.collect::<Vec<_>>();
assert_eq!(completions, vec!["কেমন", "কেমনি", "কেমনে"]);
assert_eq!(decision.replacement, None);
let kemon = decision
.candidates
.iter()
.find(|candidate| candidate.text == "কেমন")
.expect("prefix completion should include কেমন");
assert_eq!(kemon.features.source_id, 4);
assert_eq!(kemon.edit_cost.0, 0);
}