61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Verify the fresh CoinGecko top-20 extraction artifact."""
|
|
import json
|
|
import sys
|
|
|
|
JSON_PATH = "/root/.hermes/wizard-outputs/ledger/crypto-top20-fresh.json"
|
|
# subject: /root/.hermes/wizard-outputs/ledger/crypto-top20-fresh.json -- grades the live tree outside the repo by design (not a repo fixture)
|
|
MD_PATH = "/root/.hermes/wizard-outputs/ledger/crypto-top20-fresh.md"
|
|
|
|
errors = []
|
|
|
|
|
|
def fail(msg):
|
|
errors.append(msg)
|
|
|
|
|
|
def main():
|
|
try:
|
|
with open(JSON_PATH) as f:
|
|
rows = json.load(f)
|
|
except Exception as e:
|
|
fail(f"cannot read {JSON_PATH}: {e}")
|
|
rows = None
|
|
|
|
if rows is not None:
|
|
if not isinstance(rows, list) or len(rows) != 20:
|
|
fail(f"expected 20 rows, got {len(rows) if isinstance(rows, list) else type(rows)}")
|
|
ranks = [r.get("rank") for r in rows]
|
|
if ranks != list(range(1, 21)):
|
|
fail(f"ranks not 1..20 contiguous: {ranks}")
|
|
if not all(isinstance(r.get("market_cap_usd"), int) and r["market_cap_usd"] > 0 for r in rows):
|
|
fail("market_cap_usd not positive int for all rows")
|
|
if any(not r.get("name") or not r.get("symbol") for r in rows):
|
|
fail("missing name/symbol in some row")
|
|
|
|
try:
|
|
with open(MD_PATH) as f:
|
|
md = f.read()
|
|
except Exception as e:
|
|
fail(f"cannot read {MD_PATH}: {e}")
|
|
md = ""
|
|
|
|
if md:
|
|
lines = [l for l in md.splitlines() if l.strip()]
|
|
if not lines or not lines[0].startswith("# "):
|
|
fail("md first line not a title")
|
|
data_rows = [l for l in lines[4:] if l.startswith("|") and "---" not in l]
|
|
if len(data_rows) != 20:
|
|
fail(f"md data rows != 20: {len(data_rows)}")
|
|
|
|
if errors:
|
|
print("FAIL")
|
|
for e in errors:
|
|
print(" -", e)
|
|
sys.exit(1)
|
|
print("OK: 20 rows, ranks 1..20 contiguous, all market caps positive; md has 20 rows")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|