mirror of
https://github.com/pupperpowell/bibdle.git
synced 2026-04-05 17:33:31 -04:00
146 tests covering evaluateGuess, grading, ordinals, bible data integrity, section counts, share text generation, and stat string helpers. Also fixes toOrdinal for 111-113 (was using >= 11 && <= 13 instead of % 100 check). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
235 lines
6.0 KiB
TypeScript
235 lines
6.0 KiB
TypeScript
import { describe, test, expect } from "bun:test";
|
|
import {
|
|
getBookById,
|
|
getBookByNumber,
|
|
getBooksByTestament,
|
|
getBooksBySection,
|
|
isAdjacent,
|
|
bookNumberToId,
|
|
bookIdToNumber,
|
|
bibleBooks,
|
|
} from "$lib/server/bible";
|
|
|
|
describe("bibleBooks data integrity", () => {
|
|
test("contains exactly 66 books", () => {
|
|
expect(bibleBooks).toHaveLength(66);
|
|
});
|
|
|
|
test("order numbers are 1 through 66 with no gaps or duplicates", () => {
|
|
const orders = bibleBooks.map((b) => b.order).sort((a, b) => a - b);
|
|
for (let i = 0; i < 66; i++) {
|
|
expect(orders[i]).toBe(i + 1);
|
|
}
|
|
});
|
|
|
|
test("book IDs are unique", () => {
|
|
const ids = bibleBooks.map((b) => b.id);
|
|
const unique = new Set(ids);
|
|
expect(unique.size).toBe(66);
|
|
});
|
|
|
|
test("every book has a non-empty name", () => {
|
|
for (const book of bibleBooks) {
|
|
expect(book.name.length).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
|
|
test("Old Testament has 39 books", () => {
|
|
expect(bibleBooks.filter((b) => b.testament === "old")).toHaveLength(39);
|
|
});
|
|
|
|
test("New Testament has 27 books", () => {
|
|
expect(bibleBooks.filter((b) => b.testament === "new")).toHaveLength(27);
|
|
});
|
|
|
|
test("Genesis is first and Revelation is last", () => {
|
|
const sorted = [...bibleBooks].sort((a, b) => a.order - b.order);
|
|
expect(sorted[0].id).toBe("GEN");
|
|
expect(sorted[65].id).toBe("REV");
|
|
});
|
|
|
|
test("Matthew is the first New Testament book", () => {
|
|
const nt = bibleBooks
|
|
.filter((b) => b.testament === "new")
|
|
.sort((a, b) => a.order - b.order);
|
|
expect(nt[0].id).toBe("MAT");
|
|
});
|
|
});
|
|
|
|
describe("section counts", () => {
|
|
test("Law: 5 books", () => {
|
|
expect(getBooksBySection("Law")).toHaveLength(5);
|
|
});
|
|
|
|
test("History: 13 books (12 OT + Acts)", () => {
|
|
expect(getBooksBySection("History")).toHaveLength(13);
|
|
});
|
|
|
|
test("Wisdom: 5 books", () => {
|
|
expect(getBooksBySection("Wisdom")).toHaveLength(5);
|
|
});
|
|
|
|
test("Major Prophets: 5 books", () => {
|
|
expect(getBooksBySection("Major Prophets")).toHaveLength(5);
|
|
});
|
|
|
|
test("Minor Prophets: 12 books", () => {
|
|
expect(getBooksBySection("Minor Prophets")).toHaveLength(12);
|
|
});
|
|
|
|
test("Gospels: 4 books", () => {
|
|
expect(getBooksBySection("Gospels")).toHaveLength(4);
|
|
});
|
|
|
|
test("Pauline Epistles: 13 books", () => {
|
|
expect(getBooksBySection("Pauline Epistles")).toHaveLength(13);
|
|
});
|
|
|
|
test("General Epistles: 8 books", () => {
|
|
expect(getBooksBySection("General Epistles")).toHaveLength(8);
|
|
});
|
|
|
|
test("Apocalyptic: 1 book (Revelation)", () => {
|
|
const books = getBooksBySection("Apocalyptic");
|
|
expect(books).toHaveLength(1);
|
|
expect(books[0].id).toBe("REV");
|
|
});
|
|
|
|
test("all sections sum to 66", () => {
|
|
const total =
|
|
getBooksBySection("Law").length +
|
|
getBooksBySection("History").length +
|
|
getBooksBySection("Wisdom").length +
|
|
getBooksBySection("Major Prophets").length +
|
|
getBooksBySection("Minor Prophets").length +
|
|
getBooksBySection("Gospels").length +
|
|
getBooksBySection("Pauline Epistles").length +
|
|
getBooksBySection("General Epistles").length +
|
|
getBooksBySection("Apocalyptic").length;
|
|
expect(total).toBe(66);
|
|
});
|
|
});
|
|
|
|
describe("getBookById", () => {
|
|
test("returns Genesis for GEN", () => {
|
|
const book = getBookById("GEN");
|
|
expect(book).toBeDefined();
|
|
expect(book!.name).toBe("Genesis");
|
|
});
|
|
|
|
test("returns Revelation for REV", () => {
|
|
const book = getBookById("REV");
|
|
expect(book!.name).toBe("Revelation");
|
|
});
|
|
|
|
test("returns undefined for unknown ID", () => {
|
|
expect(getBookById("UNKNOWN")).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("getBookByNumber", () => {
|
|
test("1 → Genesis", () => {
|
|
expect(getBookByNumber(1)!.id).toBe("GEN");
|
|
});
|
|
|
|
test("66 → Revelation", () => {
|
|
expect(getBookByNumber(66)!.id).toBe("REV");
|
|
});
|
|
|
|
test("40 → Matthew (first NT book)", () => {
|
|
expect(getBookByNumber(40)!.id).toBe("MAT");
|
|
});
|
|
|
|
test("0 → undefined", () => {
|
|
expect(getBookByNumber(0)).toBeUndefined();
|
|
});
|
|
|
|
test("67 → undefined", () => {
|
|
expect(getBookByNumber(67)).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("getBooksByTestament", () => {
|
|
test("old returns 39 books", () => {
|
|
expect(getBooksByTestament("old")).toHaveLength(39);
|
|
});
|
|
|
|
test("new returns 27 books", () => {
|
|
expect(getBooksByTestament("new")).toHaveLength(27);
|
|
});
|
|
|
|
test("all OT books have testament = old", () => {
|
|
for (const book of getBooksByTestament("old")) {
|
|
expect(book.testament).toBe("old");
|
|
}
|
|
});
|
|
|
|
test("all NT books have testament = new", () => {
|
|
for (const book of getBooksByTestament("new")) {
|
|
expect(book.testament).toBe("new");
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("isAdjacent", () => {
|
|
test("Genesis and Exodus are adjacent", () => {
|
|
expect(isAdjacent("GEN", "EXO")).toBe(true);
|
|
});
|
|
|
|
test("adjacency is symmetric", () => {
|
|
expect(isAdjacent("EXO", "GEN")).toBe(true);
|
|
});
|
|
|
|
test("Malachi and Matthew are adjacent across testament boundary", () => {
|
|
expect(isAdjacent("MAL", "MAT")).toBe(true); // 39, 40
|
|
});
|
|
|
|
test("Jude and Revelation are adjacent", () => {
|
|
expect(isAdjacent("JUD", "REV")).toBe(true); // 65, 66
|
|
});
|
|
|
|
test("same book is not adjacent to itself", () => {
|
|
expect(isAdjacent("GEN", "GEN")).toBe(false);
|
|
});
|
|
|
|
test("books two apart are not adjacent", () => {
|
|
expect(isAdjacent("GEN", "LEV")).toBe(false); // 1, 3
|
|
});
|
|
|
|
test("returns false for invalid IDs", () => {
|
|
expect(isAdjacent("FAKE", "GEN")).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("bookNumberToId / bookIdToNumber lookup tables", () => {
|
|
test("bookNumberToId[1] is GEN", () => {
|
|
expect(bookNumberToId[1]).toBe("GEN");
|
|
});
|
|
|
|
test("bookNumberToId[66] is REV", () => {
|
|
expect(bookNumberToId[66]).toBe("REV");
|
|
});
|
|
|
|
test("bookIdToNumber['GEN'] is 1", () => {
|
|
expect(bookIdToNumber["GEN"]).toBe(1);
|
|
});
|
|
|
|
test("bookIdToNumber['REV'] is 66", () => {
|
|
expect(bookIdToNumber["REV"]).toBe(66);
|
|
});
|
|
|
|
test("round-trip: number → ID → number", () => {
|
|
for (let i = 1; i <= 66; i++) {
|
|
const id = bookNumberToId[i];
|
|
expect(bookIdToNumber[id]).toBe(i);
|
|
}
|
|
});
|
|
|
|
test("round-trip: ID → number → ID", () => {
|
|
for (const book of bibleBooks) {
|
|
const num = bookIdToNumber[book.id];
|
|
expect(bookNumberToId[num]).toBe(book.id);
|
|
}
|
|
});
|
|
});
|