Vectrum
Sign In
66 lines · 2.1 KB · Go
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)
	}
}