476abbed00
Cover search filtering, intent matching, card affordances, checklist parsing, template slot discovery/resolve, date grouping, and truncation.
132 lines
3.4 KiB
Go
132 lines
3.4 KiB
Go
package tui
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/lerko/nib/internal/db"
|
|
)
|
|
|
|
func TestMatchesIntent(t *testing.T) {
|
|
snippet := db.CardSnippet
|
|
template := db.CardTemplate
|
|
checklist := db.CardChecklist
|
|
note := db.CardNote
|
|
link := db.CardLink
|
|
decision := db.CardDecision
|
|
|
|
tests := []struct {
|
|
name string
|
|
cardType *db.CardType
|
|
intent intent
|
|
want bool
|
|
}{
|
|
{"all matches nil", nil, intentAll, true},
|
|
{"all matches snippet", &snippet, intentAll, true},
|
|
{"all matches template", &template, intentAll, true},
|
|
|
|
{"grab matches nil", nil, intentGrab, true},
|
|
{"grab matches snippet", &snippet, intentGrab, true},
|
|
{"grab rejects template", &template, intentGrab, false},
|
|
{"grab rejects note", ¬e, intentGrab, false},
|
|
|
|
{"read matches note", ¬e, intentRead, true},
|
|
{"read matches link", &link, intentRead, true},
|
|
{"read matches decision", &decision, intentRead, true},
|
|
{"read rejects snippet", &snippet, intentRead, false},
|
|
{"read rejects nil", nil, intentRead, false},
|
|
|
|
{"fill matches template", &template, intentFill, true},
|
|
{"fill matches checklist", &checklist, intentFill, true},
|
|
{"fill rejects snippet", &snippet, intentFill, false},
|
|
{"fill rejects nil", nil, intentFill, false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := &db.Entity{CardType: tt.cardType}
|
|
if got := matchesIntent(e, tt.intent); got != tt.want {
|
|
t.Fatalf("matchesIntent(%v, %v) = %v, want %v", tt.cardType, tt.intent, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDetectAffordance(t *testing.T) {
|
|
snippet := db.CardSnippet
|
|
template := db.CardTemplate
|
|
checklist := db.CardChecklist
|
|
decision := db.CardDecision
|
|
link := db.CardLink
|
|
note := db.CardNote
|
|
|
|
tests := []struct {
|
|
name string
|
|
cardType *db.CardType
|
|
want string
|
|
}{
|
|
{"nil", nil, ""},
|
|
{"snippet", &snippet, "code"},
|
|
{"template", &template, "fill"},
|
|
{"checklist", &checklist, "steps"},
|
|
{"decision", &decision, "decide"},
|
|
{"link", &link, "link"},
|
|
{"note", ¬e, ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := &db.Entity{CardType: tt.cardType}
|
|
if got := detectAffordance(e); got != tt.want {
|
|
t.Fatalf("detectAffordance(%v) = %q, want %q", tt.cardType, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIntentCycle(t *testing.T) {
|
|
order := []intent{intentAll, intentGrab, intentRead, intentFill, intentAll}
|
|
for i := 0; i < len(order)-1; i++ {
|
|
got := order[i].next()
|
|
if got != order[i+1] {
|
|
t.Fatalf("%v.next() = %v, want %v", order[i], got, order[i+1])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestApplyFilter_PinnedFirst(t *testing.T) {
|
|
snippet := db.CardSnippet
|
|
c := newCardsModel()
|
|
c.setEntities([]*db.Entity{
|
|
{ID: "1", Body: "a", CardType: &snippet},
|
|
{ID: "2", Body: "b", Pinned: true, CardType: &snippet},
|
|
{ID: "3", Body: "c", CardType: &snippet},
|
|
})
|
|
|
|
if len(c.filtered) != 3 {
|
|
t.Fatalf("expected 3 filtered, got %d", len(c.filtered))
|
|
}
|
|
if c.filtered[0].ID != "2" {
|
|
t.Fatalf("pinned entity should be first, got %s", c.filtered[0].ID)
|
|
}
|
|
}
|
|
|
|
func TestApplyFilter_CursorClamps(t *testing.T) {
|
|
snippet := db.CardSnippet
|
|
template := db.CardTemplate
|
|
c := newCardsModel()
|
|
c.setEntities([]*db.Entity{
|
|
{ID: "1", Body: "a", CardType: &snippet},
|
|
{ID: "2", Body: "b", CardType: &snippet},
|
|
{ID: "3", Body: "c", CardType: &template},
|
|
})
|
|
c.cursor = 2
|
|
|
|
c.setIntent(intentFill)
|
|
if len(c.filtered) != 1 {
|
|
t.Fatalf("expected 1 fill entity, got %d", len(c.filtered))
|
|
}
|
|
if c.cursor != 0 {
|
|
t.Fatalf("cursor should clamp to 0, got %d", c.cursor)
|
|
}
|
|
}
|