diora-web/tui/tools/parity/compare_blocks.py

39 lines
1.7 KiB
Python
Raw Permalink Normal View History

"""Compare the TUI's block list with the web reader's (web_blocks.cjs output).
python compare_blocks.py web.json [name-part ...]
What must match is the number and tag of the blocks (they make the position anchors
shared by all clients). Text differences are reported too: they are cosmetic, but they
show where the TUI's HTML parser (lxml) reads a book differently from Chrome's.
Exit status 1 when a book's block list differs in length or tags.
"""
import json
import os
import sys
from pathlib import Path
from diora_tui.blocks import load_flat_book
def main(ref_file, only):
ref = json.load(open(ref_file, encoding="utf-8"))
failed = False
for file, web in ref.items():
if only and not any(o in file for o in only):
continue
book = load_flat_book(Path(file))
wb, tb = web["blocks"], book.blocks
structure = len(wb) == len(tb) and all(w["tag"] == t.tag for w, t in zip(wb, tb))
texts = [i for i, (w, t) in enumerate(zip(wb, tb)) if w["text"] != t.text]
chars = [i for i, (w, t) in enumerate(zip(wb, tb)) if (w["start"], w["len"]) != (t.char_start, t.char_len)]
total_ok = web["total"] == book.total_chars
failed |= not structure
print(f"{'OK ' if structure else 'FAIL'} {os.path.basename(file)[:50]}: web {len(wb)} / tui {len(tb)} blocks, "
f"{len(texts)} with other text" + (f" (first: {texts[0]})" if texts else "") +
f"; chars {'equal' if not chars and total_ok else f'{len(chars)} blocks differ, total web {web['total']} / tui {book.total_chars}'}")
return 1 if failed else 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1], sys.argv[2:]))