#!/usr/bin/env python3 """Script pour analyser le rapport JaCoCo et extraire les classes sans tests.""" import os import re from pathlib import Path from html.parser import HTMLParser class JaCoCoParser(HTMLParser): def __init__(self): super().__init__() self.current_package = "" self.classes = [] self.in_tbody = False self.current_row = {} self.current_cell = "" self.cell_index = 0 def handle_starttag(self, tag, attrs): if tag == "tbody": self.in_tbody = True elif tag == "tr" and self.in_tbody: self.current_row = {} self.cell_index = 0 elif tag == "td" and self.in_tbody: self.current_cell = "" elif tag == "a" and self.in_tbody: for attr, value in attrs: if attr == "href" and value.endswith(".html"): self.current_row["href"] = value def handle_endtag(self, tag): if tag == "tbody": self.in_tbody = False elif tag == "tr" and self.in_tbody and self.current_row: if "coverage" in self.current_row and self.current_row["coverage"] == "0 %": self.classes.append(self.current_row.copy()) elif tag == "td" and self.in_tbody: self.cell_index += 1 def handle_data(self, data): if self.in_tbody: data = data.strip() if data and self.cell_index == 0: self.current_row["name"] = data elif data and "%" in data: self.current_row["coverage"] = data def analyze_package(package_path, package_name): """Analyse un fichier index.html de package.""" index_file = os.path.join(package_path, "index.html") if not os.path.exists(index_file): return [] with open(index_file, 'r', encoding='utf-8') as f: content = f.read() parser = JaCoCoParser() parser.current_package = package_name parser.feed(content) classes = [] for row in parser.classes: if "name" in row: classes.append({ "package": package_name, "class": row["name"], "coverage": row.get("coverage", "0 %") }) return classes def main(): jacoco_dir = Path("target/site/jacoco") if not jacoco_dir.exists(): print(f"Erreur: Le répertoire {jacoco_dir} n'existe pas.") print("Veuillez exécuter 'mvn clean test' pour générer le rapport JaCoCo.") return # Collecter tous les packages all_classes = [] for package_dir in jacoco_dir.iterdir(): if package_dir.is_dir() and not package_dir.name.startswith("."): package_name = package_dir.name.replace("/", ".") classes = analyze_package(package_dir, package_name) all_classes.extend(classes) # Trier par package et type dto_requests = [] dto_responses = [] dto_other = [] enums = [] others = [] for cls in all_classes: pkg = cls["package"] name = cls["class"] if "enums" in pkg: enums.append(cls) elif "dto" in pkg: if ".request" in pkg: dto_requests.append(cls) elif ".response" in pkg: dto_responses.append(cls) else: dto_other.append(cls) else: others.append(cls) # Afficher les résultats print("=" * 80) print("CLASSES SANS TESTS (0% de couverture)") print("=" * 80) print() if dto_requests: print("1. DTOs REQUEST (dev.lions.unionflow.server.api.dto)") print("-" * 80) for cls in sorted(dto_requests, key=lambda x: (x["package"], x["class"])): print(f" {cls['package']}.{cls['class']}") print(f" Type: DTO Request | Couverture: {cls['coverage']}") print() if dto_responses: print("2. DTOs RESPONSE (dev.lions.unionflow.server.api.dto)") print("-" * 80) for cls in sorted(dto_responses, key=lambda x: (x["package"], x["class"])): print(f" {cls['package']}.{cls['class']}") print(f" Type: DTO Response | Couverture: {cls['coverage']}") print() if dto_other: print("3. AUTRES DTOs") print("-" * 80) for cls in sorted(dto_other, key=lambda x: (x["package"], x["class"])): print(f" {cls['package']}.{cls['class']}") print(f" Type: DTO | Couverture: {cls['coverage']}") print() if enums: print("4. ENUMS (dev.lions.unionflow.server.api.enums)") print("-" * 80) for cls in sorted(enums, key=lambda x: (x["package"], x["class"])): print(f" {cls['package']}.{cls['class']}") print(f" Type: Enum | Couverture: {cls['coverage']}") print() if others: print("5. AUTRES") print("-" * 80) for cls in sorted(others, key=lambda x: (x["package"], x["class"])): print(f" {cls['package']}.{cls['class']}") print(f" Type: Autre | Couverture: {cls['coverage']}") print() print("=" * 80) print(f"TOTAL: {len(all_classes)} classes sans tests") print(f" - DTO Requests: {len(dto_requests)}") print(f" - DTO Responses: {len(dto_responses)}") print(f" - Autres DTOs: {len(dto_other)}") print(f" - Enums: {len(enums)}") print(f" - Autres: {len(others)}") print("=" * 80) if __name__ == "__main__": main()