completions_test.go

  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}