98 lines
3.1 KiB
JavaScript
98 lines
3.1 KiB
JavaScript
// validate-structure.js
|
|||
|
|
// Compares verse counts in `bible-structure.js` against actual data in `nlt-data.js`.
|
||
|
|
// Exits with non-zero code if any discrepancies are found.
|
||
|
|
|
||
|
|
import { bibleStructure } from './bible-structure.js';
|
||
|
|
import { nltData } from './nlt-data.js';
|
||
|
|
|
||
|
|
function getSortedNumericKeys(object) {
|
||
|
|
return Object.keys(object)
|
||
|
|
.map((key) => Number(key))
|
||
|
|
.sort((a, b) => a - b);
|
||
|
|
}
|
||
|
|
|
||
|
|
function validate() {
|
||
|
|
const errors = [];
|
||
|
|
|
||
|
|
const bookNamesInData = Object.keys(nltData);
|
||
|
|
const bookNamesInStructure = Object.keys(bibleStructure);
|
||
|
|
|
||
|
|
// Check for missing/extra books
|
||
|
|
for (const book of bookNamesInData) {
|
||
|
|
if (!(book in bibleStructure)) {
|
||
|
|
errors.push(`Missing book in bibleStructure: ${book}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for (const book of bookNamesInStructure) {
|
||
|
|
if (!(book in nltData)) {
|
||
|
|
errors.push(`Book present in bibleStructure but missing in nltData: ${book}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate chapter counts and verse counts per chapter
|
||
|
|
for (const book of bookNamesInData) {
|
||
|
|
const chaptersObject = nltData[book];
|
||
|
|
const chapterNumbers = getSortedNumericKeys(chaptersObject);
|
||
|
|
|
||
|
|
if (!(book in bibleStructure)) {
|
||
|
|
// already reported above
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
const structureChapterCounts = bibleStructure[book];
|
||
|
|
|
||
|
|
// Chapter count check
|
||
|
|
if (structureChapterCounts.length !== chapterNumbers.length) {
|
||
|
|
errors.push(
|
||
|
|
`Chapter count mismatch in ${book}: structure=${structureChapterCounts.length}, data=${chapterNumbers.length}`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Verse count checks per chapter
|
||
|
|
for (const chapterNumber of chapterNumbers) {
|
||
|
|
const chapterIndex = chapterNumber - 1;
|
||
|
|
const versesObject = chaptersObject[String(chapterNumber)];
|
||
|
|
const verseNumbers = getSortedNumericKeys(versesObject);
|
||
|
|
const reportedVerseCount = structureChapterCounts[chapterIndex];
|
||
|
|
const actualVerseCount = verseNumbers.length;
|
||
|
|
|
||
|
|
// Ensure verses are contiguous from 1..N (no gaps or non-numeric keys)
|
||
|
|
for (let i = 1; i <= actualVerseCount; i += 1) {
|
||
|
|
if (verseNumbers[i - 1] !== i) {
|
||
|
|
errors.push(
|
||
|
|
`Non-contiguous or missing verse in ${book} ${chapterNumber}: expected ${i}, found ${verseNumbers[i - 1] ?? 'undefined'}`
|
||
|
|
);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (reportedVerseCount !== actualVerseCount) {
|
||
|
|
errors.push(
|
||
|
|
`Verse count mismatch in ${book} ${chapterNumber}: structure=${reportedVerseCount}, data=${actualVerseCount}`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Spot-check: Psalm 119
|
||
|
|
if (bibleStructure['Psalms']) {
|
||
|
|
const psalm119FromStructure = bibleStructure['Psalms'][118];
|
||
|
|
const psalm119FromData = Object.keys(nltData['Psalms']['119']).length;
|
||
|
|
console.log(`Psalm 119 — structure: ${psalm119FromStructure}, data: ${psalm119FromData}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (errors.length > 0) {
|
||
|
|
console.error(`\nFound ${errors.length} issue(s):`);
|
||
|
|
for (const err of errors) {
|
||
|
|
console.error(`- ${err}`);
|
||
|
|
}
|
||
|
|
process.exit(1);
|
||
|
|
} else {
|
||
|
|
console.log('\nAll books/chapters/verses match between bible-structure and nlt-data.');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
validate();
|
||
|
|
|
||
|
|
|