1package completions
2
3import (
4 "testing"
5
6 "charm.land/lipgloss/v2"
7 "github.com/stretchr/testify/require"
8)
9
10func TestFilterPrefersExactBasenameStem(t *testing.T) {
11 t.Parallel()
12
13 c := New(lipgloss.NewStyle(), lipgloss.NewStyle(), lipgloss.NewStyle())
14 c.SetItems([]FileCompletionValue{
15 {Path: "internal/ui/chat/search.go"},
16 {Path: "internal/ui/chat/user.go"},
17 }, nil)
18
19 c.Filter("user")
20
21 filtered := c.filtered
22 require.NotEmpty(t, filtered)
23 first, ok := filtered[0].(*CompletionItem)
24 require.True(t, ok)
25 require.Equal(t, "internal/ui/chat/user.go", first.Text())
26 require.NotEmpty(t, first.match.MatchedIndexes)
27}
28
29func TestFilterPrefersBasenamePrefix(t *testing.T) {
30 t.Parallel()
31
32 c := New(lipgloss.NewStyle(), lipgloss.NewStyle(), lipgloss.NewStyle())
33 c.SetItems([]FileCompletionValue{
34 {Path: "internal/ui/chat/mcp.go"},
35 {Path: "internal/ui/model/chat.go"},
36 }, nil)
37
38 c.Filter("chat.g")
39
40 filtered := c.filtered
41 require.NotEmpty(t, filtered)
42 first, ok := filtered[0].(*CompletionItem)
43 require.True(t, ok)
44 require.Equal(t, "internal/ui/model/chat.go", first.Text())
45 require.NotEmpty(t, first.match.MatchedIndexes)
46}
47
48func TestNamePriorityTier(t *testing.T) {
49 t.Parallel()
50
51 tests := []struct {
52 name string
53 path string
54 query string
55 wantTier int
56 }{
57 {
58 name: "exact stem",
59 path: "internal/ui/chat/user.go",
60 query: "user",
61 wantTier: tierExactName,
62 },
63 {
64 name: "basename prefix",
65 path: "internal/ui/model/chat.go",
66 query: "chat.g",
67 wantTier: tierPrefixName,
68 },
69 {
70 name: "path segment exact",
71 path: "internal/ui/chat/mcp.go",
72 query: "chat",
73 wantTier: tierPathSegment,
74 },
75 {
76 name: "fallback",
77 path: "internal/ui/chat/search.go",
78 query: "user",
79 wantTier: tierFallback,
80 },
81 }
82
83 for _, tt := range tests {
84 tt := tt
85 t.Run(tt.name, func(t *testing.T) {
86 t.Parallel()
87 got := namePriorityTier(tt.path, tt.query)
88 require.Equal(t, tt.wantTier, got)
89 })
90 }
91}
92
93func TestFilterPrefersPathSegmentExact(t *testing.T) {
94 t.Parallel()
95
96 c := New(lipgloss.NewStyle(), lipgloss.NewStyle(), lipgloss.NewStyle())
97 c.SetItems([]FileCompletionValue{
98 {Path: "internal/ui/model/xychat.go"},
99 {Path: "internal/ui/chat/mcp.go"},
100 }, nil)
101
102 c.Filter("chat")
103
104 filtered := c.filtered
105 require.NotEmpty(t, filtered)
106 first, ok := filtered[0].(*CompletionItem)
107 require.True(t, ok)
108 require.Equal(t, "internal/ui/chat/mcp.go", first.Text())
109}