e22e040688
CI / test (pull_request) Successful in 2m31s
Tag autocomplete shows suggestions when typing #partial in capture bar. Tab/enter accepts, up/down navigates, esc dismisses. Query composition extends ? search with date filters (@today, @week, @month, <7d, >30d), card type filters (^snippet), all composable with existing text and tag filters.
86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
package tui
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/lerko/nib/internal/db"
|
|
)
|
|
|
|
func TestTagTokenAtCursor(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
val string
|
|
cursor int
|
|
wantStart int
|
|
wantEnd int
|
|
wantPfx string
|
|
wantOk bool
|
|
}{
|
|
{"mid tag cursor after a", "hello #par world", 9, 6, 10, "pa", true},
|
|
{"end of tag", "hello #par world", 10, 6, 10, "par", true},
|
|
{"end of input", "hello #parenting", 16, 6, 16, "parenting", true},
|
|
{"start of tag just hash", "hello # world", 7, 6, 7, "", true},
|
|
{"not in tag", "hello world", 5, 0, 0, "", false},
|
|
{"tag at start", "#ops stuff", 4, 0, 4, "ops", true},
|
|
{"cursor at hash", "#ops", 1, 0, 4, "", true},
|
|
{"multiple tags second", "hello #ops #inf", 15, 11, 15, "inf", true},
|
|
{"empty string", "", 0, 0, 0, "", false},
|
|
{"cursor past end", "#ops", 10, 0, 4, "ops", true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
start, end, pfx, ok := tagTokenAtCursor(tt.val, tt.cursor)
|
|
if ok != tt.wantOk {
|
|
t.Fatalf("ok = %v, want %v", ok, tt.wantOk)
|
|
}
|
|
if !ok {
|
|
return
|
|
}
|
|
if start != tt.wantStart || end != tt.wantEnd {
|
|
t.Fatalf("range = [%d,%d), want [%d,%d)", start, end, tt.wantStart, tt.wantEnd)
|
|
}
|
|
if pfx != tt.wantPfx {
|
|
t.Fatalf("prefix = %q, want %q", pfx, tt.wantPfx)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFilterTagSuggestions(t *testing.T) {
|
|
tags := []db.TagCount{
|
|
{Tag: "ops", Count: 5},
|
|
{Tag: "ops-deploy", Count: 3},
|
|
{Tag: "infra", Count: 2},
|
|
{Tag: "ops-team", Count: 1},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
prefix string
|
|
want []string
|
|
}{
|
|
{"empty prefix", "", nil},
|
|
{"exact match excluded", "ops", []string{"ops-deploy", "ops-team"}},
|
|
{"partial match", "op", []string{"ops", "ops-deploy", "ops-team"}},
|
|
{"no match", "zzz", nil},
|
|
{"case insensitive", "OP", []string{"ops", "ops-deploy", "ops-team"}},
|
|
{"single match", "inf", []string{"infra"}},
|
|
{"full match excluded", "infra", nil},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := filterTagSuggestions(tags, tt.prefix)
|
|
if len(got) != len(tt.want) {
|
|
t.Fatalf("got %v, want %v", got, tt.want)
|
|
}
|
|
for i := range got {
|
|
if got[i] != tt.want[i] {
|
|
t.Fatalf("got %v, want %v", got, tt.want)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|