bible-reference-formatter
Version:
Utility that converts Bible references from OSIS to human-readable formats and Paratext.
416 lines (358 loc) • 17.6 kB
JavaScript
/* global require, describe, it, expect, beforeEach */
const osisToReadable = require("../es6/osisToReadable")
const c = new osisToReadable
function resetBooks() {
c.setBooks({
"Gen": ["Gen."],
"Ps": ["Ps.", "Pss.", "Psalms"],
"Ps.$chapters": ["Ps.", "Pss."],
"Ps151": ["Ps. 151"],
"AddPs": ["Ps. 151"],
"Matt": ["Matt."],
"Luke": ["Luke"],
"Phlm": ["Philem."],
"Heb": ["Heb. S.", "Heb. P."],
"1John": ["1 John"],
"2John": ["2 John"],
"3John": ["3 John"],
"Rev": ["Rev."],
"1John-3John": ["1\u20143 John"],
"1John-2John": ["1\u20142 John"],
"2John-3John": ["2\u20143 John"],
"1John,2John": ["1 and 2 John"],
"2John,3John": ["2 and 3 John"],
"1John,3John": ["1 and 3 John"],
"1John,2John,3John": ["1, 2, and 3 John"]
})
}
function setOptions(newOptions={}) {
const options = {
"^v": "$verses ",
"^c": "$chapters ",
"b1^v": "$verses ",
"b1^c": "$b ",
//"^cv": "",
"$chapters": ["ch.", "chs."],
"$verses": ["v.", "vv."],
"-b": "\u2014", // Matt-Mark
"-c": "\u2013", // Matt-Matt.3
"-v": "\u2013", // Phlm-Phlm.1.2
"c-v": "-$verses ", // Matt.1-Matt.1.2
"v-c": "\u2013$chapters ", // Matt.1.1-Matt.3
"v-cv": "\u2013", // Matt.1.1-Matt.3.4
"v-v": "-", // Matt.1.1-Matt.1.2
",b": "; ", // Matt,Mark
",c": "; ", // Matt,Matt.3
"b,v": "; $b ", // Phlm,Phlm.1.2
"v,c": "; $chapters ",
"v,cv": "; ",
"bc,v": ", $c:",
"c,v": ", $c:",
".c": " ", // Matt.1
".v": ":", // (Matt.)1.1
"b.v": " " // Phlm.(1.)2
}
for (const key of Object.keys(newOptions)) {
options[key] = newOptions[key]
}
c.setOptions(options)
}
resetBooks()
describe("Initialization", function() {
it("should initialize", function() {
expect(c.toReadable("Matt")).toEqual("Matt.")
})
})
describe("Basic parsing", function() {
beforeEach(function() {
setOptions()
})
it("should handle multi-chapter books", function() {
expect(c.toReadable("Matt.1.2-Matt.1.3,Matt.1.4,Matt.1.5,Matt.8.6-Luke.2.3")).toEqual("Matt. 1:2-3, 4, 5; 8:6\u2014Luke 2:3")
expect(c.toReadable("Matt.1.2-Phlm.1.3")).toEqual("Matt. 1:2\u2014Philem. 3")
expect(c.toReadable("Matt.8.6-Matt.9")).toEqual("Matt. 8:6\u2013ch. 9")
expect(c.toReadable("Matt.8.6,Matt.9-Matt.10")).toEqual("Matt. 8:6; chs. 9\u201310")
expect(c.toReadable("Matt.8,Matt.8.6-Matt.8.7,Matt.8.9")).toEqual("Matt. 8, 8:6-7, 9")
expect(c.toReadable("Matt.1.4-Phlm.1")).toEqual("Matt. 1:4\u2014Philem. 1")
expect(c.toReadable("Matt-Luke")).toEqual("Matt.\u2014Luke")
expect(c.toReadable("Matt.1,Luke.1")).toEqual("Matt. 1; Luke 1")
expect(c.toReadable("Matt.1.1,Luke.1.1")).toEqual("Matt. 1:1; Luke 1:1")
expect(c.toReadable("Matt.1,Matt.1.2-Matt.1.3")).toEqual("Matt. 1, 1:2-3")
expect(c.toReadable("Matt.2-Matt.2.3")).toEqual("Matt. 2-v. 3")
})
it("should handle single-chapter books", function() {
expect(c.toReadable("Phlm.1")).toEqual("Philem. 1")
expect(c.toReadable("Phlm.1-Rev")).toEqual("Philem. 1\u2014Rev.")
expect(c.toReadable("Phlm.1.4-Phlm.1")).toEqual("Philem. 4\u2013ch. 1")
expect(c.toReadable("Phlm.1.2-Phlm.1.3")).toEqual("Philem. 2-3")
expect(c.toReadable("Phlm,Phlm.1.2")).toEqual("Philem.; Philem. 2")
})
it("should handle single-chapter books with `bcv`", function() {
setOptions({singleChapterFormat: "bcv"})
expect(c.toReadable("Phlm.1")).toEqual("Philem. 1")
expect(c.toReadable("Phlm.1-Rev")).toEqual("Philem. 1\u2014Rev.")
expect(c.toReadable("Phlm.1.4-Phlm.1")).toEqual("Philem. 1:4\u2013ch. 1")
expect(c.toReadable("Phlm.1.2-Phlm.1.3")).toEqual("Philem. 1:2-3")
expect(c.toReadable("Phlm,Phlm.1.2")).toEqual("Philem.; 1:2")
})
it("should handle Psalms", function() {
expect(c.toReadable("Ps.1.2-Ps.1.3")).toEqual("Ps. 1:2-3")
expect(c.toReadable("Ps.1")).toEqual("Ps. 1")
expect(c.toReadable("Ps.1-Ps.2")).toEqual("Pss. 1\u20132")
expect(c.toReadable("Ps.1,Ps.2")).toEqual("Pss. 1; 2")
expect(c.toReadable("Ps.1,Matt.2,Ps.3")).toEqual("Ps. 1; Matt. 2; Ps. 3")
expect(c.toReadable("Ps.1,Ps.2.2-Ps.2.3")).toEqual("Pss. 1; 2:2-3")
expect(c.toReadable("Ps.1.1-Ps.2.3")).toEqual("Pss. 1:1\u20132:3")
expect(c.toReadable("Ps.1.1-Matt.2.3")).toEqual("Pss. 1:1\u2014Matt. 2:3")
expect(c.toReadable("Ps.1,Ps.2.4,Ps.3-Ps.4")).toEqual("Pss. 1; 2:4; Pss. 3\u20134")
expect(c.toReadable("Ps.1,Ps.2.2-Ps.3")).toEqual("Pss. 1; 2:2\u2013Ps. 3")
expect(c.toReadable("Ps.1.2-Ps.3,Ps.4")).toEqual("Pss. 1:2\u2013Pss. 3; 4")
expect(c.toReadable("Ps.1.2,Ps.3,Ps.4")).toEqual("Pss. 1:2; Pss. 3; 4") // `Ps. 1:2` would be better.
expect(c.toReadable("Ps.1,Ps.3,Ps.4", "Ps")).toEqual("Pss. 1; 3; 4", "Ps")
expect(c.toReadable("Ps.1,Ps.3,Ps.4", "Ps.1")).toEqual("Pss. 1; 3; 4", "Ps")
})
it("should handle Psalm ranges", function() {
expect(c.toReadable("Ps.149-Matt.1")).toEqual("Pss. 149\u2014Matt. 1")
expect(c.toReadable("Ps.150-Matt.1")).toEqual("Ps. 150\u2014Matt. 1")
})
it("should handle a range as a context argument", function() {
expect(c.toReadable("Ps.3.2,Ps.1.3,Ps.1.4", "Ps.1-Ps.3")).toEqual("v. 2; 1:3, 4")
})
it("should handle chapter start contexts", function () {
expect(c.toReadable("Matt.2-Matt.2.3", "Matt.1")).toEqual("ch. 2-v. 3")
expect(c.toReadable("Matt.2-Matt.3.3", "Matt.1")).toEqual("chs. 2\u20133:3")
expect(c.toReadable("Matt.2-Matt.3.3,Matt.4", "Matt.1")).toEqual("chs. 2\u20133:3; ch. 4")
expect(c.toReadable("Matt.2-Matt.3,Matt.4", "Matt.1")).toEqual("chs. 2\u20133; 4")
expect(c.toReadable("Matt.2,Matt.4", "Matt.1")).toEqual("chs. 2; 4")
})
it("should handle verse start contexts", function () {
expect(c.toReadable("Matt.1.2-Matt.2.3", "Matt.1")).toEqual("vv. 2\u20132:3")
expect(c.toReadable("Matt.1.2-Matt.1.3", "Matt.1")).toEqual("vv. 2-3")
expect(c.toReadable("Matt.1.2-Matt.1.3,Matt.1.4", "Matt.1")).toEqual("vv. 2-3, 4")
expect(c.toReadable("Matt.1.2-Matt.1.3,Matt.4", "Matt.1")).toEqual("vv. 2-3; ch. 4")
expect(c.toReadable("Matt.1.2,Matt.1.4", "Matt.1")).toEqual("vv. 2, 4")
expect(c.toReadable("Ps.2.2,Ps.2.3", "Ps.2")).toEqual("vv. 2, 3")
})
})
describe("Setting options", function() {
beforeEach(function() {
setOptions()
})
it("should handle adding text to single-chapter books", function() {
setOptions({"b.v": " $verses "}) // Phlm.(1.)2
expect(c.toReadable("Matt.1.2-Phlm.1.3")).toEqual("Matt. 1:2\u2014Philem. v. 3")
expect(c.toReadable("Phlm.1.4-Phlm.1")).toEqual("Philem. vv. 4\u2013ch. 1")
expect(c.toReadable("Phlm.1.2-Phlm.1.3")).toEqual("Philem. vv. 2-3")
expect(c.toReadable("Phlm.1.2,Phlm.1.3,Phlm.1.4", "Phlm.1.2")).toEqual("vv. 2, 3, 4")
expect(c.toReadable("Phlm.1.2,Phlm.1.3,Phlm.1.4", "Phlm.1")).toEqual("vv. 2, 3, 4")
expect(c.toReadable("Phlm.1.2,Phlm.1.3,Phlm.1.4", "Phlm")).toEqual("vv. 2, 3, 4")
expect(c.toReadable("Phlm.1,Phlm", "Phlm.1.2-Phlm.1.2")).toEqual("Philem. 1; Philem.")
expect(c.toReadable("Phlm.1,Phlm", "Phlm.1-Phlm.1")).toEqual("Philem. 1; Philem.")
expect(c.toReadable("Phlm.1,Phlm", "Phlm-Phlm")).toEqual("Philem. 1; Philem.")
})
it("should handle adding text to multi-chapter books", function() {
setOptions({"b.v": " $verses "}) // Phlm.(1.)2
expect(c.toReadable("Matt.1.2-Matt.1.4", "Matt.1.2")).toEqual("vv. 2-4")
expect(c.toReadable("Matt.1.2,Matt.1.3,Matt.1.4", "Matt.1.2")).toEqual("vv. 2, 3, 4")
expect(c.toReadable("Matt.1.2,Matt.1.3,Matt.1.4", "Matt.1")).toEqual("vv. 2, 3, 4")
expect(c.toReadable("Matt.1.2,Matt.1.3,Matt.1.4", "Matt")).toEqual("1:2, 3, 4")
expect(c.toReadable("Matt.1,Matt.2,Matt.3", "Matt.1.2")).toEqual("chs. 1; 2; 3")
expect(c.toReadable("Matt.1,Matt.2,Matt.3", "Matt.1")).toEqual("chs. 1; 2; 3")
expect(c.toReadable("Matt.1,Matt.2,Matt.3", "Matt")).toEqual("chs. 1; 2; 3")
})
it("should handle adding text to Psalms", function() {
setOptions({"b.v": " $verses "}) // Phlm.(1.)2
expect(c.toReadable("Ps.1.2-Ps.1.4", "Ps.1.2")).toEqual("vv. 2-4")
expect(c.toReadable("Ps.1.2,Ps.1.3,Ps.1.4", "Ps.1.2")).toEqual("vv. 2, 3, 4")
expect(c.toReadable("Ps.1.2,Ps.1.3,Ps.1.4", "Ps.2")).toEqual("1:2, 3, 4")
expect(c.toReadable("Ps.1.2,Ps.1.3,Ps.1.4", "Ps")).toEqual("1:2, 3, 4")
expect(c.toReadable("Ps.1,Ps.2-Ps.4", "Ps.5")).toEqual("Pss. 1; 2\u20134")
expect(c.toReadable("Ps.1,Ps.2-Ps.4", "Ps.5.5")).toEqual("Pss. 1; 2\u20134")
expect(c.toReadable("Ps.1,Ps.2-Ps.4", "Ps")).toEqual("Pss. 1; 2\u20134")
})
it("should handle a single chapter option", function() {
setOptions({"$chapters": ["chapter"]})
expect(c.toReadable("Matt.2-Matt.3", "Matt")).toEqual("chapter 2\u20133")
expect(c.toReadable("Matt.2", "Matt")).toEqual("chapter 2")
})
it("should handle a single verse option", function() {
setOptions({"$verses": ["v."]})
expect(c.toReadable("Ps.1.2-Ps.1.3", "Ps.1")).toEqual("v. 2-3")
})
it("should handle an odd `$chapters`", function() {
setOptions({"c.v": " $chapters "})
expect(c.toReadable("Matt.2.3,Matt.2.4", "Matt")).toEqual("2 ch. 3, 4")
expect(c.toReadable("Matt.3.3,Matt.4.4")).toEqual("Matt. 3 ch. 3; 4 ch. 4")
})
it("should handle multiple `$chapters` replacements", function() {
setOptions({"b.c": " $chapters $chapters "})
expect(c.toReadable("Matt.2.3,Ps.2.4")).toEqual("Matt. ch. ch. 2:3; Ps. Ps. Ps. 2:4")
expect(c.toReadable("Matt.3.3,Matt.4.4")).toEqual("Matt. chs. chs. 3:3; 4:4")
})
it("should handle multiple `$verses` replacements", function() {
setOptions({"c.v": " $verses $verses "})
expect(c.toReadable("Matt.2.3,Ps.2.4")).toEqual("Matt. 2 v. v. 3; Ps. 2 v. v. 4")
expect(c.toReadable("Matt.3.3,Matt.4.4")).toEqual("Matt. 3 v. v. 3; 4 v. v. 4")
})
it("should handle multiple `$b` replacements", function() {
setOptions({"b.c": " ($b $b) "})
expect(c.toReadable("Matt.2.3,Ps.2.4")).toEqual("Matt. (Matt. Matt.) 2:3; Ps. (Ps. Ps.) 2:4")
expect(c.toReadable("Matt.3.3,Matt.4.4")).toEqual("Matt. (Matt. Matt.) 3:3; 4:4")
})
it("should return an empty string for `$c` and `$v` when they're not defined", function() {
setOptions({"b.c": " (chapter $c $c) ", "c.v": " (verse $v $v) "})
expect(c.toReadable("Matt.2.3,Ps.2.4")).toEqual("Matt. (chapter ) 2 (verse ) 3; Ps. (chapter ) 2 (verse ) 4")
expect(c.toReadable("Matt.3.3,Matt.3.4")).toEqual("Matt. (chapter ) 3 (verse ) 3, 4")
})
it("should handle `singleChapterFormat = \"b\"` with the same book", function () {
setOptions({"singleChapterFormat": "b", "b1^v": "$b V ", "b-v": "\u2014$b R "})
expect(c.toReadable("Phlm-Phlm.1")).toEqual("Philem.\u2014Philem\.")
expect(c.toReadable("Phlm-Phlm.1.2")).toEqual("Philem.\u2014Philem\. R 2")
expect(c.toReadable("Phlm,Phlm.1")).toEqual("Philem.; Philem\.")
expect(c.toReadable("Phlm,Phlm.1.3")).toEqual("Philem.; Philem\. 3")
expect(c.toReadable("Phlm.1", "Phlm")).toEqual("Philem\.")
expect(c.toReadable("Phlm.1.4", "Phlm")).toEqual("Philem\. V 4")
expect(c.toReadable("Phlm.1", "Phlm.1")).toEqual("Philem\.")
expect(c.toReadable("Phlm.1.4", "Phlm.1")).toEqual("Philem\. V 4")
})
it("should handle `singleChapterFormat = \"b\"` with a different book", function () {
setOptions({"singleChapterFormat": "b", "b1^v": "$b V ", "b-v": "\u2014$b R "})
expect(c.toReadable("Matt-Phlm.1")).toEqual("Matt.\u2014Philem\.")
expect(c.toReadable("Matt-Phlm.1.2")).toEqual("Matt.\u2014Philem\. 2")
expect(c.toReadable("Matt,Phlm.1")).toEqual("Matt.; Philem\.")
expect(c.toReadable("Matt,Phlm.1.3")).toEqual("Matt.; Philem\. 3")
expect(c.toReadable("Phlm.1", "Matt")).toEqual("Philem\.")
expect(c.toReadable("Phlm.1.4", "Matt")).toEqual("Philem\. 4")
expect(c.toReadable("Phlm.1", "Matt.1")).toEqual("Philem\.")
expect(c.toReadable("Phlm.1.4", "Matt.1")).toEqual("Philem\. 4")
})
it("should show the plural when looking at the whole book of Psalms", function() {
expect(c.toReadable("Ps")).toEqual("Psalms")
expect(c.toReadable("Heb")).toEqual("Heb. P.")
expect(c.toReadable("Phlm")).toEqual("Philem.")
})
})
describe("Psalm 151", function() {
beforeEach(function() {
setOptions()
})
it("should handle Ps151 as a `bc`", function() {
setOptions({"b.v": " $verses ", "Ps151Format": "bc"})
expect(c.toReadable("Ps.1-Ps151")).toEqual("Pss. 1\u2013151")
expect(c.toReadable("Ps.1.2-Ps151")).toEqual("Pss. 1:2\u2013Ps. 151")
expect(c.toReadable("Ps151")).toEqual("Ps. 151")
expect(c.toReadable("Ps151.1")).toEqual("Ps. 151")
expect(c.toReadable("Ps151.1.2-Ps151.1.3")).toEqual("Ps. 151:2-3")
expect(c.toReadable("Ps151-Matt.1")).toEqual("Ps. 151\u2014Matt. 1")
expect(c.toReadable("Ps151.1-Matt.1")).toEqual("Ps. 151\u2014Matt. 1")
expect(c.toReadable("Ps151.1.1-Matt.1")).toEqual("Ps. 151:1\u2014Matt. 1")
})
it("should handle Ps151 as a `b` with `singleChapterFormat: bv`", function() {
setOptions({"Ps151Format": "b", "singleChapterFormat": "bv" })
expect(c.toReadable("Ps.1-Ps151")).toEqual("Pss. 1\u2014Ps. 151")
expect(c.toReadable("Ps.1.2-Ps151")).toEqual("Pss. 1:2\u2014Ps. 151")
expect(c.toReadable("Ps151")).toEqual("Ps. 151")
expect(c.toReadable("Ps151.1")).toEqual("Ps. 151 1")
expect(c.toReadable("Ps151.1.3-Ps151.1.4")).toEqual("Ps. 151 3-4")
expect(c.toReadable("Ps151-Matt.1")).toEqual("Ps. 151\u2014Matt. 1")
expect(c.toReadable("Ps151.1-Matt.1")).toEqual("Ps. 151 1\u2014Matt. 1")
expect(c.toReadable("Ps151.1.1-Matt.1")).toEqual("Ps. 151 1\u2014Matt. 1")
})
it("should handle Ps151 as a `b` with `singleChapterFormat: bcv`", function() {
setOptions({"Ps151Format": "b", "singleChapterFormat": "bcv"})
expect(c.toReadable("Ps151.1.4-Ps151.1.5")).toEqual("Ps. 151 1:4-5")
expect(c.toReadable("Ps151-Matt.1")).toEqual("Ps. 151\u2014Matt. 1")
expect(c.toReadable("Ps151.1-Matt.1")).toEqual("Ps. 151 1\u2014Matt. 1")
expect(c.toReadable("Ps151.1.1-Matt.1")).toEqual("Ps. 151 1:1\u2014Matt. 1")
})
})
describe("Exceptions", function() {
beforeEach(function() {
setOptions()
})
it("should not accept a sequence as a context argument", function() {
expect(() => c.toReadable("Ps.1.2", "Ps.2,Ps.3")).toThrow()
})
it("should not accept a non-string as a first argument", function() {
expect(() => c.toReadable(1, "Ps.1")).toThrow()
expect(() => c.toReadable([], "Ps.1")).toThrow()
expect(() => c.toReadable({}, "Ps.1")).toThrow()
})
it("should not accept a non-string as a second argument", function() {
expect(() => c.toReadable("Ps.2", 1)).toThrow()
expect(() => c.toReadable("Ps.2", [])).toThrow()
expect(() => c.toReadable("Ps.2", {})).toThrow()
})
it("should not accept an invalid OSIS as as first argument", function() {
expect(() => c.toReadable("Ps 2")).toThrow()
expect(() => c.toReadable("")).toThrow()
expect(() => c.toReadable("Book.2")).toThrow()
expect(() => c.toReadable("Matt.")).toThrow()
expect(() => c.toReadable("Matt.1.")).toThrow()
expect(() => c.toReadable("Matt.1.-")).toThrow()
expect(() => c.toReadable("Matt.1-")).toThrow()
})
it("should not accept an invalid OSIS as as second argument", function() {
expect(() => c.toReadable("Matt.1", "Ps 2")).toThrow()
expect(() => c.toReadable("Matt.1", "")).toThrow()
expect(() => c.toReadable("Matt.1", "Book.2")).toThrow()
expect(() => c.toReadable("Matt.1", "Matt.")).toThrow()
expect(() => c.toReadable("Matt.1", "Matt.1.")).toThrow()
expect(() => c.toReadable("Matt.1", "Matt.1.-")).toThrow()
expect(() => c.toReadable("Matt.1", "Matt.1-")).toThrow()
})
it("should not accept an invalid type when setting options", function() {
expect(c.setOptions("")).not.toBeDefined()
expect(() => c.setOptions({singleChapterBooks: "Phlm"})).toThrow()
expect(() => c.setOptions({singleChapterFormat: ["bv"]})).toThrow()
})
it("should not accept an empty `setOptions()` call", function() {
expect(c.setOptions()).not.toBeDefined()
})
})
describe("Multiple objects", function() {
beforeEach(function() {
setOptions()
})
it("should allow multiple objects not to trample each other", function() {
const c1 = new osisToReadable
c1.setBooks({Matt: ["Matt"]})
c1.setOptions({".": "/", "c.v": "/"})
expect(c1.toReadable("Matt.1.1")).toEqual("Matt/1/1")
expect(c.toReadable("Matt.1.1")).toEqual("Matt. 1:1")
})
})
describe("Multiple books by themselves", function() {
beforeEach(function() {
setOptions()
})
it("should handle special book ranges", function() {
expect(c.toReadable("Ps,1John-3John,Matt")).toEqual("Psalms; 1\u20143 John; Matt.")
expect(c.toReadable("Ps,1John-2John,3John")).toEqual("Psalms; 1\u20142 John; 3 John")
expect(c.toReadable("Ps,1John,2John-3John")).toEqual("Psalms; 1 John; 2\u20143 John")
})
it("should handle special book sequences", function() {
expect(c.toReadable("Ps,1John,2John,3John,Matt")).toEqual("Psalms; 1, 2, and 3 John; Matt.")
expect(c.toReadable("Ps,1John,2John,Matt")).toEqual("Psalms; 1 and 2 John; Matt.")
expect(c.toReadable("Ps,2John,3John,3John.1.2,2John,1John,2John")).toEqual("Psalms; 2 and 3 John; 3 John 2; 2 John; 1 and 2 John")
expect(c.toReadable("Ps,Matt,3John,Phlm,Heb,Rev")).toEqual("Psalms; Matt.; 3 John; Philem.; Heb. P.; Rev.")
})
})
describe("setBooks", function() {
beforeEach(function() {
setOptions()
})
it("should not accept a non-array value", function() {
expect(() => c.setBooks("Matt.1")).toThrow()
expect(() => c.setBooks({"a": "Matt.1"})).toThrow()
expect(() => c.setBooks({"a": {}})).toThrow()
})
it("should only accept arrays of lengths 1, 2, or 3", function() {
expect(() => c.setBooks({"a": []})).toThrow()
expect(c.setBooks({"a": ["b"]})).not.toBeDefined()
expect(c.setBooks({"a": ["b", "c"]})).not.toBeDefined()
expect(() => c.setBooks({"a": ["b", "c", "d", "e"]})).toThrow()
})
resetBooks()
})