Files
claude-code fa75becfe8
werkator build succeeded after 01:40
werkator/publish build succeeded after 00:09
The code city page leads with its views (0.23.0) (#47)
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-09 11:09:30 +02:00

299 lines
16 KiB
Gherkin

# language: de
Funktionalität: CodeCharta-Export der Mutation-CRAP-Analyse
Als Entwickler möchte ich sehen, wo in der Architektur schlecht getestete komplexe Klassen liegen,
ohne dass die Visualisierung fehlende Daten als gute Qualität zeigt.
Grundlage:
Angenommen ein erfolgreicher werkcrappit-Lauf hat einen vollständigen Mutation-CRAP-Report erzeugt
@MC-CC-001
Szenario: Packages werden zu Stadtteilen und Klassen zu Gebäuden
Angenommen die Analyse enthält Klassen in mehreren verschachtelten Packages
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält der Dateibaum für die Package-Hierarchie verschachtelte Folder-Knoten
Und jede analysierte Top-Level-Klasse wird durch genau einen File-Knoten dargestellt
Und eine Klasse, die werkcrappit.excludeClasses oder codeCharta.excludeClasses ausschließt, erscheint nicht
@MC-CC-002
Szenario: Gebäudegrundfläche basiert auf den echten Codezeilen der Quelldatei
Angenommen die Quelldatei einer Klasse enthält Code, Annotationen, Leerzeilen und Kommentare
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält ihr Gebäude die absolute Metrik "rloc"
Und der Wert ist die Anzahl der Zeilen der Quelldatei, die weder leer sind noch nur Kommentar enthalten
Und package-, import- und Annotationszeilen zählen mit
@MC-CC-003
Szenario: Gebäudehöhe basiert auf der aggregierten Komplexität
Angenommen eine Klasse besitzt mehrere analysierte Methoden mit JaCoCo-Komplexitätswerten
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält ihr Gebäude die absolute Metrik "complexity"
Und der Wert ist die Summe der berücksichtigten Methodenkomplexitäten
@MC-CC-004
Szenario: Gebäudefarbe zeigt den schlechtesten Mutation-CRAP-Wert der Klasse
Angenommen eine Klasse besitzt mehrere mit Mutation-CRAP bewertete Methoden
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält ihr Gebäude die Metrik "mutation_crap"
Und der Wert entspricht dem höchsten numerischen Mutation-CRAP-Wert dieser Methoden
@MC-CC-005
Szenario: Nicht bewertbare Methoden erzeugen keinen erfundenen guten Klassenwert
Angenommen keine Methode einer Klasse besitzt einen numerischen Mutation-CRAP-Wert
Wenn der CodeCharta-Export ausgeführt wird
Dann besitzt das Gebäude dieser Klasse keine Metrik "mutation_crap"
Und der Export setzt dafür nicht den Wert 0
@MC-CC-006
Szenario: Direkte Klassenabhängigkeiten werden als gerichtete Edges exportiert
Angenommen Klasse A referenziert Klasse B direkt im Produktionsbytecode
Und beide Klassen gehören zum exportierten Analyseumfang
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält der Dependency-Lens genau eine gerichtete physische Edge von A nach B
Und diese Edge besitzt ein numerisches Attribut "dependencies"
@MC-CC-007
Szenario: Mehrere Referenzen derselben Klassen werden zu einer Edge zusammengefasst
Angenommen Klasse A nutzt den Typ B, zwei Methoden von B und ein Feld von B, die Methoden jeweils mehrfach
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält der Dependency-Lens nur eine gerichtete Edge von A nach B
Und das Attribut "dependencies" ist 4, die Anzahl verschiedener genutzter Elemente von B
@MC-CC-008
Szenario: Ein Zyklus wird durch zwei gerichtete Edges dargestellt
Angenommen Klasse A hängt direkt von Klasse B ab
Und Klasse B hängt direkt von Klasse A ab
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält der Dependency-Lens eine Edge von A nach B und eine von B nach A
Und beide tragen "isCyclic": true
Und genau eine der beiden trägt "isPointingUpwards": true, die Rückkante, die den Zyklus bricht
@MC-CC-009
Szenario: Klassen ohne Gebäude erzeugen keine Gebäude und keine Edges
Angenommen eine analysierte Klasse referenziert eine Klasse aus einer externen Bibliothek
Und eine eigene Klasse, deren Methoden alle ausgeschlossen sind
Wenn der CodeCharta-Export ausgeführt wird
Dann wird für diese Klassen kein Gebäude erzeugt
Und es wird keine physische Edge zu einem nicht vorhandenen Zielknoten erzeugt
@MC-CC-010
Szenario: Der analysierte Git-Commit wird als Metadatum exportiert
Angenommen der analysierte Git-Commit ist eindeutig bekannt
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält "meta.commitHash" die vollständige SHA dieses Commits
@MC-CC-011
Szenario: Ein konfigurierter Source-Link zeigt auf den analysierten Commit
Angenommen ein Source-Link-Template ist konfiguriert
Und Commit, Source-Pfad und Startzeile einer Klasse sind bekannt
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält der File-Knoten dieser Klasse einen expandierten Link
Und der Link verwendet den analysierten Commit statt eines beweglichen Branch-Namens
Und der Link zeigt auf die erste Zeile der Methode mit dem höchsten Mutation-CRAP
Und hat die Klasse keine Methode mit Code, wie ein Interface, zeigt er auf Zeile 1
@MC-CC-012
Szenario: Der Export ist deterministisch
Angenommen dieselben Analyse- und Bytecode-Daten werden zweimal in unterschiedlicher Eingabereihenfolge bereitgestellt
Wenn beide CodeCharta-Exporte ausgeführt werden
Dann sind die erzeugten Dateien byteweise identisch
@MC-CC-013
Szenario: Der erzeugte Datensatz ist mit der unterstützten CodeCharta-Version kompatibel
Angenommen eine reale Gradle-Testfixture enthält sieben Klassen und zehn direkte Abhängigkeiten
Wenn PIT, werkcrappit und anschließend der CodeCharta-Export ausgeführt werden
Dann ist die erzeugte Datei gegen den gepinnten CodeCharta-Kompatibilitätsvertrag gültig
Und sie enthält sieben Klassengebäude
Und sie enthält zehn gerichtete Dependency-Edges
@MC-CC-014
Szenario: Unbewertbare Methoden neben bewerteten werden gemeldet
Angenommen eine Klasse besitzt eine bewertete Methode mit Mutation-CRAP 6
Und eine Methode im Zustand INCONCLUSIVE
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält ihr Gebäude die Metrik "mutation_crap" mit dem Wert 6
Und der Export warnt, dass diese Klasse unbewertbare Methoden hat
@MC-CC-015
Szenario: Innere Klassen gehören zum Gebäude ihrer Top-Level-Klasse
Angenommen eine Klasse Order enthält eine innere Klasse Order$Line und ein Lambda
Wenn der CodeCharta-Export ausgeführt wird
Dann gibt es genau ein Gebäude "Order"
Und "executable_lines", "complexity" und "mutation_crap" umfassen die Methoden von Order und Order$Line
@MC-CC-017
Szenario: Package-Ketten ohne eigene Klassen werden zusammengefasst
Angenommen alle Klassen liegen unter net.hostsharing.hsadminng
Und net, net.hostsharing und net.hostsharing.hsadminng enthalten außer dem nächsten Package nichts
Wenn der CodeCharta-Export ausgeführt wird
Dann gibt es unter der Wurzel genau einen Folder-Knoten "net.hostsharing.hsadminng"
Und ein Package mit eigenen Klassen oder mehreren Unter-Packages bleibt ein eigener Folder-Knoten
@MC-CC-018
Szenario: Ein Package zeigt für Maxima den Median, für alles andere die Summe
Angenommen ein Package enthält viele Klassen mit niedrigem und eine mit hohem Mutation-CRAP
Wenn der CodeCharta-Export ausgeführt wird
Dann sind "mutation_crap" und "max_method_complexity" vom Typ relative, CodeCharta zeigt für das Package den Median
Und "rloc", "executable_lines", "complexity" und die Zählmetriken sind vom Typ absolute, CodeCharta zeigt die Summe
@MC-CC-019
Szenario: Generierter Code vergrößert kein Gebäude
Angenommen eine Entität hat zehn Felder mit Lombok-Annotationen @Getter und @Setter
Wenn der CodeCharta-Export ausgeführt wird
Dann zählt "rloc" die Annotationen und Felder der Quelldatei
Aber keine der von Lombok erzeugten Methoden
@MC-CC-020
Szenario: Ausführbare Zeilen bleiben als eigene Metrik wählbar
Angenommen eine Klasse besitzt ausführbaren Code
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält ihr Gebäude die absolute Metrik "executable_lines"
Und der Wert ist die Anzahl unterschiedlicher Quelltextzeilen mit Instruktionen ihrer nicht ausgeschlossenen Methoden
@MC-CC-021
Szenario: Ohne gefundene Quelldatei gibt es keine erfundene Grundfläche
Angenommen die Quelldatei einer Klasse liegt in keinem Quellverzeichnis des main-Source-Sets
Wenn der CodeCharta-Export ausgeführt wird
Dann besitzt ihr Gebäude keine Metrik "rloc"
Und der Export nennt diese Klasse in einer Warnung
@MC-CC-022
Szenario: Klassen außerhalb des PIT-Laufs werden graue Gebäude
Angenommen eine Klasse des main-Source-Sets gehört nicht zu den von PIT analysierten Klassen
Wenn der CodeCharta-Export ausgeführt wird
Dann gibt es für sie ein Gebäude mit "rloc", "executable_lines" und "complexity"
Und "complexity" stammt aus derselben statischen JaCoCo-Analyse wie im PIT-Lauf
Aber das Gebäude besitzt keine Metrik "mutation_crap"
Und die Report-Seite erklärt die Flatten-Regel "mutation_crap < 1", die solche Gebäude in CodeCharta grau zeichnet
@MC-CC-023
Szenario: Klassen ohne ausführbaren Code erscheinen mit ihrer Quelltextgröße
Angenommen ein Interface ohne Default-Methoden, etwa ein Spring-Data-Repository mit @Query-Annotationen
Wenn der CodeCharta-Export ausgeführt wird
Dann gibt es für es ein Gebäude mit der Metrik "rloc"
Aber ohne "complexity", "executable_lines" und "mutation_crap"
@MC-CC-024
Szenario: Klassen lassen sich aus der Stadt ausschließen
Angenommen codeCharta.excludeClasses enthält "**.generated.**"
Wenn der CodeCharta-Export ausgeführt wird
Dann erscheint keine Klasse eines Packages "generated" als Gebäude
@MC-CC-025
Szenario: Die Report-Seite öffnet die Code-City direkt in CodeCharta
Angenommen die Seite index.html der Code-City wird über http oder https aufgerufen
Wenn man dem Link "In CodeCharta öffnen" folgt
Dann öffnet sich der CodeCharta-Viewer mit der absoluten URL von mutation-crap.cc.json als Parameter "file"
Und mit den Parametern area=rloc, height=complexity und color=mutation_crap
Aber beim Öffnen von der Festplatte (file://) zeigt die Seite den Link nicht, nur den Download
@MC-CC-036
Szenario: Die Report-Seite beginnt mit den vier Ansichten
… damit man die Code-City mit einem Klick öffnet, ohne den Weg über den Download zu lesen.
Angenommen die Seite index.html der Code-City wird über http oder https aufgerufen
Wenn man sie öffnet
Dann folgen auf die Überschrift und die Zeile mit der Zahl der Gebäude vier Schaltflächen
Und sie heißen Mutation-CRAP, Kohäsion, Kopplung und Änderungsrisiko
Und jede nennt in einem Satz, was ihre Farbe zeigt
Und der Download und das Hochladen von Hand stehen erst danach, unter "Without a direct link"
@MC-CC-026
Szenario: Der Viewer des Links ist konfigurierbar
Angenommen codeCharta.viewerUrl ist nicht gesetzt
Wenn die Report-Seite den Link "In CodeCharta öffnen" bildet
Dann zeigt er auf https://javagil.de/codecharta/index.html, den Viewer, der unbewertete Klassen grau zeichnet
Und mit codeCharta.viewerUrl = "https://codecharta.com/visualization/app/index.html" zeigt er auf jenen
@MC-CC-027
Szenario: Packages und Klassen bekommen Abhängigkeits-Ebenen
Angenommen im Package shop hängt service von persistence und domain ab, persistence von domain
Wenn der CodeCharta-Export ausgeführt wird
Dann hat domain die Ebene 0, persistence die Ebene 1 und service die Ebene 2 im Dependency-Lens "nodes"
Und eine Edge, deren Ziel unter dem gemeinsamen Ordner nicht tiefer liegt als ihre Quelle, trägt "isPointingUpwards": true
@MC-CC-028
Szenario: Ohne Levelisierung ist die Datei für das Original von CodeCharta lesbar
Angenommen codeCharta.levelization ist false
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält keine Edge "isCyclic" oder "isPointingUpwards" und der Dependency-Lens keine "nodes"
Und die Datei ist gültig gegen das Schema von CodeCharta vis-2.7.0
@MC-CC-029
Szenario: Der Link zeigt rot schon kurz vor dem Grenzwert des Gates
… damit man die Klassen sieht, die als nächstes anzusehen sind, bevor der Build fehlschlägt.
Angenommen werkcrappit.maxMutationCrap ist 10
Wenn die Report-Seite den Link "In CodeCharta öffnen" bildet
Dann enthält er colorFrom=5 und colorTo=9: grün unter der Hälfte des Grenzwerts, gelb ab 5, rot ab 9
Und colorMode=absolute, damit die Stufen hart sind
Und ohne maxMutationCrap enthält er colorFrom=5 und colorTo=9
@MC-CC-030
Szenario: Die Farbgrenze zu rot ist einstellbar, gelb beginnt bei ihrer Hälfte
… damit ein Projekt seinen Puffer vor dem Grenzwert selbst wählt und gelb auch bei einem Ratchet weit darüber bleibt.
Angenommen werkcrappit.maxMutationCrap ist 650
Und codeCharta.colorRedFrom ist 12
Wenn die Report-Seite den Link "In CodeCharta öffnen" bildet
Dann enthält er colorFrom=6 und colorTo=12: gelb ab der Hälfte von colorRedFrom, nicht von maxMutationCrap
Und ein colorRedFrom über maxMutationCrap bricht den Export mit einer Meldung ab, weil rot dann nie vor dem Fehlschlag käme
@MC-CC-031
Szenario: Die Farbgrenze zu gelb ist einstellbar
… damit ein Projekt den Übergang von grün zu gelb unabhängig von rot wählt.
Angenommen werkcrappit.maxMutationCrap ist 650
Und codeCharta.colorRedFrom ist 12
Und codeCharta.colorYellowFrom ist 8
Wenn die Report-Seite den Link "In CodeCharta öffnen" bildet
Dann enthält er colorFrom=8 und colorTo=12
Und ein colorYellowFrom über dem Beginn von rot bricht den Export mit einer Meldung ab, weil gelb dann nie zu sehen wäre
@MC-CC-016
Szenario: Der Export passt zu den Klassen des PIT-Laufs
Angenommen eine Klassendatei wurde nach dem PIT-Lauf neu kompiliert und weicht vom Report ab
Wenn der CodeCharta-Export ausgeführt wird
Dann scheitert der Export mit dem Hinweis, PIT erneut auszuführen
@MC-CC-032
Szenario: Der Export schreibt je Sicht ein CodeCharta-Szenario
… damit man im Viewer per Szenario-Liste zwischen Mutation-CRAP, Kohäsion und Kopplung umschalten kann, jede mit ihren eigenen Farbgrenzen.
Angenommen werkcrappit.maxMutationCrap ist 10 und werkcrappit.maxEfferentCoupling ist 34
Wenn der CodeCharta-Export ausgeführt wird
Dann liegen neben mutation-crap.cc.json die Dateien mutation-crap.ccscenario, cohesion.ccscenario und coupling.ccscenario
Und jede hat schemaVersion 3, Fläche rloc, Höhe complexity und colorMode absolute
Und "Mutation-CRAP" färbt nach mutation_crap mit colorRange 5 bis 9, wie der Link der Report-Seite
Und "Cohesion" färbt nach lcom4 mit colorRange 2 bis 3
Und "Coupling" färbt nach efferent_coupling mit colorRange 17 bis 30.6
@MC-CC-033
Szenario: Ohne maxEfferentCoupling hat das Szenario Coupling keine Farbgrenzen
… damit der Viewer seine eigenen Drittel nimmt, statt Grenzen ohne Grundlage zu zeigen.
Angenommen werkcrappit.maxEfferentCoupling ist nicht gesetzt
Wenn der CodeCharta-Export ausgeführt wird
Dann enthält coupling.ccscenario weder colorRange noch colorMode
Und mutation-crap.ccscenario hat ohne maxMutationCrap colorRange 5 bis 9, wie der Link der Report-Seite
@MC-CC-034
Szenario: Ein Link öffnet die Stadt mit allen drei Szenarien
… damit ein Klick genügt, um die Stadt zu sehen und im Viewer zwischen den drei Sichten umzuschalten.
Angenommen die Report-Seite wird über http(s) ausgeliefert
Wenn sie den Link "Open in CodeCharta" bildet
Dann trägt er neben file die Parameter scenario für mutation-crap.ccscenario, cohesion.ccscenario und coupling.ccscenario, jeweils als absolute URL
Und der Viewer der javagil.de-Fassung übernimmt die drei Szenarien in seine Liste und wendet das erste an
Und die Seite bietet die drei Dateien auch zum Herunterladen an, für den Import von Hand in einen anderen Viewer
@MC-CC-035
Szenario: Die Stadt zeigt Change-Risk als vierte Sicht
… damit man die riskantesten Klassen in der Stadt findet und sieht, ob sie groß, verflochten oder schlecht getestet sind.
Angenommen eine Klasse mit changeRisk 70 und eine mit changeRisk null
Wenn der CodeCharta-Export ausgeführt wird
Dann trägt das Gebäude der ersten Klasse die Metrik change_risk 70, das der zweiten keine
Und neben den drei Szenarien liegt change-risk.ccscenario: "Change Risk" färbt nach change_risk mit colorRange 30 bis 100
Und der Link "Open in CodeCharta" trägt change-risk.ccscenario als vierten Parameter scenario
Und die Report-Seite bietet change-risk.ccscenario wie die anderen drei zum Herunterladen an