1616package guru .nidi .codeassert .io ;
1717
1818import guru .nidi .codeassert .config .AnalyzerConfig ;
19- import guru .nidi .codeassert .model .Model ;
19+ import guru .nidi .codeassert .config .For ;
20+ import guru .nidi .codeassert .dependency .*;
21+ import guru .nidi .codeassert .jacoco .*;
22+ import guru .nidi .codeassert .model .*;
23+ import guru .nidi .graphviz .attribute .*;
24+ import guru .nidi .graphviz .model .MutableNode ;
2025import org .junit .jupiter .api .Disabled ;
2126import org .junit .jupiter .api .Test ;
2227
2328import java .io .File ;
2429import java .io .IOException ;
30+ import java .util .Map ;
31+ import java .util .function .Function ;
2532
33+ import static guru .nidi .codeassert .config .CollectorConfig .just ;
34+ import static guru .nidi .codeassert .dependency .DependencyRules .denyAll ;
2635import static guru .nidi .codeassert .io .ModelVisualizer .replaceFunc ;
36+ import static guru .nidi .graphviz .attribute .Size .Mode .FIXED ;
37+ import static guru .nidi .graphviz .model .Factory .mutNode ;
38+ import static guru .nidi .graphviz .model .Factory .to ;
39+ import static java .util .stream .Collectors .toMap ;
2740import static org .junit .jupiter .api .Assertions .assertTrue ;
2841
2942class ModelVisualizerTest {
@@ -35,9 +48,66 @@ void myself() throws IOException {
3548 .ignoringPackages ("java" , "org.hamcrest" , "org.slf4j" , "org.apache" )
3649 .mergingPackages ("edu.umd.cs.findbugs" , "net.sourceforge.pmd" , "io.gitlab.arturbosch.detekt" , "com.puppycrawl.tools.checkstyle" , "com.github.shyiko.ktlint" , "kotlin" , "org.junit" , "guru.nidi.graphviz" )
3750 .read ();
38- final ModelVisualizer visualizer = new ModelVisualizer (model ).labelFunc (replaceFunc ("guru.nidi.codeassert" , "" ));
51+
52+ class GuruNidiCodeassert extends DependencyRuler {
53+ DependencyRule checkstyleLib = denyRule ("com.puppycrawl.tools.checkstyle" ).andAllSub ();
54+ DependencyRule detektLib = denyRule ("io.gitlab.arturbosch.detekt" ).andAllSub ();
55+ DependencyRule findBugsLib = denyRule ("edu.umd.cs.findbugs" ).andAllSub ();
56+ DependencyRule ktlintLib = denyRule ("com.github.shyiko.ktlint" ).andAllSub ();
57+ DependencyRule pmdLib = denyRule ("net.sourceforge.pmd" ).andAllSub ();
58+ DependencyRule graphvizLib = denyRule ("guru.nidi.graphviz" ).andAllSub ();
59+ DependencyRule config , dependency , findbugs , checkstyle , detekt , io , model , pmd , ktlint , util , junit , junitKotlin , jacoco ;
60+
61+ @ Override
62+ public void defineRules () {
63+ base ().mayBeUsedBy (all ());
64+ config .mayBeUsedBy (all ());
65+ util .mayBeUsedBy (all ());
66+ dependency .mayUse (model );
67+ junit .mayUse (model , dependency , findbugs , checkstyle , pmd );
68+ junitKotlin .mayUse (ktlint , detekt );
69+ checkstyle .mayUse (checkstyleLib );
70+ detekt .mayUse (detektLib );
71+ findbugs .mayUse (findBugsLib );
72+ io .mayUse (jacoco , model , graphvizLib );
73+ ktlint .mayUse (ktlintLib );
74+ pmd .mayUse (pmdLib ).mustUse (io );
75+ }
76+ }
77+
78+ final DependencyRules rules = denyAll ()
79+ .withExternals ("java.*" , "org.*" , "kotlin.*" )
80+ .withRelativeRules (new GuruNidiCodeassert ());
81+ final Dependencies dependencies = new DependencyAnalyzer (model ).rules (rules ).analyze ().findings ();
82+
83+ final Map <String , Double > coverage = new JacocoAnalyzer (new CoverageCollector (CoverageType .LINE )
84+ .config (just (For .allPackages ().setMinima (100 ))))
85+ .analyze ()
86+ .findings ().stream ()
87+ .collect (toMap (f -> f .getPack (), f -> f .getValues ()[0 ]));
88+
89+ final Function <String , String > labelFunc = replaceFunc ("guru.nidi.codeassert" , "" );
90+ final ModelVisualizer visualizer = new ModelVisualizer (model ).labelFunc (labelFunc );
3991 final File target = new File ("images/packages.png" );
40- visualizer .visualize ().toFile (target );
92+ visualizer .visualizePackages (pack -> {
93+ final MutableNode node = mutNode (labelFunc .apply (pack .getName ())).add (Shape .ELLIPSE );
94+ if (model .isOwnPackage (pack )) {
95+ final Double cover = coverage .getOrDefault (pack .getName (), 1D );
96+ final int codeSize = pack .getClasses ().stream ().mapToInt (CodeClass ::getTotalSize ).sum ();
97+ node .add (Shape .RECTANGLE )
98+ .add (Size .mode (FIXED ).size (1 + codeSize / 20000.0 , .5 + pack .getClasses ().size () / 10.0 ))
99+ .add (Color .rgb (255 - (int ) (2.55 * cover ), (int ) (2.55 * cover ) - 255 , 0 ).fill ())
100+ .add (Style .FILLED );
101+ }
102+ for (String missing : dependencies .getMissing (pack .getName (), pack .uses (), CodePackage ::getName )) {
103+ node .addLink (to (mutNode (labelFunc .apply (missing ))).with (Style .DASHED , Color .RED ));
104+ }
105+ for (CodePackage dep : pack .uses ()) {
106+ final boolean denied = dependencies .isDenied (pack .getName (), dep .getName ());
107+ node .addLink (to (mutNode (labelFunc .apply (dep .getName ()))).with (denied ? Color .RED : Color .BLACK ));
108+ }
109+ return node ;
110+ }).toFile (target );
41111 assertTrue (target .exists ());
42112 }
43113}
0 commit comments