diff --git a/src/main/java/org/jpeek/App.java b/src/main/java/org/jpeek/App.java index c23fb5dd..5ceac544 100644 --- a/src/main/java/org/jpeek/App.java +++ b/src/main/java/org/jpeek/App.java @@ -68,12 +68,12 @@ * @checkstyle MethodLengthCheck (500 lines) * @checkstyle JavaNCSSCheck (500 lines) * - * @todo #9:30min LCC metric has impediments (see puzzles in LCC.xml). + * @todo #9:30min LCC metric has impediments (see puzzles in LCC.xsl). * Once they are resolved, cover the metric with autotests and add it * to reports list. * (details on how to test the metrics are to be negotiated here - #107) * - * @todo #17:30min MWE metric has impediments (see puzzles in MWE.xml). + * @todo #17:30min MWE metric has impediments (see puzzles in MWE.xsl). * Once they are resolved, cover the metric with autotests and add it * to reports list. * (details on how to test the metrics are to be negotiated here - #107) @@ -124,7 +124,8 @@ public App(final Path source, final Path target) { new MapEntry<>("MMAC", true), new MapEntry<>("OCC", true), new MapEntry<>("PCC", true), - new MapEntry<>("TCC", true) + new MapEntry<>("TCC", true), + new MapEntry<>("LCC", true) ) ); } @@ -257,6 +258,14 @@ public void analyze() throws IOException { ) ); } + if (this.params.containsKey("LCC")) { + reports.add( + new Report( + chain.transform(skeleton), + "LCC" + ) + ); + } new IoCheckedScalar<>( new AndInThreads( report -> { diff --git a/src/main/resources/org/jpeek/metrics/LCC.xsl b/src/main/resources/org/jpeek/metrics/LCC.xsl index 785980f4..5653321d 100644 --- a/src/main/resources/org/jpeek/metrics/LCC.xsl +++ b/src/main/resources/org/jpeek/metrics/LCC.xsl @@ -26,33 +26,35 @@ SOFTWARE. - TCC + LCC LCC(C) = (NDC(C) + NIC(C)) / NP(C), where C is the class, NP(C) is a maximal possible number of direct or indirect connections - N * (N - 1) / 2, - NDC(C) is a number of direct connections, NID(C) is a number of indirect - connections. Value of the metric is in range [0, 1], greater is better. + NDC(C) is a number of direct connections, + NIC(C) is a number of indirect connections. + Value of the metric is in range [0, 1], greater is better. - + + - + - - - - + + + + @@ -70,8 +72,8 @@ SOFTWARE. --> - + @@ -86,6 +88,9 @@ SOFTWARE. + + + diff --git a/src/main/resources/org/jpeek/metrics/TCC.xsl b/src/main/resources/org/jpeek/metrics/TCC.xsl index 18879aac..20e6c907 100644 --- a/src/main/resources/org/jpeek/metrics/TCC.xsl +++ b/src/main/resources/org/jpeek/metrics/TCC.xsl @@ -30,8 +30,8 @@ SOFTWARE. TCC(C) = NDC(C) / NP(C), where C is the class, NP(C) is a maximal possible number of direct or indirect connections - N * (N - 1) / 2, - NDC(C) is a number of direct connections. Value of the metric is in range [0, 1], - greater is better. + NDC(C) is a number of direct connections. + Value of the metric is in range [0, 1], greater is better. @@ -80,7 +80,8 @@ SOFTWARE. 0 - + + diff --git a/src/test/java/org/jpeek/MetricsTest.java b/src/test/java/org/jpeek/MetricsTest.java index cdda6a7a..ddf7a4b4 100644 --- a/src/test/java/org/jpeek/MetricsTest.java +++ b/src/test/java/org/jpeek/MetricsTest.java @@ -87,7 +87,20 @@ public final class MetricsTest { @Parameterized.Parameters(name = "{0}:{1}:{2}") public static Collection targets() { return new CollectionOf<>( - new Object[] {"NoMethods", "NHD", Double.NaN}, + new Object[] {"Bar", "CAMC", 0.4d}, + new Object[] {"Foo", "CAMC", 0.6667d}, + new Object[] {"MethodsWithDiffParamTypes", "CCM", 0.0476d}, + new Object[] {"Bar", "LCC", 0.0d}, + new Object[] {"Foo", "LCC", 1.0d}, + new Object[] {"MethodMethodCalls", "LCC", 0.1d}, + new Object[] {"MethodsWithDiffParamTypes", "LCC", 0.2d}, + new Object[] {"NoMethods", "LCC", 0.0d}, + new Object[] {"OneMethodCreatesLambda", "LCC", 0.0d}, + new Object[] {"OneVoidMethodWithoutParams", "LCC", 0.0d}, + new Object[] {"OnlyOneMethodWithParams", "LCC", 0.0d}, + new Object[] {"OverloadMethods", "LCC", 1.0d}, + new Object[] {"TwoCommonAttributes", "LCC", 0.0d}, + new Object[] {"WithoutAttributes", "LCC", 0.0d}, new Object[] {"Bar", "LCOM", 6.0d}, new Object[] {"Foo", "LCOM", 1.0d}, new Object[] {"MethodsWithDiffParamTypes", "LCOM", 15.0d}, @@ -97,8 +110,31 @@ public static Collection targets() { new Object[] {"TwoCommonAttributes", "LCOM", 6.0d}, new Object[] {"WithoutAttributes", "LCOM", 1.0d}, new Object[] {"OneMethodCreatesLambda", "LCOM", 3.0d}, - new Object[] {"Bar", "CAMC", 0.4d}, - new Object[] {"Foo", "CAMC", 0.6667d}, + new Object[] {"Foo", "LCOM2", 0.3333d}, + new Object[] {"MethodsWithDiffParamTypes", "LCOM2", 0.5714d}, + new Object[] {"NoMethods", "LCOM2", 1.0d}, + new Object[] {"OneVoidMethodWithoutParams", "LCOM2", 0.5d}, + new Object[] {"OverloadMethods", "LCOM2", 0.2d}, + new Object[] {"TwoCommonAttributes", "LCOM2", 0.75d}, + new Object[] {"WithoutAttributes", "LCOM2", 0.0d}, + new Object[] {"OneMethodCreatesLambda", "LCOM2", 1.0d}, + new Object[] {"Foo", "LCOM3", 0.5d}, + new Object[] {"MethodsWithDiffParamTypes", "LCOM3", 0.6667d}, + new Object[] {"NoMethods", "LCOM3", 0.0d}, + new Object[] {"OneVoidMethodWithoutParams", "LCOM3", 1.0d}, + new Object[] {"OverloadMethods", "LCOM3", 0.25d}, + new Object[] {"TwoCommonAttributes", "LCOM3", 1.0d}, + new Object[] {"WithoutAttributes", "LCOM3", 0.0d}, + new Object[] {"MethodMethodCalls", "LCOM4", 0.6d}, + new Object[] {"Bar", "LCOM5", 0.8125d}, + new Object[] {"Foo", "LCOM5", 0.5d}, + new Object[] {"MethodsWithDiffParamTypes", "LCOM5", 0.6667d}, + new Object[] {"OverloadMethods", "LCOM5", 0.25d}, + new Object[] {"TwoCommonAttributes", "LCOM5", 1.0d}, + new Object[] {"NoMethods", "LCOM5", Double.NaN}, + new Object[] {"WithoutAttributes", "LCOM5", Double.NaN}, + new Object[] {"OneVoidMethodWithoutParams", "LCOM5", 1.0d}, + new Object[] {"OneMethodCreatesLambda", "LCOM5", 1.5d}, new Object[] {"Bar", "MMAC", 0.1d}, new Object[] {"Foo", "MMAC", 0.3333d}, new Object[] {"MethodsWithDiffParamTypes", "MMAC", 0.0d}, @@ -108,46 +144,28 @@ public static Collection targets() { new Object[] {"TwoCommonAttributes", "MMAC", 0.1667d}, new Object[] {"WithoutAttributes", "MMAC", 0.0d}, new Object[] {"OneMethodCreatesLambda", "MMAC", 0.0d}, - new Object[] {"Foo", "LCOM5", 0.5d}, - new Object[] {"Bar", "LCOM5", 0.8125d}, - new Object[] {"MethodsWithDiffParamTypes", "LCOM5", 0.6667d}, - new Object[] {"OverloadMethods", "LCOM5", 0.25d}, - new Object[] {"TwoCommonAttributes", "LCOM5", 1.0d}, - new Object[] {"NoMethods", "LCOM5", Double.NaN}, - new Object[] {"WithoutAttributes", "LCOM5", Double.NaN}, - new Object[] {"OneVoidMethodWithoutParams", "LCOM5", 1.0d}, - new Object[] {"OneMethodCreatesLambda", "LCOM5", 1.5d}, new Object[] {"Bar", "NHD", 0.4d}, new Object[] {"Foo", "NHD", 0.3333d}, new Object[] {"MethodsWithDiffParamTypes", "NHD", 0.7143d}, new Object[] {"OverloadMethods", "NHD", 0.5333d}, new Object[] {"TwoCommonAttributes", "NHD", 0.3333d}, - new Object[] {"MethodsWithDiffParamTypes", "CCM", 0.0476d}, + new Object[] {"NoMethods", "NHD", Double.NaN}, + new Object[] {"Foo", "OCC", 0.5d}, + new Object[] {"MethodsWithDiffParamTypes", "PCC", 0.3333d}, new Object[] {"TwoCommonAttributes", "SCOM", 0.0d}, new Object[] {"NoMethods", "SCOM", Double.NaN}, new Object[] {"OneVoidMethodWithoutParams", "SCOM", 0.0d}, new Object[] {"WithoutAttributes", "SCOM", Double.NaN}, new Object[] {"OneMethodCreatesLambda", "SCOM", 0.0d}, - new Object[] {"Foo", "LCOM2", 0.3333d}, - new Object[] {"MethodsWithDiffParamTypes", "LCOM2", 0.5714d}, - new Object[] {"NoMethods", "LCOM2", 1.0d}, - new Object[] {"OneVoidMethodWithoutParams", "LCOM2", 0.5d}, - new Object[] {"OverloadMethods", "LCOM2", 0.2d}, - new Object[] {"TwoCommonAttributes", "LCOM2", 0.75d}, - new Object[] {"WithoutAttributes", "LCOM2", 0.0d}, - new Object[] {"OneMethodCreatesLambda", "LCOM2", 1.0d}, - new Object[] {"Foo", "LCOM3", 0.5d}, - new Object[] {"MethodsWithDiffParamTypes", "LCOM3", 0.6667d}, - new Object[] {"NoMethods", "LCOM3", 0.0d}, - new Object[] {"OneVoidMethodWithoutParams", "LCOM3", 1.0d}, - new Object[] {"OverloadMethods", "LCOM3", 0.25d}, - new Object[] {"TwoCommonAttributes", "LCOM3", 1.0d}, - new Object[] {"WithoutAttributes", "LCOM3", 0.0d}, - new Object[] {"MethodsWithDiffParamTypes", "PCC", 0.3333d}, - new Object[] {"Foo", "OCC", 0.5d}, new Object[] {"Bar", "TCC", 0.0d}, new Object[] {"Foo", "TCC", 1.0d}, + new Object[] {"IndirectlyRelatedPairs", "TCC", 0.6667}, + new Object[] {"MethodMethodCalls", "TCC", 0.1d}, new Object[] {"MethodsWithDiffParamTypes", "TCC", 0.2d}, + new Object[] {"NoMethods", "TCC", 0.0d}, + new Object[] {"OneMethodCreatesLambda", "TCC", 0.0d}, + new Object[] {"OneVoidMethodWithoutParams", "TCC", 0.0d}, + new Object[] {"OnlyOneMethodWithParams", "TCC", 0.0d}, new Object[] {"OverloadMethods", "TCC", 1.0d}, new Object[] {"TwoCommonAttributes", "TCC", 0.0d}, new Object[] {"WithoutAttributes", "TCC", 0.0d}, @@ -158,8 +176,7 @@ public static Collection targets() { new Object[] {"OnlyOneMethodWithParams", "TLCOM", 0.0d}, new Object[] {"OverloadMethods", "TLCOM", 0.0d}, new Object[] {"TwoCommonAttributes", "TLCOM", 4.0d}, - new Object[] {"WithoutAttributes", "TLCOM", 1.0d}, - new Object[] {"MethodMethodCalls", "LCOM4", 0.6d} + new Object[] {"WithoutAttributes", "TLCOM", 1.0d} ); } diff --git a/src/test/resources/org/jpeek/samples/IndirectlyRelatedPairs.java b/src/test/resources/org/jpeek/samples/IndirectlyRelatedPairs.java new file mode 100644 index 00000000..384cf275 --- /dev/null +++ b/src/test/resources/org/jpeek/samples/IndirectlyRelatedPairs.java @@ -0,0 +1,15 @@ +public final class IndirectlyRelatedPairs { + int a, b, c, d; + public IndirectlyRelatedPairs(final int x) { + methodOne(a+d); + } + public void methodOne(final int x) { + methodTwo(a+b); + } + public void methodTwo(final int x) { + methodThree(b+c); + } + public void methodThree(final int x) { + new IndirectlyRelatedPairs(c+d); + } +}