Files

71 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""Verdict test for ledger-coinmarket-10 (extract lane).
Exit code 0 = artifact correct; nonzero = artifact wrong.
Checks: file presence, CSV parse, row count, header contract, rank/order,
numeric fields, and source payload inclusion. No network access required.
"""
import csv, json, os, sys
BASE = os.path.dirname(os.path.abspath(__file__))
MD = os.path.join(BASE, "top-cryptocurrencies.md")
CSV = os.path.join(BASE, "top-cryptocurrencies.csv")
SRC = os.path.join(BASE, "source/coins_raw.json")
FAIL = []
def check(name, cond):
print(("PASS" if cond else "FAIL"), "-", name)
if not cond: FAIL.append(name)
# 1. presence
check("md exists", os.path.isfile(MD))
check("csv exists", os.path.isfile(CSV))
check("source json exists", os.path.isfile(SRC))
import re
# 2. markdown table renders a header + separator + 10 data rows
md = open(MD).read() if os.path.isfile(MD) else ""
check("md has header", "| Rank |" in md and "| --- |" in md)
data_rows = [l for l in md.splitlines() if re.match(r"^\|\s*\d+\s*\|", l)]
check("md data row count == 10", len(data_rows) == 10)
# 3. csv parse + contract
rows = []
if os.path.isfile(CSV):
with open(CSV, newline="") as f:
rdr = csv.DictReader(f)
check("csv header == expected", bool(rdr.fieldnames))
rows = list(rdr)
check("csv row count == 10", len(rows) == 10)
check("csv header is 22 cols", bool(rdr.fieldnames) and len(rdr.fieldnames) == 22)
def is_num(s):
try:
float(s); return True
except (TypeError, ValueError):
return False
bad = 0
for r in rows:
if not (is_num(r["rank"]) and int(r["rank"]) == int(rows.index(r) + 1)):
bad += 1
for k in ("price_usd","market_cap_usd","total_volume_usd","circulating_supply"):
if not is_num(r[k]): bad += 1
check("csv ranks == 1..10 & numeric fields parse", bad == 0)
# 4. order: market cap non-increasing across rows
caps = [float(r["market_cap_usd"]) for r in rows]
check("market cap non-increasing (desc)", all(caps[i] >= caps[i+1] for i in range(len(caps)-1)))
# 5. source payload included (never fabricated)
try:
snap = json.load(open(SRC))
check("source json has 10 rows", isinstance(snap, dict) and len(snap.get("rows", [])) == 10)
check("source json fetched_at set", bool(snap.get("fetched_at")))
except Exception as e:
check("source json loads", False)
print()
print("RESULT:", "OK" if not FAIL else f"{len(FAIL)} FAILURES: {FAIL}")
sys.exit(1 if FAIL else 0)