summaryrefslogtreecommitdiff
path: root/internal/web
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-29 11:46:17 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-29 11:46:17 +0200
commit8ddd910dd545c45a7227da87ca125758b4a0e2cb (patch)
treeb652bb239c622e2f8806a443db21a0b0bf8c8962 /internal/web
parent79f9ae051c1e8f179e2e7c17f590c105eb18bef1 (diff)
downloadlectio-8ddd910dd545c45a7227da87ca125758b4a0e2cb.tar.gz
lectio-8ddd910dd545c45a7227da87ca125758b4a0e2cb.zip
test(bible): skip corpus-dependent tests when optional corpora aren't embedded
Since 51c0f4e split the corpora (only vul embedded by default; wuj/drb/grb behind -tags fullbible), `go test ./...` on the default build was red across six packages -- every failure was a test assuming an optional corpus is present. Guard those assertions with a skip keyed on bible.Meta(code), so they run under -tags fullbible and skip -- not fail -- on the default vul-only build. Mixed tests are split into subtests so the always-embedded vul assertions and pure logic (pl->vul fallback, explicit passthrough, bt-rejection, i18n labels) keep running on both builds. Test-only change; no product code or corpora touched. - internal/bible: TestVerses, TestLookup, TestCorpusBooks, TestChapters, TestGrbNoApparatusMarkers, TestCrossChapterRange* (requireCorpus helper). - internal/cli, config, render, tui, web: the same pattern for their corpus-dependent tests. - Fixes an index-out-of-range panic in internal/tui's reader tests that was aborting the package binary and masking 3 further corpus-absence failures (TestReaderBookmarkFlow, TestReaderChapterJump, TestReaderRemembersPlace). Verified: `go test ./...` and `go test -tags fullbible ./...` both green (0 FAIL); guards active only on the default build (29 skips vs 1 unrelated pre-existing); gofmt and go vet clean.
Diffstat (limited to 'internal/web')
-rw-r--r--internal/web/render_test.go45
-rw-r--r--internal/web/server_test.go58
2 files changed, 77 insertions, 26 deletions
diff --git a/internal/web/render_test.go b/internal/web/render_test.go
index 39bcc58..94d5e6e 100644
--- a/internal/web/render_test.go
+++ b/internal/web/render_test.go
@@ -124,26 +124,37 @@ func TestRenderReadingsInterlinear(t *testing.T) {
t.Errorf("interlinear output missing vnum: %q", html[:min(300, len(html))])
}
// The first ilverse block should group both version labels under one key.
- // Bound it by the next vnum span (each ilverse carries exactly one).
- i := strings.Index(html, `class="vnum"`)
- block := html[i:]
- if j := strings.Index(html[i+1:], `class="vnum"`); j != -1 {
- block = html[i : i+1+j]
- }
- if !strings.Contains(block, "Wujek") || !strings.Contains(block, "Wulgata") {
- t.Errorf("first interlinear verse block missing both version labels: %q", block)
- }
+ // Bound it by the next vnum span (each ilverse carries exactly one). The
+ // Wujek line appears only when the optional wuj corpus is embedded and
+ // contributes versified text to the alignment.
+ t.Run("both version labels", func(t *testing.T) {
+ requireCorpus(t, "wuj")
+ i := strings.Index(html, `class="vnum"`)
+ block := html[i:]
+ if j := strings.Index(html[i+1:], `class="vnum"`); j != -1 {
+ block = html[i : i+1+j]
+ }
+ if !strings.Contains(block, "Wujek") || !strings.Contains(block, "Wulgata") {
+ t.Errorf("first interlinear verse block missing both version labels: %q", block)
+ }
+ })
}
func TestRenderReadingsInterlinearExcludesBT(t *testing.T) {
secs := []liturgy.Section{{Heading: "Ewangelia", Citation: "J 20, 1. 11-18", Ref: "John 20:1,11-18", PartID: "ewangelia"}}
html := string(RenderReadings(secs, []string{"bt", "vul"}, "new", "interlinear", "pl", liturgy.DayInfo{}))
+ // bt is dropped before rendering regardless, so its own label never shows.
if strings.Contains(html, "Biblia TysiÄ…clecia (niedziela.pl)") {
t.Errorf("interlinear output should substitute wuj for bt, not carry bt's label: %q", html[:min(300, len(html))])
}
- if !strings.Contains(html, "Wujek") {
- t.Errorf("interlinear output should substitute wuj for bt: %q", html[:min(300, len(html))])
- }
+ // bt maps to wuj, but the Wujek label only renders when wuj is embedded and
+ // supplies versified text to the alignment.
+ t.Run("wuj substituted", func(t *testing.T) {
+ requireCorpus(t, "wuj")
+ if !strings.Contains(html, "Wujek") {
+ t.Errorf("interlinear output should substitute wuj for bt: %q", html[:min(300, len(html))])
+ }
+ })
}
func TestRenderReadingsInterlinearNoVersifiedNote(t *testing.T) {
@@ -190,9 +201,15 @@ func TestRenderReadingsLocalizesEN(t *testing.T) {
func TestRenderPassageColumns(t *testing.T) {
html := string(RenderPassage("John", "John", 3, []string{"wuj"}, "vertical", "en"))
- if !strings.Contains(html, "John 3") || !strings.Contains(html, "3:16") {
- t.Errorf("passage columns missing heading/verse:\n%s", html)
+ if !strings.Contains(html, "John 3") { // passage heading, independent of the corpus
+ t.Errorf("passage columns missing heading:\n%s", html)
}
+ t.Run("verse", func(t *testing.T) {
+ requireCorpus(t, "wuj") // the verse text comes from the optional wuj corpus
+ if !strings.Contains(html, "3:16") {
+ t.Errorf("passage columns missing verse:\n%s", html)
+ }
+ })
}
func TestRenderPassageInterlinear(t *testing.T) {
diff --git a/internal/web/server_test.go b/internal/web/server_test.go
index 42de0b5..49f7776 100644
--- a/internal/web/server_test.go
+++ b/internal/web/server_test.go
@@ -15,6 +15,18 @@ import (
"github.com/lukaszkasprzak/lectio/internal/liturgy"
)
+// requireCorpus skips the test when corpus `code` is not embedded in this
+// build. The optional corpora (wuj, drb, grb) compile in only with
+// `-tags fullbible` (or when dropped into the user corpora dir); mirrors the
+// helper in internal/bible so these tests run under fullbible and skip -- not
+// fail -- on the default vul-only build.
+func requireCorpus(t *testing.T, code string) {
+ t.Helper()
+ if _, ok := bible.Meta(code); !ok {
+ t.Skipf("corpus %q not embedded; build with -tags fullbible", code)
+ }
+}
+
// TestServer exercises NewServer's handler tree end to end via httptest. Every
// reading is computed offline (no network, no cache, no fixture server).
func TestServer(t *testing.T) {
@@ -33,10 +45,14 @@ func TestServer(t *testing.T) {
t.Errorf("body missing reading heading: %q", body)
}
// ?v=wuj -> the gospel is rendered from the Wujek corpus ("grobu" is
- // distinctly Polish Wujek verse text, not Latin/English).
- if !strings.Contains(body, "grobu") {
- t.Errorf("body missing Wujek verse text: %q", body)
- }
+ // distinctly Polish Wujek verse text, not Latin/English) -- needs the
+ // optional wuj corpus embedded.
+ t.Run("wuj verse text", func(t *testing.T) {
+ requireCorpus(t, "wuj")
+ if !strings.Contains(body, "grobu") {
+ t.Errorf("body missing Wujek verse text: %q", body)
+ }
+ })
if !strings.Contains(body, "htmx") {
t.Errorf("body missing htmx reference")
}
@@ -121,9 +137,14 @@ func TestServer(t *testing.T) {
block = body[i : i+1+j]
}
// config.Default() is English chrome: "Wujek (Polish)"/"Vulgate (Latin)".
- if !strings.Contains(block, "Wujek") || !strings.Contains(block, "Vulgate") {
- t.Errorf("interlinear verse block missing both version labels grouped together: %q", block)
- }
+ // The Wujek line appears only when the optional wuj corpus is embedded and
+ // contributes versified text to the alignment.
+ t.Run("both version labels", func(t *testing.T) {
+ requireCorpus(t, "wuj")
+ if !strings.Contains(block, "Wujek") || !strings.Contains(block, "Vulgate") {
+ t.Errorf("interlinear verse block missing both version labels grouped together: %q", block)
+ }
+ })
})
t.Run("readings partial vertical", func(t *testing.T) {
@@ -144,9 +165,15 @@ func TestServer(t *testing.T) {
t.Fatalf("status = %d, want 200", rec.Code)
}
body := rec.Body.String()
- if !strings.Contains(body, "Wujek") {
- t.Errorf("bt should be substituted with wuj in interlinear mode: %q", body)
- }
+ // bt maps to wuj, but its Wujek label only renders when wuj is embedded and
+ // supplies versified text to the interlinear alignment.
+ t.Run("wuj substituted", func(t *testing.T) {
+ requireCorpus(t, "wuj")
+ if !strings.Contains(body, "Wujek") {
+ t.Errorf("bt should be substituted with wuj in interlinear mode: %q", body)
+ }
+ })
+ // bt is dropped before rendering regardless, so its own label never shows.
if strings.Contains(body, "Biblia TysiÄ…clecia (niedziela.pl)") {
t.Errorf("bt paragraph column should not appear in interlinear mode: %q", body)
}
@@ -251,9 +278,16 @@ func TestReaderPassage(t *testing.T) {
if rec.Code != 200 {
t.Fatalf("status %d", rec.Code)
}
- if b := rec.Body.String(); !strings.Contains(b, "John 3") || !strings.Contains(b, "3:16") {
- t.Errorf("passage missing heading/verse")
+ b := rec.Body.String()
+ if !strings.Contains(b, "John 3") { // passage heading, independent of the corpus
+ t.Errorf("passage missing heading")
}
+ t.Run("verse", func(t *testing.T) {
+ requireCorpus(t, "wuj") // the verse text comes from the optional wuj corpus
+ if !strings.Contains(b, "3:16") {
+ t.Errorf("passage missing verse")
+ }
+ })
}
func TestReaderCompareAndBTFilter(t *testing.T) {