1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
package render
import (
"strings"
"testing"
"github.com/lukaszkasprzak/lectio/internal/liturgy"
)
func TestGatherBible(t *testing.T) {
// Offline sections carry the English-canonical lookup reference in Ref; the
// display citation stays in the reader's sigla dialect.
sec := liturgy.Section{Heading: "Ewangelia", Citation: "J 20, 1. 11-18", Ref: "John 20:1,11-18"}
label, blocks := GatherVersion("wuj", sec, "new", "pl")
if !strings.Contains(label, "Wujek") {
t.Errorf("label = %q", label)
}
if len(blocks) == 0 || !strings.HasPrefix(blocks[0], "20:1") {
t.Errorf("first block = %q", blocks)
}
}
func TestGatherTraditional(t *testing.T) {
sec := liturgy.Section{Citation: "Luke 7:36-50"}
_, blocks := GatherVersion("vul", sec, "traditional", "pl")
if len(blocks) == 0 || !strings.HasPrefix(blocks[0], "7:36") {
t.Errorf("first block = %q", blocks)
}
}
// TestGatherVersionLabelLang checks that the label's language follows the
// lang parameter -- pl reproduces today's Polish labels exactly, en gives
// the English set from internal/i18n.
func TestGatherVersionLabelLang(t *testing.T) {
sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"}
label, _ := GatherVersion("vul", sec, "new", "pl")
if label != "Wulgata (lac.)" {
t.Errorf(`GatherVersion(..., "pl") label = %q, want "Wulgata (lac.)"`, label)
}
label, _ = GatherVersion("vul", sec, "new", "en")
if label != "Vulgate (Latin)" {
t.Errorf(`GatherVersion(..., "en") label = %q, want "Vulgate (Latin)"`, label)
}
}
// TestCompareLabelLang checks Compare's column-header row follows lang,
// same as GatherVersion (which it wraps via compareSection).
func TestCompareLabelLang(t *testing.T) {
sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"}
out := Compare([]liturgy.Section{sec}, []string{"vul"}, 80, "new", "pl")
if !strings.Contains(out, "Wulgata (lac.)") {
t.Errorf(`Compare(..., "pl") = %q, want it to contain "Wulgata (lac.)"`, out)
}
out = Compare([]liturgy.Section{sec}, []string{"vul"}, 80, "new", "en")
if !strings.Contains(out, "Vulgate (Latin)") {
t.Errorf(`Compare(..., "en") = %q, want it to contain "Vulgate (Latin)"`, out)
}
}
// TestGatherVersionNoVersionLang checks that the "(not in %s)" block
// (bible.Lookup finding nothing at all) follows lang -- pl reproduces the
// original Polish wording exactly, en uses internal/i18n's English wording.
func TestGatherVersionNoVersionLang(t *testing.T) {
sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"}
_, blocks := GatherVersion("zzz", sec, "new", "pl")
if len(blocks) == 0 || blocks[0] != `(brak w „zzz”)` {
t.Errorf(`GatherVersion(..., "pl") blocks = %v, want [(brak w „zzz”)]`, blocks)
}
_, blocks = GatherVersion("zzz", sec, "new", "en")
if len(blocks) == 0 || blocks[0] != "(not in zzz)" {
t.Errorf(`GatherVersion(..., "en") blocks = %v, want [(not in zzz)]`, blocks)
}
}
// TestGatherVersionNoReferenceLang checks the "(no reference)" block (no
// citation resolvable at all) follows lang.
func TestGatherVersionNoReferenceLang(t *testing.T) {
sec := liturgy.Section{Heading: "Bez odwołania"}
_, blocks := GatherVersion("wuj", sec, "new", "pl")
if len(blocks) == 0 || blocks[0] != "(brak odwołania)" {
t.Errorf(`GatherVersion(..., "pl") blocks = %v, want [(brak odwołania)]`, blocks)
}
_, blocks = GatherVersion("wuj", sec, "new", "en")
if len(blocks) == 0 || blocks[0] != "(no reference)" {
t.Errorf(`GatherVersion(..., "en") blocks = %v, want [(no reference)]`, blocks)
}
}
func TestOfflineVersions(t *testing.T) {
got := OfflineVersions([]string{"bt", "wuj", "vul"})
for _, v := range got {
if v == "bt" {
t.Error("bt not dropped offline")
}
}
}
func TestGatherVersesBible(t *testing.T) {
sec := liturgy.Section{Heading: "Ewangelia", Citation: "J 20, 1. 11-18", Ref: "John 20:1,11-18"}
label, verses, versified := GatherVerses("wuj", sec, "new", "pl")
if !strings.Contains(label, "Wujek") {
t.Errorf("label = %q", label)
}
if !versified {
t.Error("versified = false, want true for wuj with a resolvable citation")
}
if len(verses) == 0 {
t.Fatal("verses empty")
}
if verses[0].Chapter != 20 || verses[0].Verse != 1 || verses[0].Text == "" {
t.Errorf("verses[0] = %+v", verses[0])
}
}
func TestGatherVersesBT(t *testing.T) {
sec := liturgy.Section{
Heading: "Psalm (Ps 1)",
Paragraphs: [][]string{{"stanza one"}},
}
_, verses, versified := GatherVerses("bt", sec, "new", "pl")
if versified {
t.Error("versified = true, want false for bt (paragraph text, no verse numbers)")
}
if verses != nil {
t.Errorf("verses = %+v, want nil for bt", verses)
}
}
// TestGatherVersesLabelLang checks GatherVerses' label also follows lang,
// same as GatherVersion.
func TestGatherVersesLabelLang(t *testing.T) {
sec := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)"}
label, _, _ := GatherVerses("vul", sec, "new", "en")
if label != "Vulgate (Latin)" {
t.Errorf(`GatherVerses(..., "en") label = %q, want "Vulgate (Latin)"`, label)
}
}
// TestLocalizeHeading covers render.LocalizeHeading's part-label swap
// (brief §3b): the pl label prefix of a modern (niedziela.pl) heading is
// replaced by its en label, the citation kept exactly as scraped, and every
// other case (pl, unknown/traditional partID, prefix mismatch) is a safe
// no-op that returns heading unchanged.
func TestHeadingWithRef(t *testing.T) {
// Traditional-style: a bare label plus Citation -> reference appended.
trad := liturgy.Section{Heading: "Gospel", Citation: "Luke 16:1-9", PartID: "evangelium"}
if got := HeadingWithRef(trad, "en"); got != "Gospel (Luke 16:1-9)" {
t.Errorf("traditional heading = %q, want %q", got, "Gospel (Luke 16:1-9)")
}
// Modern-style: heading already carries "(...)" -> not doubled; the pl label
// is still localised to en.
modern := liturgy.Section{Heading: "Ewangelia (J 20, 1. 11-18)", Citation: "J 20, 1. 11-18", PartID: "ewangelia"}
if got := HeadingWithRef(modern, "en"); got != "Gospel (J 20, 1. 11-18)" {
t.Errorf("modern heading = %q", got)
}
// No citation -> unchanged.
if got := HeadingWithRef(liturgy.Section{Heading: "Gospel", PartID: "evangelium"}, "en"); got != "Gospel" {
t.Errorf("no-citation heading = %q", got)
}
}
func TestLocalizeHeading(t *testing.T) {
cases := []struct {
name, heading, partID, lang, want string
}{
{"gospel en", "Ewangelia (J 20, 1. 11-18)", "ewangelia", "en", "Gospel (J 20, 1. 11-18)"},
{"first reading en", "1. czytanie (Dz 2, 14. 22-33)", "pierwsze_czytanie", "en", "1st reading (Dz 2, 14. 22-33)"},
{"psalm en", "Psalm (Ps 15)", "psalm", "en", "Psalm (Ps 15)"},
{"acclamation en", "Aklamacja (Alleluja)", "aklamacja", "en", "Acclamation (Alleluja)"},
{"pl unchanged", "Ewangelia (J 20, 1. 11-18)", "ewangelia", "pl", "Ewangelia (J 20, 1. 11-18)"},
{"unknown partID unchanged", "Coś innego (X 1)", "", "en", "Coś innego (X 1)"},
{"already-English heading unchanged (traditional lectionary, no pl prefix to match)", "Gospel (Luke 7:36-50)", "ewangelia", "en", "Gospel (Luke 7:36-50)"},
{"prefix mismatch unchanged", "Nieoczekiwany tytuł (J 1)", "ewangelia", "en", "Nieoczekiwany tytuł (J 1)"},
// Split (two-reading) feast day: niedziela.pl scrapes
// PartID="drugie_czytanie" onto a heading that still literally
// starts with "1. czytanie" (its own numbering quirk). Matching
// must follow the heading's actual text, not partID's label, so
// this localises to "1st reading", not staying Polish.
{"drugie_czytanie partID with a 1. czytanie heading (split feast day)", "1. czytanie (Dz 2, 14. 22-33)", "drugie_czytanie", "en", "1st reading (Dz 2, 14. 22-33)"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := LocalizeHeading(c.heading, c.partID, c.lang)
if got != c.want {
t.Errorf("LocalizeHeading(%q, %q, %q) = %q, want %q", c.heading, c.partID, c.lang, got, c.want)
}
})
}
}
|