148 lines
5.6 KiB
Python
148 lines
5.6 KiB
Python
from pathlib import Path
|
|
from datetime import datetime
|
|
import json
|
|
import sys
|
|
|
|
def stringify(obj):
|
|
if obj is None or obj == "":
|
|
return "`None`"
|
|
if isinstance(obj, list):
|
|
return ', '.join(stringify(e) for e in obj)
|
|
if isinstance(obj, dict):
|
|
return ', '.join(f"`{k}: {stringify(v)}`" for k, v in obj.items())
|
|
return f"`{str(obj)}`"
|
|
|
|
def write_details_block(f, title, data):
|
|
f.write(f"<details>\n<summary>{title}</summary>\n\n")
|
|
if not data:
|
|
f.write("- `None`\n")
|
|
else:
|
|
for key, value in data.items():
|
|
f.write(f"- **{key}:**\n")
|
|
f.write("```\n")
|
|
if isinstance(value, dict):
|
|
for k, v in value.items():
|
|
f.write(f"{k}: {v}\n")
|
|
elif isinstance(value, list):
|
|
for item in value:
|
|
if isinstance(item, dict):
|
|
for k, v in item.items():
|
|
f.write(f"{k}: {v}\n")
|
|
f.write("\n")
|
|
else:
|
|
f.write(f"{item}\n")
|
|
else:
|
|
f.write(f"{value}\n")
|
|
f.write("```\n")
|
|
f.write("</details>\n\n")
|
|
|
|
def extract_params(test):
|
|
if "params" in test:
|
|
return stringify(test["params"])
|
|
|
|
nodeid = test.get("nodeid", "")
|
|
if "[" not in nodeid:
|
|
return "`None`"
|
|
|
|
raw_params = nodeid.split("[")[-1].rstrip("]")
|
|
lines = []
|
|
named = all("=" in p for p in raw_params.split("-"))
|
|
|
|
if named:
|
|
for param in raw_params.split("-"):
|
|
if "=" in param:
|
|
name, value = param.split("=", 1)
|
|
lines.append(f" - `{name.strip()}`: `{value.strip()}`")
|
|
else:
|
|
lines.append(f" - `{param.strip()}`")
|
|
else:
|
|
for i, value in enumerate(raw_params.split("-"), 1):
|
|
lines.append(f" - Param {i}: `{value.strip()}`")
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
def json_to_adaptive_md(json_path, md_path):
|
|
with open(json_path) as f:
|
|
data = json.load(f)
|
|
|
|
with open(md_path, 'w', encoding='utf-8') as f:
|
|
f.write(f"# 🧪 Rapport de Tests\n")
|
|
f.write(f"*Généré le {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*\n\n")
|
|
|
|
if 'summary' in data:
|
|
f.write("## 📋 Résumé\n")
|
|
for key, value in data['summary'].items():
|
|
f.write(f"- **{key.capitalize()}**: {stringify(value)}\n")
|
|
duration = data.get("duration")
|
|
if duration is not None:
|
|
f.write(f"- **Durée totale**: `{duration:.3f}`s\n")
|
|
f.write("\n")
|
|
|
|
if "collectors" in data:
|
|
f.write("## 📚 Collectés\n")
|
|
for collector in data["collectors"]:
|
|
outcome = collector.get("outcome", "unknown")
|
|
emoji = "✅" if outcome == "passed" else "❌"
|
|
nodeid = collector.get("nodeid", "unknown")
|
|
short_node = nodeid.split("[")[0]
|
|
f.write(f"<details>\n<summary>{emoji} `{short_node}`</summary>\n\n")
|
|
f.write(f"- **outcome:** `{outcome}`\n")
|
|
results = collector.get("result", [])
|
|
if results:
|
|
f.write("- **result:**\n```\n")
|
|
for item in results:
|
|
if isinstance(item, dict):
|
|
for k, v in item.items():
|
|
f.write(f"{k}: {v}\n")
|
|
f.write("\n")
|
|
else:
|
|
f.write(f"{item}\n")
|
|
f.write("```\n")
|
|
else:
|
|
f.write("- **result:** `None`\n")
|
|
f.write("</details>\n\n")
|
|
|
|
if "tests" in data:
|
|
f.write("## 🔎 Tests\n")
|
|
for test in data["tests"]:
|
|
outcome = test.get("outcome", "unknown")
|
|
icons = {"passed": "✅", "failed": "❌", "skipped": "⏭️", "error": "❗"}
|
|
emoji = icons.get(outcome, "❔")
|
|
nodeid = test.get("nodeid", "unknown")
|
|
short_name = nodeid.split("::")[-1].split("[")[0]
|
|
|
|
f.write(f"<details>\n<summary>{emoji} `{short_name}`</summary>\n\n")
|
|
|
|
param_string = extract_params(test)
|
|
if param_string != "`None`":
|
|
f.write(f"- **Paramètres:** {param_string}\n")
|
|
|
|
f.write(f"- **Statut:** {emoji} `{outcome}`\n")
|
|
duration = test.get("call", {}).get("duration")
|
|
f.write(f"- **Durée:** `{duration:.6f}` s\n" if duration else "- **Durée:** `None`\n")
|
|
|
|
if outcome != "passed":
|
|
f.write(f"- **Détails:**\n")
|
|
f.write("<details>\n<summary>Détails</summary>\n\n")
|
|
for key in ['duration', 'outcome', 'crash', 'traceback', 'longrepr']:
|
|
value = test.get("call", {}).get(key)
|
|
f.write(f"- **{key}:**\n")
|
|
f.write("```\n")
|
|
f.write(f"{value if value else 'None'}\n")
|
|
f.write("```\n\n")
|
|
f.write("</details>\n")
|
|
f.write("</details>\n\n")
|
|
|
|
def main():
|
|
import argparse
|
|
parser = argparse.ArgumentParser(description="Convert JSON test results to Markdown.")
|
|
parser.add_argument("--input", required=True, help="Chemin du fichier JSON d'entrée")
|
|
parser.add_argument("--output", required=True, help="Chemin du fichier Markdown de sortie")
|
|
|
|
args = parser.parse_args()
|
|
json_to_adaptive_md(args.input, args.output)
|
|
print(f"✅ Rapport généré dans {args.output}")
|
|
|
|
if __name__ == "__main__":
|
|
main() |