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)
}
}