package tui import ( "strings" "testing" ) func TestFuzzyMatchIsASubsequence(t *testing.T) { cases := []struct { pattern, s string want bool }{ {"", "dark-mode", true}, {"dark", "dark-mode", true}, {"dkmd", "dark-mode", true}, {"DARK", "dark-mode", true}, {"mode", "dark-mode", true}, {"dm", "dark-mode", true}, {"modedark", "dark-mode", false}, {"darkk", "dark-mode", false}, {"z", "dark-mode", false}, } for _, c := range cases { if _, ok := fuzzyMatch(c.pattern, c.s); ok != c.want { t.Errorf("fuzzyMatch(%q, %q) = %v, want %v", c.pattern, c.s, ok, c.want) } } } // What is typed is nearly always the start of a word or a run out of one, so // those have to beat a match scattered across the candidate. func TestFuzzyScoreFavoursRunsAndWordStarts(t *testing.T) { run, _ := fuzzyMatch("mode", "dark-mode") scattered, _ := fuzzyMatch("mode", "my-old-directory-extras") if run <= scattered { t.Errorf("a run scored %d, a scattered match %d — want the run ahead", run, scattered) } exact, _ := fuzzyMatch("api", "api") inside, _ := fuzzyMatch("api", "rapid-prototyping") if exact <= inside { t.Errorf("the exact name scored %d, the longer one %d — want the exact ahead", exact, inside) } } func TestFuzzyRankOrdersBestFirstAndKeepsTiesStable(t *testing.T) { items := []string{"old-parser", "parser-rewrite", "dark-mode", "pretty-printer"} got := fuzzyRank(items, "par", func(s string) string { return s }) if len(got) != 2 { t.Fatalf("fuzzyRank returned %v, want the two that contain p, a and r in order", got) } if got[0] != "parser-rewrite" { t.Errorf("best match = %q, want the one starting with the pattern", got[0]) } // An empty filter changes nothing: the list keeps the order it arrived in. all := fuzzyRank(items, "", func(s string) string { return s }) if strings.Join(all, ",") != strings.Join(items, ",") { t.Errorf("an empty filter reordered the list: %v", all) } if none := fuzzyRank(items, "zzz", func(s string) string { return s }); len(none) != 0 { t.Errorf("fuzzyRank(%q) = %v, want nothing", "zzz", none) } }