Files

108 lines
3.9 KiB
Python

#!/usr/bin/env python3
"""CHECK: re-derive the catalog from the raw JSON source and diff against the
produced artifact (catalog.json + catalog.md). Exit 0 only if they agree.
This is a real regression test, not a tautology: it re-reads the source file and
re-derives the rows, then compares against the committed artifact bytes.
"""
import json
import re
import sys
SRC = '/root/stackchain_catalog_raw.json'
ACTUAL_JSON = '/root/.hermes/wizard-outputs/ledger/catalog.json'
ACTUAL_MD = '/root/.hermes/wizard-outputs/ledger/catalog.md'
TYPE_RE = re.compile(r'"type"\s*:\s*"(.*?)"')
TEXT_RE = re.compile(r'"text"\s*:\s*"(.*?)"', re.DOTALL)
DOUBLE_N = '\\\\n'
SINGLE_N = '\\n'
def reextract():
raw = json.load(open(SRC, encoding='utf-8'))
rows = []
for idx, (fname, v) in enumerate(raw.items(), 1):
m_type = TYPE_RE.search(v)
ftype = m_type.group(1) if m_type else None
m_text = TEXT_RE.search(v)
text = m_text.group(1) if m_text else None
if text is not None:
text = text.replace(DOUBLE_N, '\n').replace(SINGLE_N, '\n')
rows.append({
'no': idx,
'entry': fname,
'type': ftype if ftype is not None else '(not transcribed)',
'text': text,
'words': len(text.split()) if text else 0,
})
return rows
def load_actual():
rows = json.load(open(ACTUAL_JSON, encoding='utf-8'))
md = open(ACTUAL_MD, encoding='utf-8').read()
return rows, md
def md_table_rows(md):
rows = []
for line in md.splitlines():
if line.startswith('|') and '---' not in line and 'No.' not in line:
cells = [c.strip() for c in line.strip('|').split('|')]
if cells:
rows.append(cells)
return rows
def main():
errors = []
expected = reextract()
actual, md = load_actual()
if len(actual) != len(expected):
errors.append(f'row count: actual={len(actual)} expected={len(expected)}')
for i, (a, e) in enumerate(zip(actual, expected), 1):
for key in ('no', 'entry', 'type', 'text', 'words'):
if a.get(key) != e[key]:
errors.append(f'row {i} field {key}: actual={a.get(key)!r} expected={e[key]!r}')
# markdown sanity: every entry must appear, with a type, and word counts must
# match the numbers in the table.
seen = set()
for cells in md_table_rows(md):
if len(cells) == 5 and cells[1].startswith('`'):
seen.add(cells[1].strip('`'))
if cells[3] == '—':
if actual[int(cells[0]) - 1]['text'] is not None:
errors.append(f'row {cells[0]} shows — but source text present')
else:
text = actual[int(cells[0]) - 1]['text']
if text is None:
errors.append(f'row {cells[0]} preview missing but source text absent')
else:
single = ' '.join(text.split())
exp_preview = single[:140].rstrip() + ('…' if len(single) > 140 else '')
if cells[3] != exp_preview:
errors.append(f'row {cells[0]} preview mismatch: {cells[3]!r} vs {exp_preview!r}')
if cells[2] != actual[int(cells[0]) - 1]['type']:
errors.append(f'row {cells[0]} type: {cells[2]} vs {actual[int(cells[0]) - 1]["type"]}')
expected_entries = {r['entry'] for r in expected}
if seen != expected_entries:
errors.append('md entries missing/extra: ' + ', '.join(sorted(seen ^ expected_entries)))
if errors:
print('CHECK FAILED:')
for e in errors:
print(' -', e)
sys.exit(1)
print(f'CHECK OK: {len(actual)} rows match the source exactly '
f'({sum(1 for r in actual if r["text"])} transcribed, '
f'{sum(1 for r in actual if not r["text"])} empty).')
sys.exit(0)
if __name__ == '__main__':
main()