1package fuzzy
2
3import (
4 "testing"
5
6 "github.com/stretchr/testify/require"
7)
8
9func TestMatch(t *testing.T) {
10 tests := []struct {
11 name string
12 text string
13 query string
14 want Score
15 ok bool
16 }{
17 {name: "empty query", text: "work", query: "", want: Score{Kind: Exact}, ok: true},
18 {name: "exact", text: "work", query: "work", want: Score{Kind: Exact, Positions: []int{0, 1, 2, 3}, Span: 4}, ok: true},
19 {name: "prefix", text: "workspace", query: "wor", want: Score{Kind: Prefix, Positions: []int{0, 1, 2}, Span: 3}, ok: true},
20 {name: "subsequence", text: "a-b-c", query: "bc", want: Score{Kind: Subsequence, Positions: []int{2, 4}, Span: 3, First: 2}, ok: true},
21 {name: "runes not bytes", text: "été-x", query: "x", want: Score{Kind: Subsequence, Positions: []int{4}, Span: 1, First: 4}, ok: true},
22 {name: "multi-byte prefix counts runes", text: "été", query: "ét", want: Score{Kind: Prefix, Positions: []int{0, 1}, Span: 2}, ok: true},
23 {name: "no match", text: "work", query: "z", ok: false},
24 {name: "out of order", text: "ab", query: "ba", ok: false},
25 }
26 for _, tt := range tests {
27 t.Run(tt.name, func(t *testing.T) {
28 got, ok := Match(tt.text, tt.query, []rune(tt.query))
29 require.Equal(t, tt.ok, ok)
30 require.Equal(t, tt.want, got)
31 })
32 }
33}
34
35// TestKindOrder pins the best-first order callers rely on to use a Kind as a
36// rank.
37func TestKindOrder(t *testing.T) {
38 require.Less(t, Exact, Prefix)
39 require.Less(t, Prefix, Subsequence)
40}
41
42func TestLess(t *testing.T) {
43 tests := []struct {
44 name string
45 leftRank int
46 left Score
47 rightRank int
48 right Score
49 wantLess bool
50 wantGreater bool
51 }{
52 {name: "rank wins", leftRank: 0, left: Score{Span: 9}, rightRank: 1, right: Score{Span: 1}, wantLess: true},
53 {name: "span breaks rank tie", left: Score{Span: 2, First: 5}, right: Score{Span: 3}, wantLess: true},
54 {name: "first breaks span tie", left: Score{Span: 2, First: 1}, right: Score{Span: 2, First: 3}, wantLess: true},
55 {name: "equal", left: Score{Span: 2}, right: Score{Span: 2}},
56 }
57 for _, tt := range tests {
58 t.Run(tt.name, func(t *testing.T) {
59 require.Equal(t, tt.wantLess, Less(tt.leftRank, tt.left, tt.rightRank, tt.right))
60 require.Equal(t, tt.wantGreater, Less(tt.rightRank, tt.right, tt.leftRank, tt.left))
61 })
62 }
63}