summaryrefslogtreecommitdiff
path: root/internal/bible/booktable_test.go
blob: 2fdd89155bfdb3509eed2afed06580d7acc48c21 (plain) (blame)
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
package bible

import (
	"testing"
)

func TestBookTableDefaults(t *testing.T) {
	tbl, err := LoadBookTable(nil)
	if err != nil {
		t.Fatal(err)
	}
	for _, d := range []string{"en", "pl"} {
		if got := len(tbl.Books(d)); got != 73 {
			t.Errorf("Books(%q) len=%d want 73", d, got)
		}
	}
	en := tbl.Books("en")
	if en[0].Canonical != "Genesis" || en[len(en)-1].Canonical != "Revelation" {
		t.Errorf("en order: first=%q last=%q", en[0].Canonical, en[len(en)-1].Canonical)
	}
	// John display: en shortcut "Jn"/name "John"; pl shortcut "J"/name "Jana".
	find := func(bs []BookInfo, canon string) BookInfo {
		for _, b := range bs {
			if b.Canonical == canon {
				return b
			}
		}
		return BookInfo{}
	}
	if b := find(en, "John"); b.Shortcut != "Jn" || b.Name != "John" {
		t.Errorf("en John = %+v", b)
	}
	if b := find(tbl.Books("pl"), "John"); b.Shortcut != "J" || b.Name != "Jana" {
		t.Errorf("pl John = %+v", b)
	}
}

func TestParseRefDialects(t *testing.T) {
	tbl, _ := LoadBookTable(nil)
	cases := []struct {
		dialect, in, want string
		ok                bool
	}{
		{"en", "Jn 3:16", "John 3:16", true},
		{"en", "Jn 5:15-17.20-22", "John 5:15-17,20-22", true},
		{"en", "1 Cor 13:4-7", "1 Corinthians 13:4-7", true},
		{"pl", "J 3,16", "John 3:16", true},
		{"pl", "J 3, 16", "John 3:16", true},
		{"pl", "J 6,6", "John 6:6", true},
		{"pl", "J 5,15-17. 20-22", "John 5:15-17,20-22", true},
		{"pl", "1 Kor 13,4-7", "1 Corinthians 13:4-7", true},
		{"pl", "Łk 1,46-55", "Luke 1:46-55", true},
		// dialect scoping: Polish abbrev/sep must fail in en, English in pl.
		{"en", "Łk 3:16", "", false},
		{"pl", "Lk 3,16", "", false},
		{"en", "Zzz 1:1", "", false},
		{"en", "John", "", false}, // no chapter:verse
	}
	for _, c := range cases {
		got, ok := tbl.ParseRef(c.dialect, c.in)
		if ok != c.ok || got != c.want {
			t.Errorf("ParseRef(%q,%q)=%q,%v want %q,%v", c.dialect, c.in, got, ok, c.want, c.ok)
		}
	}
}

func TestFormatRef(t *testing.T) {
	tbl, _ := LoadBookTable(nil)
	cases := []struct {
		dialect, canonical, want string
	}{
		{"en", "John 20:1,11-18", "Jn 20:1,11-18"},
		{"pl", "John 20:1,11-18", "J 20, 1. 11-18"},
		{"en", "Matthew 13:18-23", "Matt 13:18-23"},
		{"pl", "Matthew 13:18-23", "Mt 13, 18-23"},
		{"en", "Luke 16:1-9", "Lk 16:1-9"},
		// Round-trip: ParseRef then FormatRef in the same dialect is stable.
	}
	for _, c := range cases {
		if got := tbl.FormatRef(c.dialect, c.canonical); got != c.want {
			t.Errorf("FormatRef(%q,%q)=%q want %q", c.dialect, c.canonical, got, c.want)
		}
	}
	// Unparseable / unknown book -> unchanged (safe fallback).
	if got := tbl.FormatRef("en", "not a ref"); got != "not a ref" {
		t.Errorf("unparseable ref should be unchanged, got %q", got)
	}
	// Round-trip through both dialects.
	canon, ok := tbl.ParseRef("pl", "J 20, 1. 11-18")
	if !ok || canon != "John 20:1,11-18" {
		t.Fatalf("ParseRef round-trip canon=%q ok=%v", canon, ok)
	}
	if got := tbl.FormatRef("pl", canon); got != "J 20, 1. 11-18" {
		t.Errorf("pl round-trip = %q", got)
	}
}

func TestBookTableMergeAndMalformed(t *testing.T) {
	// User adds an alias "Jhn" to English John; other books stay default.
	user := []byte("[en]\nJohn = Jn, Jhn, John\n")
	tbl, err := LoadBookTable(user)
	if err != nil {
		t.Fatalf("merge err: %v", err)
	}
	if got, ok := tbl.ParseRef("en", "Jhn 3:16"); !ok || got != "John 3:16" {
		t.Errorf("merged alias: got %q,%v", got, ok)
	}
	if got, ok := tbl.ParseRef("en", "Gen 1:1"); !ok || got != "Genesis 1:1" {
		t.Errorf("unlisted book lost after merge: %q,%v", got, ok)
	}
	// Malformed user INI -> non-nil error but a usable defaults table.
	tbl2, err := LoadBookTable([]byte("this is not valid ini"))
	if err == nil {
		t.Error("expected error for malformed user ini")
	}
	if got, ok := tbl2.ParseRef("en", "Jn 3:16"); !ok || got != "John 3:16" {
		t.Errorf("defaults unusable after malformed user ini: %q,%v", got, ok)
	}
}