summaryrefslogtreecommitdiff
path: root/internal/tui/reader_test.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-24 12:26:23 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-24 12:26:23 +0200
commited34fd574b4fc2e0a52c655ececddd1be29b271e (patch)
tree8980a2b86ec279289abcabe3a691fa8a2a925765 /internal/tui/reader_test.go
parenta26fed000ad9f292618f9cecfd2b505dddfd004a (diff)
downloadlectio-ed34fd574b4fc2e0a52c655ececddd1be29b271e.tar.gz
lectio-ed34fd574b4fc2e0a52c655ececddd1be29b271e.zip
reader: lectio-ui --reader fuzzy book picker + chapter reader over the corpora; v0.8.0
Diffstat (limited to 'internal/tui/reader_test.go')
-rw-r--r--internal/tui/reader_test.go100
1 files changed, 100 insertions, 0 deletions
diff --git a/internal/tui/reader_test.go b/internal/tui/reader_test.go
new file mode 100644
index 0000000..167e546
--- /dev/null
+++ b/internal/tui/reader_test.go
@@ -0,0 +1,100 @@
+package tui
+
+import (
+ "strings"
+ "testing"
+
+ tea "github.com/charmbracelet/bubbletea"
+
+ "github.com/lukaszkasprzak/lectio/internal/bible"
+ "github.com/lukaszkasprzak/lectio/internal/config"
+)
+
+func enReader(t *testing.T) ReaderModel {
+ t.Helper()
+ tbl, err := bible.LoadBookTable(nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ cfg := config.Default()
+ cfg.UILanguage = "en"
+ cfg.SiglaStyle = "english"
+ cfg.Versions = []string{"bt", "wuj", "vul", "grb", "drb"}
+ return NewReader(cfg, tbl)
+}
+
+func key(m ReaderModel, k tea.KeyMsg) ReaderModel {
+ nm, _ := m.Update(k)
+ return nm.(ReaderModel)
+}
+
+func runes(s string) tea.KeyMsg { return tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune(s)} }
+
+func TestReaderInit(t *testing.T) {
+ m := enReader(t)
+ if m.mode != modePick {
+ t.Errorf("mode = %v want modePick", m.mode)
+ }
+ if len(m.matches) != len(m.books) || len(m.books) != 73 {
+ t.Errorf("matches=%d books=%d", len(m.matches), len(m.books))
+ }
+ if len(m.versions) == 0 || m.versions[0] == "bt" {
+ t.Errorf("versions = %v (bt must be excluded, non-empty)", m.versions)
+ }
+}
+
+func TestReaderFilterAndOpen(t *testing.T) {
+ m := enReader(t)
+ nm, _ := m.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
+ m = nm.(ReaderModel)
+ m = key(m, runes("jn"))
+ if len(m.matches) == 0 || m.books[m.matches[0]].Canonical != "John" {
+ t.Fatalf("filter 'jn' top = %v", m.books[m.matches[m.pickSel]])
+ }
+ m = key(m, tea.KeyMsg{Type: tea.KeyEnter})
+ if m.mode != modeRead {
+ t.Fatalf("did not enter read mode")
+ }
+ if m.books[m.bookIdx].Canonical != "John" || len(m.verses) == 0 {
+ t.Errorf("opened book=%q verses=%d", m.books[m.bookIdx].Canonical, len(m.verses))
+ }
+ if !strings.Contains(m.View(), "1") { // chapter 1 header
+ t.Errorf("read view missing chapter:\n%s", m.View())
+ }
+}
+
+func TestReaderChapterAndVersion(t *testing.T) {
+ m := enReader(t)
+ nm, _ := m.Update(tea.WindowSizeMsg{Width: 80, Height: 24})
+ m = nm.(ReaderModel)
+ m = key(m, runes("jn"))
+ m = key(m, tea.KeyMsg{Type: tea.KeyEnter})
+ firstChap := m.chapters[m.chapPos]
+ m = key(m, tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("n")}) // next chapter
+ if m.chapters[m.chapPos] <= firstChap {
+ t.Errorf("chapter did not advance: %d -> %d", firstChap, m.chapters[m.chapPos])
+ }
+ v0 := m.verIdx
+ m = key(m, tea.KeyMsg{Type: tea.KeyTab})
+ if m.verIdx == v0 {
+ t.Errorf("version did not cycle")
+ }
+ // esc returns to picker
+ m = key(m, tea.KeyMsg{Type: tea.KeyEsc})
+ if m.mode != modePick {
+ t.Errorf("esc did not return to picker")
+ }
+}
+
+func TestReaderFuzzyScore(t *testing.T) {
+ if s, ok := fuzzyScore("gen", "Gen Genesis"); !ok || s < 500 {
+ t.Errorf("substring score = %d,%v", s, ok)
+ }
+ if _, ok := fuzzyScore("xyz", "Gen Genesis"); ok {
+ t.Error("xyz should not match Genesis")
+ }
+ // subsequence: g..s..s across the string
+ if _, ok := fuzzyScore("gss", "Gen Genesis"); !ok {
+ t.Error("gss should subsequence-match")
+ }
+}