From 09973d227d0cb61eadea535d678febcfd94b50c9 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Tue, 11 Sep 2018 08:31:47 +0200 Subject: [PATCH] Add some unit tests for find_best_match_for_name There were only some UI tests that covered this function. Since there's more diagnostic work going on, I think it makes sense to have this unit tested. --- src/libsyntax/util/lev_distance.rs | 42 ++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/util/lev_distance.rs b/src/libsyntax/util/lev_distance.rs index e429791f2bdd4..feee2422cb662 100644 --- a/src/libsyntax/util/lev_distance.rs +++ b/src/libsyntax/util/lev_distance.rs @@ -11,7 +11,7 @@ use std::cmp; use symbol::Symbol; -/// To find the Levenshtein distance between two strings +/// Find the Levenshtein distance between two strings pub fn lev_distance(a: &str, b: &str) -> usize { // cases which don't require further computation if a.is_empty() { @@ -41,10 +41,12 @@ pub fn lev_distance(a: &str, b: &str) -> usize { } dcol[t_last + 1] } -/// To find the best match for a given string from an iterator of names +/// Find the best match for a given word in the given iterator +/// /// As a loose rule to avoid the obviously incorrect suggestions, it takes /// an optional limit for the maximum allowable edit distance, which defaults /// to one-third of the given word. +/// /// Besides Levenshtein, we use case insensitive comparison to improve accuracy on an edge case with /// a lower(upper)case letters mismatch. pub fn find_best_match_for_name<'a, T>(iter_names: T, @@ -105,3 +107,39 @@ fn test_lev_distance() { assert_eq!(lev_distance(b, c), 1); assert_eq!(lev_distance(c, b), 1); } + +#[test] +fn test_find_best_match_for_name() { + use with_globals; + with_globals(|| { + let input = vec![Symbol::intern("aaab"), Symbol::intern("aaabc")]; + assert_eq!( + find_best_match_for_name(input.iter(), "aaaa", None), + Some(Symbol::intern("aaab")) + ); + + assert_eq!( + find_best_match_for_name(input.iter(), "1111111111", None), + None + ); + + let input = vec![Symbol::intern("aAAA")]; + assert_eq!( + find_best_match_for_name(input.iter(), "AAAA", None), + Some(Symbol::intern("aAAA")) + ); + + let input = vec![Symbol::intern("AAAA")]; + // Returns None because `lev_distance > max_dist / 3` + assert_eq!( + find_best_match_for_name(input.iter(), "aaaa", None), + None + ); + + let input = vec![Symbol::intern("AAAA")]; + assert_eq!( + find_best_match_for_name(input.iter(), "aaaa", Some(4)), + Some(Symbol::intern("AAAA")) + ); + }) +}