test(tui): add tier 1 unit tests for pure logic functions
Cover search filtering, intent matching, card affordances, checklist parsing, template slot discovery/resolve, date grouping, and truncation.
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user