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 TOML -> non-nil error but a usable defaults table. tbl2, err := LoadBookTable([]byte("this is not [valid toml")) if err == nil { t.Error("expected error for malformed user toml") } if got, ok := tbl2.ParseRef("en", "Jn 3:16"); !ok || got != "John 3:16" { t.Errorf("defaults unusable after malformed user toml: %q,%v", got, ok) } }