From 829667445aa95468b42e9f5c56d335ec336c5e61 Mon Sep 17 00:00:00 2001 From: Yegor Bugayenko Date: Wed, 10 Jan 2018 22:31:05 +0300 Subject: [PATCH] #85 Skeleton --- pom.xml | 2 +- src/main/java/org/jpeek/App.java | 43 ++- src/main/java/org/jpeek/Metric.java | 68 ---- src/main/java/org/jpeek/Report.java | 60 ++-- src/main/java/org/jpeek/Skeleton.java | 242 ++++++++++++++ .../org/jpeek/metrics/JavassistClasses.java | 172 ---------- src/main/java/org/jpeek/metrics/Methods.java | 103 ------ src/main/java/org/jpeek/metrics/Summary.java | 130 -------- .../java/org/jpeek/metrics/cohesion/CAMC.java | 189 ----------- .../java/org/jpeek/metrics/cohesion/LCOM.java | 113 ------- .../org/jpeek/metrics/cohesion/LCOM2.java | 117 ------- .../org/jpeek/metrics/cohesion/LCOM3.java | 115 ------- .../java/org/jpeek/metrics/cohesion/MMAC.java | 163 --------- .../java/org/jpeek/metrics/cohesion/NHD.java | 191 ----------- .../java/org/jpeek/metrics/cohesion/OCC.java | 310 ------------------ src/main/java/org/jpeek/web/Reports.java | 21 +- .../resources/org/jpeek/metrics/LCOM2.xsl | 44 +++ src/test/java/org/jpeek/ReportTest.java | 39 ++- .../java/org/jpeek/SkeletonTest.java} | 27 +- .../org/jpeek/metrics/cohesion/CAMCTest.java | 96 ------ .../org/jpeek/metrics/cohesion/LCOM2Test.java | 112 ------- .../org/jpeek/metrics/cohesion/LCOM3Test.java | 112 ------- .../org/jpeek/metrics/cohesion/LCOMTest.java | 78 ----- .../org/jpeek/metrics/cohesion/MMACTest.java | 129 -------- .../org/jpeek/metrics/cohesion/NHDTest.java | 80 ----- .../org/jpeek/metrics/cohesion/OCCTest.java | 96 ------ .../jpeek/metrics/cohesion/package-info.java | 32 -- 27 files changed, 399 insertions(+), 2485 deletions(-) delete mode 100644 src/main/java/org/jpeek/Metric.java create mode 100644 src/main/java/org/jpeek/Skeleton.java delete mode 100644 src/main/java/org/jpeek/metrics/JavassistClasses.java delete mode 100644 src/main/java/org/jpeek/metrics/Methods.java delete mode 100644 src/main/java/org/jpeek/metrics/Summary.java delete mode 100644 src/main/java/org/jpeek/metrics/cohesion/CAMC.java delete mode 100644 src/main/java/org/jpeek/metrics/cohesion/LCOM.java delete mode 100644 src/main/java/org/jpeek/metrics/cohesion/LCOM2.java delete mode 100644 src/main/java/org/jpeek/metrics/cohesion/LCOM3.java delete mode 100644 src/main/java/org/jpeek/metrics/cohesion/MMAC.java delete mode 100644 src/main/java/org/jpeek/metrics/cohesion/NHD.java delete mode 100644 src/main/java/org/jpeek/metrics/cohesion/OCC.java create mode 100644 src/main/resources/org/jpeek/metrics/LCOM2.xsl rename src/{main/java/org/jpeek/metrics/cohesion/package-info.java => test/java/org/jpeek/SkeletonTest.java} (66%) delete mode 100644 src/test/java/org/jpeek/metrics/cohesion/CAMCTest.java delete mode 100644 src/test/java/org/jpeek/metrics/cohesion/LCOM2Test.java delete mode 100644 src/test/java/org/jpeek/metrics/cohesion/LCOM3Test.java delete mode 100644 src/test/java/org/jpeek/metrics/cohesion/LCOMTest.java delete mode 100644 src/test/java/org/jpeek/metrics/cohesion/MMACTest.java delete mode 100644 src/test/java/org/jpeek/metrics/cohesion/NHDTest.java delete mode 100644 src/test/java/org/jpeek/metrics/cohesion/OCCTest.java delete mode 100644 src/test/java/org/jpeek/metrics/cohesion/package-info.java diff --git a/pom.xml b/pom.xml index f50aa863..80f220dd 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ SOFTWARE. org.cactoos cactoos - 0.25.5 + 0.28.2 org.takes diff --git a/src/main/java/org/jpeek/App.java b/src/main/java/org/jpeek/App.java index 161700f2..a2d56664 100644 --- a/src/main/java/org/jpeek/App.java +++ b/src/main/java/org/jpeek/App.java @@ -40,13 +40,6 @@ import org.cactoos.scalar.And; import org.cactoos.scalar.AndInThreads; import org.cactoos.scalar.IoCheckedScalar; -import org.jpeek.metrics.cohesion.CAMC; -import org.jpeek.metrics.cohesion.LCOM; -import org.jpeek.metrics.cohesion.LCOM2; -import org.jpeek.metrics.cohesion.LCOM3; -import org.jpeek.metrics.cohesion.MMAC; -import org.jpeek.metrics.cohesion.NHD; -import org.jpeek.metrics.cohesion.OCC; import org.xembly.Directives; import org.xembly.Xembler; @@ -98,14 +91,16 @@ public void analyze() throws IOException { ); } final Base base = new DefaultBase(this.input); + final XML skeleton = new Skeleton(base).xml(); + this.save(skeleton.toString(), "skeleton.xml"); final Iterable reports = new ListOf<>( - new Report(new CAMC(base), 0.45d, 0.10d), - new Report(new LCOM(base), 14.0d, 77.0d), - new Report(new LCOM2(base), 0.83d, -0.10d), - new Report(new LCOM3(base), 0.96d, -0.11d), - new Report(new MMAC(base), 0.08d, 0.11d), - new Report(new NHD(base), 0.53d, -0.08d), - new Report(new OCC(base), 0.43d, -0.10d) + new Report(skeleton, "CAMC", 0.45d, 0.10d), + new Report(skeleton, "LCOM", 14.0d, 77.0d), + new Report(skeleton, "LCOM2", 0.83d, -0.10d), + new Report(skeleton, "LCOM3", 0.96d, -0.11d), + new Report(skeleton, "MMAC", 0.08d, 0.11d), + new Report(skeleton, "NHD", 0.53d, -0.08d), + new Report(skeleton, "OCC", 0.43d, -0.10d) ); new IoCheckedScalar<>( new AndInThreads( @@ -170,10 +165,12 @@ public void analyze() throws IOException { * @throws IOException If fails */ private void copy(final String name) throws IOException { - new LengthOf( - new TeeInput( - new ResourceOf(String.format("org/jpeek/%s", name)), - this.output.resolve(name) + new IoCheckedScalar<>( + new LengthOf( + new TeeInput( + new ResourceOf(String.format("org/jpeek/%s", name)), + this.output.resolve(name) + ) ) ).value(); } @@ -194,10 +191,12 @@ private void copyXsl(final String name) throws IOException { * @throws IOException If fails */ private void save(final String data, final String name) throws IOException { - new LengthOf( - new TeeInput( - data, - this.output.resolve(name) + new IoCheckedScalar<>( + new LengthOf( + new TeeInput( + data, + this.output.resolve(name) + ) ) ).value(); } diff --git a/src/main/java/org/jpeek/Metric.java b/src/main/java/org/jpeek/Metric.java deleted file mode 100644 index 4d343d1b..00000000 --- a/src/main/java/org/jpeek/Metric.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek; - -import java.io.IOException; -import org.xembly.Directive; - -/** - * Single metric. - * - *

There is no thread-safety guarantee. - * - * @author Yegor Bugayenko (yegor256@gmail.com) - * @version $Id$ - * @since 0.1 - */ -public interface Metric { - - /** - * Present it in XML format. - * @return XML report - * @throws IOException If fails - */ - Iterable xembly() throws IOException; - - /** - * Fixed. - */ - final class Fixed implements Metric { - /** - * Dirs. - */ - private final Iterable dirs; - /** - * Ctor. - * @param list List of them - */ - public Fixed(final Iterable list) { - this.dirs = list; - } - @Override - public Iterable xembly() { - return this.dirs; - } - } - -} diff --git a/src/main/java/org/jpeek/Report.java b/src/main/java/org/jpeek/Report.java index 2745f5b5..e8ffcc22 100644 --- a/src/main/java/org/jpeek/Report.java +++ b/src/main/java/org/jpeek/Report.java @@ -24,9 +24,9 @@ package org.jpeek; import com.jcabi.xml.ClasspathSources; +import com.jcabi.xml.Sources; import com.jcabi.xml.StrictXML; import com.jcabi.xml.XML; -import com.jcabi.xml.XMLDocument; import com.jcabi.xml.XSD; import com.jcabi.xml.XSDDocument; import com.jcabi.xml.XSL; @@ -36,10 +36,12 @@ import org.cactoos.io.LengthOf; import org.cactoos.io.TeeInput; import org.cactoos.iterable.IterableOf; +import org.cactoos.map.MapEntry; +import org.cactoos.map.MapOf; import org.cactoos.scalar.IoCheckedScalar; import org.cactoos.scalar.Reduced; -import org.xembly.Directives; -import org.xembly.Xembler; +import org.cactoos.text.TextOf; +import org.cactoos.time.DateAsText; /** * Single report. @@ -67,10 +69,15 @@ final class Report { Report.class.getResourceAsStream("xsl/metric.xsl") ).with(new ClasspathSources()); + /** + * The skeleton. + */ + private final XML skeleton; + /** * The metric. */ - private final Metric metric; + private final String metric; /** * Post processing XSLs. @@ -79,21 +86,24 @@ final class Report { /** * Ctor. - * @param mtc Metric + * @param xml Skeleton + * @param name Name of the metric */ - Report(final Metric mtc) { - // @checkstyle MagicNumber (1 line) - this(mtc, 0.5d, 0.25d); + Report(final XML xml, final String name) { + this(xml, name, 0.5d, 0.1d); } /** * Ctor. - * @param mtc Metric + * @param xml Skeleton + * @param name Name of the metric * @param mean Mean * @param sigma Sigma */ - Report(final Metric mtc, final double mean, final double sigma) { - this.metric = mtc; + Report(final XML xml, final String name, + final double mean, final double sigma) { + this.skeleton = xml; + this.metric = name; this.post = new IterableOf<>( new XSLDocument( Report.class.getResourceAsStream("xsl/metric-post-colors.xsl") @@ -135,7 +145,7 @@ public void save(final Path target) throws IOException { ) ) ) - ).value(); + ).intValue(); new LengthOf( new TeeInput( Report.STYLESHEET.transform(xml).toString(), @@ -146,7 +156,7 @@ public void save(final Path target) throws IOException { ) ) ) - ).value(); + ).intValue(); } /** @@ -155,18 +165,18 @@ public void save(final Path target) throws IOException { * @throws IOException If fails */ private XML xml() throws IOException { - return new XMLDocument( - new Xembler( - new Directives() - .pi("xml-stylesheet", "href='metric.xsl' type='text/xsl'") - .append(this.metric.xembly()) - .xpath("/metric") - .append(new Header()) - .add("title") - .set(this.metric.getClass().getSimpleName()) - .up() - ).xmlQuietly() - ); + return new XSLDocument( + new TextOf( + this.getClass().getResource( + String.format("metrics/%s.xsl", this.metric) + ) + ).asString(), + Sources.DUMMY, + new MapOf<>( + new MapEntry<>("version", new Version().value()), + new MapEntry<>("date", new DateAsText()) + ) + ).transform(this.skeleton); } } diff --git a/src/main/java/org/jpeek/Skeleton.java b/src/main/java/org/jpeek/Skeleton.java new file mode 100644 index 00000000..bb422f58 --- /dev/null +++ b/src/main/java/org/jpeek/Skeleton.java @@ -0,0 +1,242 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Yegor Bugayenko + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.jpeek; + +import com.jcabi.xml.XML; +import com.jcabi.xml.XMLDocument; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import org.cactoos.iterable.Filtered; +import org.cactoos.iterable.Joined; +import org.cactoos.iterable.Mapped; +import org.cactoos.map.MapEntry; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.signature.SignatureReader; +import org.objectweb.asm.signature.SignatureVisitor; +import org.xembly.Directive; +import org.xembly.Directives; +import org.xembly.Xembler; + +/** + * Classes into XML. + * + *

We take into account only classes. Interfaces are ignored.

+ * + *

There is no thread-safety guarantee. + * + * @author Yegor Bugayenko (yegor256@gmail.com) + * @version $Id$ + * @see A metrics suite for object oriented design + * @since 0.23 + * @checkstyle AbbreviationAsWordInNameCheck (5 lines) + * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) + */ +final class Skeleton { + + /** + * The base. + */ + private final Base base; + + /** + * Javassist pool. + */ + private final ClassPool pool; + + /** + * Ctor. + * @param bse The base + */ + Skeleton(final Base bse) { + this.base = bse; + this.pool = new ClassPool(); + } + + /** + * As XML. + * @return XML + * @throws IOException If fails + */ + public XML xml() throws IOException { + return new XMLDocument( + new Xembler( + new Directives() + .add("metric") + .add("app") + .attr("id", this.base) + .append( + new Joined( + new Mapped<>( + ent -> new Directives() + .add("package") + .attr("id", ent.getKey()) + .append(ent.getValue()) + .up(), + this.metrics() + ) + ) + ) + ).xmlQuietly() + ); + } + + /** + * Calculate metrics for all classes. + * @return Metrics + * @throws IOException If fails + */ + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") + private Iterable> metrics() + throws IOException { + final Map map = new HashMap<>(0); + final Iterable> all = new Mapped<>( + Skeleton::metric, + new Filtered<>( + // @checkstyle BooleanExpressionComplexityCheck (10 lines) + ctClass -> !ctClass.isInterface() + && !ctClass.isEnum() + && !ctClass.isAnnotation() + && !ctClass.getName().matches("^.+\\$[0-9]+$") + && !ctClass.getName().matches("^.+\\$AjcClosure[0-9]+$"), + new Mapped<>( + path -> { + try (InputStream stream = + new FileInputStream(path.toFile())) { + return this.pool.makeClassIfNew(stream); + } + }, + new Filtered<>( + path -> Files.isRegularFile(path) + && path.toString().endsWith(".class"), + this.base.files() + ) + ) + ) + ); + for (final Map.Entry ent : all) { + map.putIfAbsent(ent.getKey(), new Directives()); + map.get(ent.getKey()).append(ent.getValue()); + } + return map.entrySet(); + } + + /** + * Calculate metrics for a single .class file. + * @param ctc The class + * @return Metrics + */ + private static Map.Entry metric(final CtClass ctc) { + ctc.defrost(); + String pkg = ctc.getPackageName(); + if (pkg == null) { + pkg = ""; + } + return new MapEntry<>( + pkg, + new Directives() + .add("class") + .attr("id", ctc.getSimpleName()) + .append(Skeleton.xembly(ctc)) + .up() + ); + } + + /** + * Turn class into XML. + * @param ctc The class + * @return XML + * @checkstyle ParameterNumberCheck (200 lines) + * @checkstyle AnonInnerLengthCheck (200 lines) + */ + private static Iterable xembly(final CtClass ctc) { + final ClassReader reader; + try { + reader = new ClassReader(ctc.toBytecode()); + } catch (final IOException | CannotCompileException ex) { + throw new IllegalStateException(ex); + } + final Directives dirs = new Directives(); + reader.accept( + new ClassVisitor(Opcodes.ASM6) { + @Override + public MethodVisitor visitMethod(final int access, + final String mtd, final String desc, + final String signature, final String[] exceptions) { + super.visitMethod(access, mtd, desc, signature, exceptions); + System.out.println(desc); + dirs.add("method") + .attr("name", mtd) + .attr("desc", desc) + .up(); + return new MethodVisitor(Opcodes.ASM6) { + @Override + public void visitFieldInsn(final int opcode, + final String owner, final String attr, + final String details) { + super.visitFieldInsn(opcode, owner, attr, details); + dirs.xpath( + String.format( + "method[@desc='%s']", desc + ) + ).strict(1).add("argument").set(attr); + new SignatureReader(desc).accept( + new SignatureVisitor(Opcodes.ASM6) { + @Override + public void visitClassType(final String name) { + super.visitClassType(name); + dirs.attr("type", name); + } + @Override + public void visitBaseType(final char name) { + super.visitBaseType(name); + if ('V' != name) { + dirs.attr( + "type", + String.format(".%s", name) + ); + } + } + } + ); + dirs.up().up(); + } + }; + } + }, + 0 + ); + return dirs; + } + +} diff --git a/src/main/java/org/jpeek/metrics/JavassistClasses.java b/src/main/java/org/jpeek/metrics/JavassistClasses.java deleted file mode 100644 index fa402303..00000000 --- a/src/main/java/org/jpeek/metrics/JavassistClasses.java +++ /dev/null @@ -1,172 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.util.HashMap; -import java.util.Map; -import javassist.ClassPool; -import javassist.CtClass; -import org.cactoos.Func; -import org.cactoos.func.IoCheckedFunc; -import org.cactoos.iterable.Filtered; -import org.cactoos.iterable.Joined; -import org.cactoos.iterable.Mapped; -import org.cactoos.map.MapEntry; -import org.jpeek.Base; -import org.jpeek.Metric; -import org.xembly.Directive; -import org.xembly.Directives; - -/** - * Classes parsed by Javassist. - * - *

We take into account only classes. Interfaces are ignored.

- * - *

There is no thread-safety guarantee. - * - * @author Yegor Bugayenko (yegor256@gmail.com) - * @version $Id$ - * @see A metrics suite for object oriented design - * @since 0.2 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) - */ -public final class JavassistClasses implements Metric { - - /** - * The base. - */ - private final Base base; - - /** - * Func. - */ - private final IoCheckedFunc> func; - - /** - * Javassist pool. - */ - private final ClassPool pool; - - /** - * Ctor. - * @param bse The base - * @param fnc Func - */ - public JavassistClasses(final Base bse, - final Func> fnc) { - this.base = bse; - this.pool = new ClassPool(); - this.func = new IoCheckedFunc<>(fnc); - } - - @Override - public Iterable xembly() throws IOException { - return new Directives() - .add("metric") - .add("app") - .attr("id", this.base) - .append( - new Joined( - new Mapped<>( - ent -> new Directives() - .add("package") - .attr("id", ent.getKey()) - .append(ent.getValue()) - .up(), - this.metrics() - ) - ) - ); - } - - /** - * Calculate metrics for all classes. - * @return Metrics - * @throws IOException If fails - */ - @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") - private Iterable> metrics() - throws IOException { - final Map map = new HashMap<>(0); - final Iterable> all = new Mapped<>( - this::metric, - new Filtered<>( - // @checkstyle BooleanExpressionComplexityCheck (10 lines) - ctClass -> !ctClass.isInterface() - && !ctClass.isEnum() - && !ctClass.isAnnotation() - && !ctClass.getName().matches("^.+\\$[0-9]+$") - && !ctClass.getName().matches("^.+\\$AjcClosure[0-9]+$"), - new Mapped<>( - path -> { - try (InputStream stream = - new FileInputStream(path.toFile())) { - return this.pool.makeClassIfNew(stream); - } - }, - new Filtered<>( - path -> Files.isRegularFile(path) - && path.toString().endsWith(".class"), - this.base.files() - ) - ) - ) - ); - for (final Map.Entry ent : all) { - map.putIfAbsent(ent.getKey(), new Directives()); - map.get(ent.getKey()).append(ent.getValue()); - } - return map.entrySet(); - } - - /** - * Calculate metrics for a single .class file. - * @param ctc The class - * @return Metrics - * @throws IOException If fails - */ - private Map.Entry metric( - final CtClass ctc) throws IOException { - final Iterable cohesion = this.func.apply(ctc); - ctc.defrost(); - String pkg = ctc.getPackageName(); - if (pkg == null) { - pkg = ""; - } - return new MapEntry<>( - pkg, - new Directives() - .add("class") - .attr("id", ctc.getSimpleName()) - .append(cohesion) - .up() - ); - } - -} diff --git a/src/main/java/org/jpeek/metrics/Methods.java b/src/main/java/org/jpeek/metrics/Methods.java deleted file mode 100644 index e888fce4..00000000 --- a/src/main/java/org/jpeek/metrics/Methods.java +++ /dev/null @@ -1,103 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics; - -import java.io.IOException; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import javassist.CannotCompileException; -import javassist.CtClass; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -/** - * Methods of a class. - * - *

There is no thread-safety guarantee. - * - * @author Yegor Bugayenko (yegor256@gmail.com) - * @version $Id$ - * @see A metrics suite for object oriented design - * @since 0.18 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) - */ -public final class Methods implements Iterable> { - - /** - * The class. - */ - private final CtClass source; - - /** - * Ctor. - * @param cls The class - */ - public Methods(final CtClass cls) { - this.source = cls; - } - - @Override - @SuppressWarnings({ "PMD.UseObjectForClearerAPI", "PMD.UseVarargs" }) - public Iterator> iterator() { - final ClassReader reader; - try { - reader = new ClassReader(this.source.toBytecode()); - } catch (final IOException | CannotCompileException ex) { - throw new IllegalStateException(ex); - } - final Collection> methods = new LinkedList<>(); - reader.accept( - // @checkstyle AnonInnerLengthCheck (50 lines) - new ClassVisitor(Opcodes.ASM6) { - @Override - // @checkstyle ParameterNumberCheck (5 lines) - public MethodVisitor visitMethod(final int access, - final String mtd, final String desc, - final String signature, final String[] exceptions) { - super.visitMethod(access, mtd, desc, signature, exceptions); - final Collection attrs = new HashSet<>(0); - methods.add(attrs); - return new MethodVisitor(Opcodes.ASM6) { - @Override - // @checkstyle ParameterNumberCheck (5 lines) - public void visitFieldInsn(final int opcode, - final String owner, final String attr, - final String details) { - super.visitFieldInsn(opcode, owner, attr, details); - attrs.add(attr); - } - }; - } - }, - 0 - ); - return methods.iterator(); - } - -} diff --git a/src/main/java/org/jpeek/metrics/Summary.java b/src/main/java/org/jpeek/metrics/Summary.java deleted file mode 100644 index 517df9da..00000000 --- a/src/main/java/org/jpeek/metrics/Summary.java +++ /dev/null @@ -1,130 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; -import org.cactoos.iterable.Joined; -import org.cactoos.iterable.Mapped; -import org.cactoos.map.MapEntry; -import org.cactoos.map.StickyMap; -import org.xembly.Directive; -import org.xembly.Directives; - -/** - * Summary of one class. - * - *

There is no thread-safety guarantee. - * - * @author Yegor Bugayenko (yegor256@gmail.com) - * @version $Id$ - * @see A metrics suite for object oriented design - * @since 0.13 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) - */ -public final class Summary implements Iterable { - - /** - * The value. - */ - private final double value; - - /** - * Vars. - */ - private final Map vars; - - /** - * Ctor. - */ - public Summary() { - this(0.0d); - } - - /** - * Ctor. - * @param val The value - */ - public Summary(final double val) { - this(val, new HashMap<>(0)); - } - - /** - * Ctor. - * @param val The value - * @param map The map of vars - */ - private Summary(final double val, final Map map) { - this.value = val; - this.vars = map; - } - - @Override - public Iterator iterator() { - return new Directives() - .attr("value", String.format(Locale.ENGLISH, "%.4f", this.value)) - .add("vars") - .append( - new Joined( - new Mapped<>( - ent -> new Directives() - .add("var") - .attr("id", ent.getKey()) - .set(ent.getValue()) - .up(), - this.vars.entrySet() - ) - ) - ) - .up() - .iterator(); - } - - /** - * With this var. - * @param var The var name - * @param val The value - * @return Summary - */ - public Summary with(final String var, final int val) { - return this.with(var, (double) val); - } - - /** - * With this var. - * @param var The var name - * @param val The value - * @return Summary - */ - public Summary with(final String var, final double val) { - return new Summary( - this.value, - new StickyMap(this.vars, new MapEntry<>(var, val)) - ); - } - -} diff --git a/src/main/java/org/jpeek/metrics/cohesion/CAMC.java b/src/main/java/org/jpeek/metrics/cohesion/CAMC.java deleted file mode 100644 index 9c51afdd..00000000 --- a/src/main/java/org/jpeek/metrics/cohesion/CAMC.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import java.io.IOException; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import javassist.CtClass; -import javassist.CtConstructor; -import javassist.CtMethod; -import javassist.Modifier; -import javassist.NotFoundException; -import org.cactoos.collection.Joined; -import org.cactoos.iterator.Mapped; -import org.jpeek.Base; -import org.jpeek.Metric; -import org.jpeek.metrics.JavassistClasses; -import org.jpeek.metrics.Summary; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.signature.SignatureReader; -import org.objectweb.asm.signature.SignatureVisitor; -import org.xembly.Directive; - -/** - * Cohesion Among Methods of Classes (CAMC). - * - *

In the CAMC metric, the cohesion in the methods of - * a class is determined by the types of objects (parameter - * access pattern of methods) that method’s take as input parameters. - * The metric determines the overlap in the object types of - * the methods parameter lists. The amount of overlap in object - * types used by the methods of a class can be used to predict - * the cohesion of the class.

- * - *

The metric value ranges between 0 and 1.0. A value of - * 1.0 represents maximum cohesion and 0 represents - * a completely un-cohesive class.

- * - *

There is no thread-safety guarantee. - * - * @author Yegor Bugayenko (yegor256@gmail.com) - * @author Mehmet Yildirim (memoyil@gmail.com) - * @version $Id$ - * @see A class cohesion metric for object-oriented designs - * @since 0.1 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) - */ -public final class CAMC implements Metric { - - /** - * The base. - */ - private final Base base; - - /** - * Ctor. - * @param bse The base - */ - public CAMC(final Base bse) { - this.base = bse; - } - - @Override - public Iterable xembly() throws IOException { - return new JavassistClasses( - this.base, CAMC::cohesion - ).xembly(); - } - - /** - * Calculate CAMC metric for a single Java class. - * @param ctc The .class file - * @return Metrics - * @throws NotFoundException If fails - */ - private static Iterable cohesion(final CtClass ctc) - throws NotFoundException { - final Collection> methods = CAMC.methods(ctc); - final Collection types = new HashSet<>( - new Joined( - () -> new Mapped<>( - strings -> strings, - methods.iterator() - ) - ) - ); - int sum = 0; - for (final String type : types) { - int mine = 0; - for (final Collection mtd : methods) { - if (mtd.contains(type)) { - ++mine; - } - } - sum += mine; - } - final double cohesion; - if (types.isEmpty() || methods.isEmpty()) { - cohesion = 1.0d; - } else { - cohesion = (double) sum / (double) (types.size() * methods.size()); - } - return new Summary(cohesion) - .with("sum", sum) - .with("types", types.size()) - .with("methods", methods.size()); - } - - /** - * Get all method signatures. - * @param ctc The .class file - * @return Method signatures - */ - @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") - private static Collection> methods(final CtClass ctc) { - final Collection> methods = new LinkedList<>(); - for (final CtMethod mtd : ctc.getDeclaredMethods()) { - if (Modifier.isPrivate(mtd.getModifiers())) { - continue; - } - final Collection args = new LinkedList<>(); - for (final String arg : CAMC.types(mtd.getSignature())) { - args.add(arg); - } - methods.add(args); - } - for (final CtConstructor ctor : ctc.getConstructors()) { - if (Modifier.isPrivate(ctor.getModifiers())) { - continue; - } - final Collection args = new LinkedList<>(); - for (final String arg : CAMC.types(ctor.getSignature())) { - args.add(arg); - } - methods.add(args); - } - return methods; - } - - /** - * Get parameter types from a method/ctor signature. - * @param sig Signature - * @return Types of params - */ - private static Iterable types(final String sig) { - final Collection types = new LinkedList<>(); - new SignatureReader(sig).accept( - new SignatureVisitor(Opcodes.ASM6) { - @Override - public void visitClassType(final String name) { - super.visitClassType(name); - types.add(name); - } - @Override - public void visitBaseType(final char name) { - super.visitBaseType(name); - if ('V' != name) { - types.add(String.format(".%s", name)); - } - } - } - ); - return types; - } - -} diff --git a/src/main/java/org/jpeek/metrics/cohesion/LCOM.java b/src/main/java/org/jpeek/metrics/cohesion/LCOM.java deleted file mode 100644 index 4dbf5509..00000000 --- a/src/main/java/org/jpeek/metrics/cohesion/LCOM.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import javassist.CtClass; -import org.cactoos.list.ListOf; -import org.jpeek.Base; -import org.jpeek.Metric; -import org.jpeek.metrics.JavassistClasses; -import org.jpeek.metrics.Methods; -import org.jpeek.metrics.Summary; -import org.xembly.Directive; - -/** - * Lack of Cohesion in Methods (LCOM). - * - *

LCOM is calculated as the number of pairs of methods - * operating on disjoint sets of instance variables, - * reduced by the number of method pairs acting on at - * least one shared instance variable.

- * - *

Say, there are 5 methods in a class. This means that there are 10 - * pairs of methods ({@code 5 * 4 / 2}). Now, we need to see how many of these - * pairs are using at least one and the same attribute (Nonempty) and how many - * of them are not using any similar attributes (Empty). Then, we - * just do {@code LCOM = Empty - Nonempty}. The metric can be really big, - * starting from zero and up to any possible number. The bigger the - * value the least cohesive is the class. A perfect design would have - * {@code LCOM=0}.

- * - *

There is no thread-safety guarantee. - * - * @author Yegor Bugayenko (yegor256@gmail.com) - * @version $Id$ - * @see A metrics suite for object oriented design - * @since 0.2 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) - */ -public final class LCOM implements Metric { - - /** - * The base. - */ - private final Base base; - - /** - * Ctor. - * @param bse The base - */ - public LCOM(final Base bse) { - this.base = bse; - } - - @Override - public Iterable xembly() throws IOException { - return new JavassistClasses( - this.base, LCOM::cohesion - ).xembly(); - } - - /** - * Calculate LCOM metric for a single Java class. - * @param ctc The .class file - * @return Metrics - */ - private static Iterable cohesion(final CtClass ctc) { - final List> methods = new ListOf<>( - new Methods(ctc) - ); - int empty = 0; - int nonempty = 0; - for (int idx = 0; idx < methods.size(); ++idx) { - for (int jdx = idx + 1; jdx < methods.size(); ++jdx) { - if (Collections.disjoint(methods.get(idx), methods.get(jdx))) { - ++empty; - } else { - ++nonempty; - } - } - } - return new Summary(Math.max(0.0d, (double) (empty - nonempty))) - .with("E", empty) - .with("NE", nonempty) - .with("methods", methods.size()); - } - -} diff --git a/src/main/java/org/jpeek/metrics/cohesion/LCOM2.java b/src/main/java/org/jpeek/metrics/cohesion/LCOM2.java deleted file mode 100644 index a676d264..00000000 --- a/src/main/java/org/jpeek/metrics/cohesion/LCOM2.java +++ /dev/null @@ -1,117 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import java.io.IOException; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import javassist.CtClass; -import org.cactoos.collection.Joined; -import org.cactoos.iterable.Mapped; -import org.cactoos.list.ListOf; -import org.jpeek.Base; -import org.jpeek.Metric; -import org.jpeek.metrics.JavassistClasses; -import org.jpeek.metrics.Methods; -import org.jpeek.metrics.Summary; -import org.xembly.Directive; - -/** - * Lack of Cohesion in Methods 2 (LCOM2). - * - *

Consider a class C with methods M1,M2,…..,Mn. Let {Ii}=set of - * instance variables used by method Mi. There are n such sets, i.e., {1i}, - * {I2},..,{In}. Let P={(Ii,Ij)|Ii∩Ij=Ø} and Q=(Ii,Ij) | - * Ii∩Ij≠Ø}. If all n sets {1i},{I2},..,{In} are Ø then let P=Ø.

- * - *

The metric value ranges between 0 and 1.0. A value of - * 1.0 represents minimum cohesion and 0 represents - * a completely cohesive class.

- * - *

There is no thread-safety guarantee.

- * - * @author Mehmet Yildirim (memoyil@gmail.com) - * @version $Id$ - * @see A metrics suite for object oriented design - * @since 0.2 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) - */ -public final class LCOM2 implements Metric { - - /** - * The base. - */ - private final Base base; - - /** - * Ctor. - * - * @param bse The base - */ - public LCOM2(final Base bse) { - this.base = bse; - } - - @Override - public Iterable xembly() throws IOException { - return new JavassistClasses( - this.base, LCOM2::cohesion - ).xembly(); - } - - /** - * Calculate LCOM2 metric for a single Java class. - * - * @param ctc The .class file - * @return Metrics - */ - private static Iterable cohesion(final CtClass ctc) { - final List> methods = new ListOf<>( - new Methods(ctc) - ); - final Collection attrs = new HashSet<>( - new Joined<>(new Mapped<>(list -> list, methods)) - ); - int sum = 0; - double result = 0; - for (final String attr : attrs) { - for (final Collection mattrs : methods) { - if (mattrs.contains(attr)) { - ++sum; - } - } - } - if (!attrs.isEmpty() && !methods.isEmpty()) { - result = 1 - (double) sum / (double) (attrs.size() - * methods.size()); - } - return new Summary(result) - .with("sum", sum) - .with("attrs", attrs.size()) - .with("methods", methods.size()); - } - -} diff --git a/src/main/java/org/jpeek/metrics/cohesion/LCOM3.java b/src/main/java/org/jpeek/metrics/cohesion/LCOM3.java deleted file mode 100644 index 99017bc1..00000000 --- a/src/main/java/org/jpeek/metrics/cohesion/LCOM3.java +++ /dev/null @@ -1,115 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import java.io.IOException; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import javassist.CtClass; -import org.cactoos.collection.Joined; -import org.cactoos.iterable.Mapped; -import org.cactoos.list.ListOf; -import org.jpeek.Base; -import org.jpeek.Metric; -import org.jpeek.metrics.JavassistClasses; -import org.jpeek.metrics.Methods; -import org.jpeek.metrics.Summary; -import org.xembly.Directive; - -/** - * Lack of Cohesion in Methods 2 (LCOM2). - * - *

Consider an undirected graph G where the vertices are the methods of a - * class, and there is an edge between two vertices if the corresponding - * methods share at least one instance variable.

- * - *

The metric value ranges between 0 and 1.0. A value of - * 1.0 represents minimum cohesion and 0 represents - * a completely cohesive class.

- * - *

There is no thread-safety guarantee.

- * - * @author Mehmet Yildirim (memoyil@gmail.com) - * @version $Id$ - * @see A metrics suite for object oriented design - * @since 0.2 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) - */ -public final class LCOM3 implements Metric { - - /** - * The base. - */ - private final Base base; - - /** - * Ctor. - * @param bse The base - */ - public LCOM3(final Base bse) { - this.base = bse; - } - - @Override - public Iterable xembly() throws IOException { - return new JavassistClasses( - this.base, LCOM3::cohesion - ).xembly(); - } - - /** - * Calculate LCOM2 metric for a single Java class. - * @param ctc The .class file - * @return Metrics - */ - private static Iterable cohesion(final CtClass ctc) { - final List> methods = new ListOf<>( - new Methods(ctc) - ); - final Collection attrs = new HashSet<>( - new Joined<>(new Mapped<>(list -> list, methods)) - ); - int sum = 0; - for (final String attr : attrs) { - for (final Collection methodattrs : methods) { - if (methodattrs.contains(attr)) { - ++sum; - } - } - } - double result = 0.0d; - if (!attrs.isEmpty() && methods.size() != 1) { - final int methodsize = methods.size(); - result = ((double) methodsize - (double) sum / (double) attrs - .size()) / (methodsize - 1); - } - return new Summary(result) - .with("sum", sum) - .with("attrs", attrs.size()) - .with("methods", methods.size()); - } - -} diff --git a/src/main/java/org/jpeek/metrics/cohesion/MMAC.java b/src/main/java/org/jpeek/metrics/cohesion/MMAC.java deleted file mode 100644 index e4fba3ad..00000000 --- a/src/main/java/org/jpeek/metrics/cohesion/MMAC.java +++ /dev/null @@ -1,163 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import java.io.IOException; -import java.util.Collection; -import java.util.HashSet; -import javassist.CtBehavior; -import javassist.CtClass; -import javassist.CtMethod; -import org.cactoos.iterable.Filtered; -import org.cactoos.iterable.IterableOf; -import org.cactoos.iterable.Mapped; -import org.cactoos.list.ListOf; -import org.jpeek.Base; -import org.jpeek.Metric; -import org.jpeek.metrics.JavassistClasses; -import org.jpeek.metrics.Summary; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.signature.SignatureReader; -import org.objectweb.asm.signature.SignatureVisitor; -import org.xembly.Directive; - -/** - * Method-Method through Attributes Cohesion (MMAC). - * - *

The MMAC is the average cohesion of all pairs of methods. - * In simple words this metric shows how much methods have the - * same parameters or return types. When class has some number - * of methods and most of them operate the same parameters it - * assumes better. It looks like class contains overloaded - * methods. Preferably when class has only one method with - * parameters and/or return type and it assumes that class - * do only one thing. Value of MMAC metric is better for these - * one classes.

- * - *

Metric value is in interval [0, 1]. Value closer to 1 is better.

- * - * @author Sergey Karazhenets (sergeykarazhenets@gmail.com) - * @version $Id$ - * @see - * Class Cohesion Metrics for Software Engineering: A Critical Review - * @since 0.2 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) - */ -public final class MMAC implements Metric { - - /** - * Source code base. - */ - private final Base base; - - /** - * Ctor. - * @param bse The base. - */ - public MMAC(final Base bse) { - this.base = bse; - } - - @Override - public Iterable xembly() throws IOException { - return new JavassistClasses( - this.base, MMAC::cohesion - ).xembly(); - } - - /** - * Calculates MMAC metric for a single Java class. - * - * @param ctc The .class file - * @return MMAC metric - * @checkstyle TrailingCommentCheck (50 lines) - */ - @SuppressWarnings( - { - "PMD.CyclomaticComplexity", - "PMD.StdCyclomaticComplexity", - "PMD.ModifiedCyclomaticComplexity" - } - ) - private static Iterable cohesion(final CtClass ctc) { - final Collection> methods = new ListOf<>( - new Mapped<>( - signature -> { - final Collection types = new HashSet<>(0); - new SignatureReader(signature).accept( - new SignatureVisitor(Opcodes.ASM6) { - @Override - public void visitClassType(final String name) { - super.visitClassType(name); - types.add(name); - } - @Override - public void visitBaseType(final char name) { - super.visitBaseType(name); - if ('V' != name) { - types.add(String.valueOf(name)); - } - } - } - ); - return types; - }, - new Mapped( - CtBehavior::getSignature, - new Filtered<>( - mtd -> !mtd.getName().contains("$"), - new IterableOf<>(ctc.getDeclaredMethods()) - ) - ) - ) - ); - final Collection types = new HashSet<>(0); - for (final Collection method : methods) { - types.addAll(method); - } - double sum = 0.0d; - for (final String type : types) { - int mcnt = 0; - for (final Collection method : methods) { - if (method.contains(type)) { - ++mcnt; - } - } - sum += mcnt * (mcnt - 1); - } - final int div = types.size() * methods.size() * (methods.size() - 1); - final double value; - if (methods.size() == 1) { - value = 1.0d; - } else if (div == 0) { - value = 0.0d; - } else { - value = sum / (double) div; - } - return new Summary(value) - .with("methods", methods.size()) - .with("types", types.size()); - } -} diff --git a/src/main/java/org/jpeek/metrics/cohesion/NHD.java b/src/main/java/org/jpeek/metrics/cohesion/NHD.java deleted file mode 100644 index 2d2a0788..00000000 --- a/src/main/java/org/jpeek/metrics/cohesion/NHD.java +++ /dev/null @@ -1,191 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import java.io.IOException; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import javassist.CtClass; -import javassist.CtConstructor; -import javassist.CtMethod; -import javassist.Modifier; -import javassist.NotFoundException; -import org.cactoos.collection.Joined; -import org.cactoos.iterator.Mapped; -import org.jpeek.Base; -import org.jpeek.Metric; -import org.jpeek.metrics.JavassistClasses; -import org.jpeek.metrics.Summary; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.signature.SignatureReader; -import org.objectweb.asm.signature.SignatureVisitor; -import org.xembly.Directive; - -/** - * Normalized Hamming Distance (NHD). - * - *

The metric uses the same parameter occurrence - * matrix used by CAMC metric (the type of the class is not - * considered). The metric calculates the average of the - * parameter agreement between each pair of methods. The - * parameter agreement between a pair of methods is defined as - * the number of places in which the parameter occurrence - * vectors of the two methods are equal.

- * - *

The metric value ranges between 0 and 1.0. A value of - * 1.0 represents minimum cohesion and 0 represents - * a completely cohesive class.

- * - *

There is no thread-safety guarantee. - * - * @author Mehmet Yildirim (memoyil@gmail.com) - * @version $Id$ - * @see A class cohesion metric for object-oriented designs - * @since 0.1 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) - */ -public final class NHD implements Metric { - - /** - * The base. - */ - private final Base base; - - /** - * Ctor. - * @param bse The base - */ - public NHD(final Base bse) { - this.base = bse; - } - - @Override - public Iterable xembly() throws IOException { - return new JavassistClasses( - this.base, NHD::cohesion - ).xembly(); - } - - /** - * Calculate NHD metric for a single Java class. - * @param ctc The .class file - * @return Metrics - * @throws NotFoundException If fails - */ - private static Iterable cohesion(final CtClass ctc) - throws NotFoundException { - final Collection> methods = NHD.methods(ctc); - final Collection types = new HashSet<>( - new Joined( - () -> new Mapped<>( - strings -> strings, - methods.iterator() - ) - ) - ); - int sum = 0; - for (final String type : types) { - int mine = 0; - for (final Collection mtd : methods) { - if (mtd.contains(type)) { - ++mine; - } - } - sum += mine * (methods.size() - mine); - } - final double cohesion; - if (types.isEmpty() || methods.isEmpty()) { - cohesion = 1.0d; - } else { - cohesion = 1.0d - 2.0d * (double) sum / (double) (types.size() - * methods.size() * (methods.size() - 1)); - } - return new Summary(cohesion) - .with("sum", sum) - .with("types", types.size()) - .with("methods", methods.size()); - } - - /** - * Get all method signatures. - * @param ctc The .class file - * @return Method signatures - * @throws NotFoundException If fails - */ - @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") - private static Collection> methods(final CtClass ctc) - throws NotFoundException { - final Collection> methods = new LinkedList<>(); - for (final CtMethod mtd : ctc.getDeclaredMethods()) { - if (Modifier.isPrivate(mtd.getModifiers())) { - continue; - } - final Collection args = new LinkedList<>(); - for (final String arg : NHD.types(mtd.getSignature())) { - args.add(arg); - } - methods.add(args); - } - for (final CtConstructor ctor : ctc.getConstructors()) { - if (Modifier.isPrivate(ctor.getModifiers())) { - continue; - } - final Collection args = new LinkedList<>(); - for (final String arg : NHD.types(ctor.getSignature())) { - args.add(arg); - } - methods.add(args); - } - return methods; - } - - /** - * Get parameter types from a method/ctor signature. - * @param sig Signature - * @return Types of params - */ - private static Iterable types(final String sig) { - final Collection types = new LinkedList<>(); - new SignatureReader(sig).accept( - new SignatureVisitor(Opcodes.ASM6) { - @Override - public void visitClassType(final String name) { - super.visitClassType(name); - types.add(name); - } - @Override - public void visitBaseType(final char name) { - super.visitBaseType(name); - if ('V' != name) { - types.add(String.format(".%s", name)); - } - } - } - ); - return types; - } - -} diff --git a/src/main/java/org/jpeek/metrics/cohesion/OCC.java b/src/main/java/org/jpeek/metrics/cohesion/OCC.java deleted file mode 100644 index b8ddc141..00000000 --- a/src/main/java/org/jpeek/metrics/cohesion/OCC.java +++ /dev/null @@ -1,310 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import javassist.CannotCompileException; -import javassist.CtClass; -import javassist.CtField; -import javassist.CtMethod; -import org.jpeek.Base; -import org.jpeek.Metric; -import org.jpeek.metrics.JavassistClasses; -import org.jpeek.metrics.Summary; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.xembly.Directive; - -/** - * Optimistic Class Cohesion (OCC). - * - * Maximum value of percentage of methods to be reachable by some method, - * on the weak-connection graph. - * - *

The metric value ranges between 0 and 1.0. A value of - * 1.0 represents minimum cohesion and 0 represents - * a completely cohesive class.

- * - *

There is no thread-safety guarantee. - * - * @author Vseslav Sekorin (vssekorin@gmail.com) - * @version $Id$ - * @see A Proposal of Class Cohesion Metrics Using Sizes of Cohesive Parts - * @since 0.4 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle ParameterNumberCheck (500 lines) - */ -@SuppressWarnings("PMD.TooManyMethods") -public final class OCC implements Metric { - - /** - * The base. - */ - private final Base base; - - /** - * Ctor. - * @param bse The base - */ - public OCC(final Base bse) { - this.base = bse; - } - - @Override - public Iterable xembly() throws IOException { - return new JavassistClasses( - this.base, OCC::cohesion - ).xembly(); - } - - /** - * Calculate OCC metric for a single Java class. - * - * @param ctc The .class file - * @return Metrics - */ - private static Iterable cohesion(final CtClass ctc) { - final List ctmethods = Arrays.stream(ctc.getDeclaredMethods()) - .map(CtMethod::getName) - .collect(Collectors.toList()); - final int number = ctmethods.size(); - final double result; - if (number == 1) { - result = 0; - } else { - result = maxRw(ctc, ctmethods) / (double) (number - 1); - } - return new Summary(result) - .with("methods", ctmethods.size()) - .with("number", number); - } - - /** - * Maximum number of methods which are reachable. - * - * @param ctc The .class file - * @param ctmethods Methods - * @return The number - */ - @SuppressWarnings({"PMD.UseVarargs", "PMD.UseObjectForClearerAPI"}) - private static double maxRw( - final CtClass ctc, final List ctmethods) { - final ClassReader reader; - try { - reader = new ClassReader(ctc.toBytecode()); - } catch (final IOException | CannotCompileException ex) { - throw new IllegalStateException(ex); - } - final Map> vars = new HashMap<>(); - final Map> methods = new HashMap<>(); - final List ctfields = Arrays.stream(ctc.getDeclaredFields()) - .map(CtField::getName) - .collect(Collectors.toList()); - reader.accept( - //@checkstyle AnonInnerLengthCheck (50 lines) - new ClassVisitor(Opcodes.ASM6) { - @Override - public MethodVisitor visitMethod( - final int access, final String mtd, final String desc, - final String signature, final String[] exceptions) { - super.visitMethod(access, mtd, desc, signature, exceptions); - final Set attrs = new HashSet<>(); - final Set names = new HashSet<>(); - vars.put(mtd, attrs); - methods.put(mtd, names); - return new MethodVisitor(Opcodes.ASM6) { - @Override - public void visitFieldInsn( - final int opcode, final String owner, - final String attr, final String details) { - super.visitFieldInsn(opcode, owner, attr, details); - if (ctfields.contains(attr)) { - attrs.add(attr); - } - } - @Override - public void visitMethodInsn( - final int opcode, final String owner, - final String name, final String desc, - final boolean itf) { - super.visitMethodInsn( - opcode, owner, name, desc, itf - ); - if (!name.equals(mtd) && ctmethods.contains(name)) { - names.add(name); - } - } - }; - } - }, - 0 - ); - methods.forEach( - (key, value) -> value.forEach( - item -> vars.get(key).addAll(vars.get(item)) - ) - ); - final boolean[][] adjacency = adjacencyMatrix(vars, ctmethods); - final int number = ctmethods.size(); - final boolean[][] reachabilty = reachabilityMatrix(adjacency, number); - return maxWays(reachabilty, number); - } - - /** - * Adjacency matrix. - * - * @param vars Variables - * @param methods Methods - * @return Result - */ - private static boolean[][] adjacencyMatrix( - final Map> vars, final List methods) { - final int number = methods.size(); - final boolean[][] result = new boolean[number][number]; - for (int row = 0; row < number; ++row) { - for (int col = 0; col < number; ++col) { - result[row][col] = hasWeakConnection( - vars.get(methods.get(row)), - vars.get(methods.get(col)) - ); - } - } - return result; - } - - /** - * Reachability matrix. - * - * @param adjacency Adjacency matrix - * @param number Number of methods - * @return Result - */ - private static boolean[][] reachabilityMatrix( - final boolean[][] adjacency, final int number) { - boolean[][] result = new boolean[number][number]; - boolean[][] current = new boolean[number][number]; - for (int ind = 0; ind < number; ++ind) { - System.arraycopy(adjacency[ind], 0, result[ind], 0, number); - System.arraycopy(adjacency[ind], 0, current[ind], 0, number); - } - for (int ind = 2; ind <= number; ++ind) { - current = multiply(current, adjacency, number); - result = disjunction(current, result, number); - } - return result; - } - - /** - * Check weak-connection of two method. - * - * @param first First method's vars - * @param second Second method's vars - * @return Result - */ - private static boolean hasWeakConnection( - final Set first, final Set second) { - boolean result = false; - for (final Object item : first) { - if (second.contains(item)) { - result = true; - break; - } - } - return result; - } - - /** - * Multiply of two boolean matrix. - * - * @param first The first matrix - * @param second The second matrix - * @param size Matrix size - * @return Result matrix - */ - private static boolean[][] multiply( - final boolean[][] first, final boolean[][] second, final int size) { - final boolean[][] result = new boolean[size][size]; - //@checkstyle NestedForDepthCheck (10 lines) - for (int row = 0; row < size; ++row) { - for (int col = 0; col < size; ++col) { - for (int inner = 0; inner < size; ++inner) { - result[row][col] = result[row][col] - || first[row][inner] && second[inner][col]; - } - } - } - return result; - } - - /** - * Disjunction of two boolean matrix. - * - * @param first The first matrix - * @param second The second matrix - * @param size Matrix size - * @return Result matrix - */ - private static boolean[][] disjunction( - final boolean[][] first, final boolean[][] second, final int size) { - final boolean[][] result = new boolean[size][size]; - for (int row = 0; row < size; ++row) { - for (int col = 0; col < size; ++col) { - result[row][col] = first[row][col] || second[row][col]; - } - } - return result; - } - - /** - * The maximum number of paths in the reachability matrix. - * - * @param array Matrix - * @param size Size of matrix - * @return The number - */ - private static int maxWays(final boolean[][] array, final int size) { - int result = 0; - for (int row = 0; row < size; ++row) { - int current = 0; - for (int col = 0; col < size; ++col) { - if (array[row][col] && row != col) { - ++current; - } - } - if (result < current) { - result = current; - } - } - return result; - } -} diff --git a/src/main/java/org/jpeek/web/Reports.java b/src/main/java/org/jpeek/web/Reports.java index 307c85db..303255fd 100644 --- a/src/main/java/org/jpeek/web/Reports.java +++ b/src/main/java/org/jpeek/web/Reports.java @@ -33,6 +33,7 @@ import org.cactoos.Func; import org.cactoos.io.LengthOf; import org.cactoos.io.TeeInput; +import org.cactoos.scalar.IoCheckedScalar; import org.cactoos.text.TextOf; import org.jpeek.App; import org.takes.Response; @@ -103,15 +104,17 @@ public Func apply(final String group, ).asString() ).xpath("/metadata/versioning/latest/text()").get(0); final String name = String.format("%s-%s.jar", artifact, version); - new LengthOf( - new TeeInput( - new URL( - String.format( - "http://repo1.maven.org/maven2/%s/%s/%s/%s", - grp, artifact, version, name - ) - ), - input.resolve(name) + new IoCheckedScalar<>( + new LengthOf( + new TeeInput( + new URL( + String.format( + "http://repo1.maven.org/maven2/%s/%s/%s/%s", + grp, artifact, version, name + ) + ), + input.resolve(name) + ) ) ).value(); try { diff --git a/src/main/resources/org/jpeek/metrics/LCOM2.xsl b/src/main/resources/org/jpeek/metrics/LCOM2.xsl new file mode 100644 index 00000000..a8e3103c --- /dev/null +++ b/src/main/resources/org/jpeek/metrics/LCOM2.xsl @@ -0,0 +1,44 @@ + + + + + + + 0 + + + + 0 + 0 + 0 + + + + + + + + + diff --git a/src/test/java/org/jpeek/ReportTest.java b/src/test/java/org/jpeek/ReportTest.java index a93b5653..d59fcb0a 100644 --- a/src/test/java/org/jpeek/ReportTest.java +++ b/src/test/java/org/jpeek/ReportTest.java @@ -24,6 +24,7 @@ package org.jpeek; import com.jcabi.matchers.XhtmlMatchers; +import com.jcabi.xml.XMLDocument; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -31,11 +32,9 @@ import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.jpeek.metrics.FakeBase; -import org.jpeek.metrics.cohesion.LCOM; -import org.jpeek.metrics.cohesion.MMAC; -import org.jpeek.metrics.cohesion.NHD; import org.junit.Test; import org.xembly.Directives; +import org.xembly.Xembler; /** * Test case for {@link Report}. @@ -51,7 +50,7 @@ public final class ReportTest { @Test public void createsXmlReport() throws IOException { final Path output = Files.createTempDirectory(""); - new Report(new LCOM(new FakeBase("Foo"))).save(output); + new Report(new Skeleton(new FakeBase("Foo")).xml(), "LCOM").save(output); MatcherAssert.assertThat( Files.exists(output.resolve("LCOM.xml")), Matchers.equalTo(true) @@ -66,12 +65,13 @@ public void createsXmlReport() throws IOException { public void createsXmlReportWithXpaths() throws IOException { final Path output = Files.createTempDirectory(""); new Report( - new MMAC( + new Skeleton( new FakeBase( "NoMethods", "Bar", "OverloadMethods", "OnlyOneMethodWithParams", "WithoutAttributes" ) - ) + ).xml(), + "MMAC" ).save(output); MatcherAssert.assertThat( XhtmlMatchers.xhtml( @@ -88,7 +88,7 @@ public void createsXmlReportWithXpaths() throws IOException { @Test public void createsXmlReportWithEmptyProject() throws IOException { final Path output = Files.createTempDirectory(""); - new Report(new NHD(new FakeBase())).save(output); + new Report(new Skeleton(new FakeBase()).xml(), "NHD").save(output); MatcherAssert.assertThat( XhtmlMatchers.xhtml( new TextOf(output.resolve("NHD.xml")).asString() @@ -103,17 +103,20 @@ public void createsXmlReportWithEmptyProject() throws IOException { public void createsFullXmlReport() throws IOException { final Path output = Files.createTempDirectory(""); new Report( - new Metric.Fixed( - new Directives() - .add("metric") - .add("app").attr("id", ".") - .add("package").attr("id", ".") - .add("class").attr("id", "A").attr("value", "0.1").up() - .add("class").attr("id", "B").attr("value", "0.5").up() - .add("class").attr("id", "C").attr("value", "0.6").up() - .add("class").attr("id", "D").attr("value", "0.7").up() - .add("class").attr("id", "E").attr("value", "NaN").up() - ) + new XMLDocument( + new Xembler( + new Directives() + .add("metric") + .add("app").attr("id", ".") + .add("package").attr("id", ".") + .add("class").attr("id", "A").attr("value", "0.1").up() + .add("class").attr("id", "B").attr("value", "0.5").up() + .add("class").attr("id", "C").attr("value", "0.6").up() + .add("class").attr("id", "D").attr("value", "0.7").up() + .add("class").attr("id", "E").attr("value", "NaN").up() + ).xmlQuietly() + ), + "" ).save(output); MatcherAssert.assertThat( XhtmlMatchers.xhtml( diff --git a/src/main/java/org/jpeek/metrics/cohesion/package-info.java b/src/test/java/org/jpeek/SkeletonTest.java similarity index 66% rename from src/main/java/org/jpeek/metrics/cohesion/package-info.java rename to src/test/java/org/jpeek/SkeletonTest.java index 47d90250..c223351a 100644 --- a/src/main/java/org/jpeek/metrics/cohesion/package-info.java +++ b/src/test/java/org/jpeek/SkeletonTest.java @@ -21,12 +21,31 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +package org.jpeek; + +import com.jcabi.matchers.XhtmlMatchers; +import java.io.IOException; +import org.hamcrest.MatcherAssert; +import org.jpeek.metrics.FakeBase; +import org.junit.Test; /** - * Cohesion metrics. - * + * Test case for {@link Skeleton}. * @author Yegor Bugayenko (yegor256@gmail.com) * @version $Id$ - * @since 0.1 + * @since 0.23 + * @checkstyle JavadocMethodCheck (500 lines) */ -package org.jpeek.metrics.cohesion; +public final class SkeletonTest { + + @Test + public void createsXml() throws IOException { + MatcherAssert.assertThat( + XhtmlMatchers.xhtml( + new Skeleton(new FakeBase("OverloadMethods")).xml().toString() + ), + XhtmlMatchers.hasXPaths("/skeleton") + ); + } + +} diff --git a/src/test/java/org/jpeek/metrics/cohesion/CAMCTest.java b/src/test/java/org/jpeek/metrics/cohesion/CAMCTest.java deleted file mode 100644 index 96928af3..00000000 --- a/src/test/java/org/jpeek/metrics/cohesion/CAMCTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import com.jcabi.matchers.XhtmlMatchers; -import java.io.IOException; -import java.nio.file.Paths; -import org.hamcrest.MatcherAssert; -import org.jpeek.DefaultBase; -import org.jpeek.metrics.FakeBase; -import org.junit.Test; -import org.xembly.Xembler; - -/** - * Test case for {@link CAMC}. - * @author Yegor Bugayenko (yegor256@gmail.com) - * @version $Id$ - * @since 0.1 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle JavadocMethodCheck (500 lines) - */ -public final class CAMCTest { - - @Test - public void createsBigXmlReport() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new CAMC( - new DefaultBase(Paths.get(".")) - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='CAMCTest']", - "//class[@id='DefaultBase' and @value='0.3333']" - ) - ); - } - - @Test - public void createsXmlReportForFixtureClassA() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new CAMC( - new FakeBase("Foo") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package[@id='']/class[@id='Foo']", - "//class[@id='Foo' and @value='0.6667']" - ) - ); - } - - @Test - public void createsXmlReportForAboveNormalize() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new CAMC( - new FakeBase("Bar") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package[@id='']/class[@id='Bar']", - "//class[@id='Bar' and @value='1.0000']" - ) - ); - } - -} diff --git a/src/test/java/org/jpeek/metrics/cohesion/LCOM2Test.java b/src/test/java/org/jpeek/metrics/cohesion/LCOM2Test.java deleted file mode 100644 index 377f37f8..00000000 --- a/src/test/java/org/jpeek/metrics/cohesion/LCOM2Test.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import com.jcabi.matchers.XhtmlMatchers; -import java.io.IOException; -import java.nio.file.Paths; -import org.hamcrest.MatcherAssert; -import org.jpeek.DefaultBase; -import org.jpeek.metrics.FakeBase; -import org.junit.Test; -import org.xembly.Xembler; - -/** - * Test case for {@link LCOM2}. - * @author Mehmet Yildirim (memoyil@gmail.com) - * @version $Id$ - * @since 0.2 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle JavadocMethodCheck (500 lines) - */ -public final class LCOM2Test { - - @Test - public void createsBigXmlReport() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM2( - new DefaultBase(Paths.get(".")) - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='LCOM2Test']", - "//class[@id='DefaultBase' and @value='0.0000']" - ) - ); - } - - @Test - public void createsXmlReportForFixtureClassA() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM2( - new FakeBase("Foo") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='Foo']", - "//class[@id='Foo' and @value='0.3333']" - ) - ); - } - - @Test - public void createsXmlReportForOneMethodWithoutAttr() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM2( - new FakeBase("Bar") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='Bar']", - "//class[@id='Bar' and @value='0.5000']" - ) - ); - } - - @Test - public void createsXmlReportForWithoutAttrClass() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM2( - new FakeBase("WithoutAttributes") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='WithoutAttributes']", - "//class[@id='WithoutAttributes' and @value='0.0000']" - ) - ); - } -} diff --git a/src/test/java/org/jpeek/metrics/cohesion/LCOM3Test.java b/src/test/java/org/jpeek/metrics/cohesion/LCOM3Test.java deleted file mode 100644 index fc285fc7..00000000 --- a/src/test/java/org/jpeek/metrics/cohesion/LCOM3Test.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import com.jcabi.matchers.XhtmlMatchers; -import java.io.IOException; -import java.nio.file.Paths; -import org.hamcrest.MatcherAssert; -import org.jpeek.DefaultBase; -import org.jpeek.metrics.FakeBase; -import org.junit.Test; -import org.xembly.Xembler; - -/** - * Test case for {@link LCOM3}. - * @author Mehmet Yildirim (memoyil@gmail.com) - * @version $Id$ - * @since 0.2 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle JavadocMethodCheck (500 lines) - */ -public final class LCOM3Test { - - @Test - public void createsBigXmlReport() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM3( - new DefaultBase(Paths.get(".")) - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='LCOM3Test']", - "//class[@id='DefaultBase' and @value='0.0000']" - ) - ); - } - - @Test - public void createsXmlReportForFixtureClassA() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM3( - new FakeBase("Foo") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='Foo']", - "//class[@id='Foo' and @value='0.5000']" - ) - ); - } - - @Test - public void createsXmlReportForOneMethodWithoutAttr() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM2( - new FakeBase("Bar") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='Bar']", - "//class[@id='Bar' and @value='0.5000']" - ) - ); - } - - @Test - public void createsXmlReportForWithoutAttrClass() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM3( - new FakeBase("WithoutAttributes") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='WithoutAttributes']", - "//class[@id='WithoutAttributes' and @value='0.0000']" - ) - ); - } -} diff --git a/src/test/java/org/jpeek/metrics/cohesion/LCOMTest.java b/src/test/java/org/jpeek/metrics/cohesion/LCOMTest.java deleted file mode 100644 index 2e9bc70b..00000000 --- a/src/test/java/org/jpeek/metrics/cohesion/LCOMTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import com.jcabi.matchers.XhtmlMatchers; -import java.io.IOException; -import java.nio.file.Paths; -import org.hamcrest.MatcherAssert; -import org.jpeek.DefaultBase; -import org.jpeek.metrics.FakeBase; -import org.junit.Test; -import org.xembly.Xembler; - -/** - * Test case for {@link LCOM}. - * @author Yegor Bugayenko (yegor256@gmail.com) - * @version $Id$ - * @since 0.1 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle JavadocMethodCheck (500 lines) - */ -public final class LCOMTest { - - @Test - public void createsBigXmlReport() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM( - new DefaultBase(Paths.get(".")) - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='LCOMTest']", - "//class[@id='DefaultBase' and @value='0.0000']" - ) - ); - } - - @Test - public void createsXmlReportForFixtureClassA() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new LCOM( - new FakeBase("Foo") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='Foo']", - "//class[@id='Foo' and @value='1.0000']" - ) - ); - } -} diff --git a/src/test/java/org/jpeek/metrics/cohesion/MMACTest.java b/src/test/java/org/jpeek/metrics/cohesion/MMACTest.java deleted file mode 100644 index 5bb8793f..00000000 --- a/src/test/java/org/jpeek/metrics/cohesion/MMACTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import com.jcabi.matchers.XhtmlMatchers; -import java.io.IOException; -import java.nio.file.Paths; -import org.hamcrest.MatcherAssert; -import org.jpeek.DefaultBase; -import org.jpeek.metrics.FakeBase; -import org.junit.Test; -import org.xembly.Xembler; - -/** - * Test case for {@link MMAC}. - * - * @author Sergey Karazhenets (sergeykarazhenets@gmail.com) - * @version $Id$ - * @since 0.2 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle JavadocMethodCheck (500 lines) - */ -public final class MMACTest { - - @Test - public void createsBigXmlReport() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new MMAC( - new DefaultBase(Paths.get(".")) - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='MMACTest']", - "//class[@id='Header' and @value='1.0000']" - ) - ); - } - - @Test - public void createsXmlReportAndExpectsRedColor() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new MMAC( - new FakeBase( - "NoMethods", - "MethodsWithDiffParamTypes" - ) - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='NoMethods']", - "//class[@id='NoMethods' and @value='0.0000']", - "/metric/app/package/class[@id='MethodsWithDiffParamTypes']", - "//class[@id='MethodsWithDiffParamTypes' and @value='0.0370']" - ) - ); - } - - @Test - public void createsXmlReportAndExpectsYellowColor() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new MMAC( - new FakeBase("OverloadMethods") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='OverloadMethods']", - "//class[@id='OverloadMethods' and @value='0.7222']" - ) - ); - } - - @Test - public void createsXmlReportAndExpectsGreenColor() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new MMAC( - new FakeBase( - "OneVoidMethodWithoutParams", - "OnlyOneMethodWithParams", - "OneMethodCreatesLambda", - "Foo" - ) - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='OneVoidMethodWithoutParams']", - "//class[@id='OneVoidMethodWithoutParams' and @value='1.0000']", - "/metric/app/package/class[@id='OnlyOneMethodWithParams']", - "//class[@id='OnlyOneMethodWithParams' and @value='1.0000']", - "/metric/app/package/class[@id='OneMethodCreatesLambda']", - "//class[@id='OneMethodCreatesLambda' and @value='1.0000']", - "/metric/app/package/class[@id='Foo']", - "//class[@id='Foo' and @value='1.0000']" - ) - ); - } -} diff --git a/src/test/java/org/jpeek/metrics/cohesion/NHDTest.java b/src/test/java/org/jpeek/metrics/cohesion/NHDTest.java deleted file mode 100644 index 55a3729c..00000000 --- a/src/test/java/org/jpeek/metrics/cohesion/NHDTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import com.jcabi.matchers.XhtmlMatchers; -import java.io.IOException; -import java.nio.file.Paths; -import org.hamcrest.MatcherAssert; -import org.jpeek.DefaultBase; -import org.jpeek.metrics.FakeBase; -import org.junit.Test; -import org.xembly.Xembler; - -/** - * Test case for {@link NHD}. - * - * @author Mehmet Yildirim (memoyil@gmail.com) - * @version $Id$ - * @since 0.1 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle JavadocMethodCheck (500 lines) - */ -public final class NHDTest { - - @Test - public void createsBigXmlReport() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new NHD( - new DefaultBase(Paths.get(".")) - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='CAMCTest']", - "//class[@id='DefaultBase' and @value='0.3333']" - ) - ); - } - - @Test - public void createsXmlReportForFixtureClassA() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new NHD( - new FakeBase("Foo") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package[@id='']/class[@id='Foo']", - "//class[@id='Foo' and @value='0.3333']" - ) - ); - } - -} diff --git a/src/test/java/org/jpeek/metrics/cohesion/OCCTest.java b/src/test/java/org/jpeek/metrics/cohesion/OCCTest.java deleted file mode 100644 index 2821feb8..00000000 --- a/src/test/java/org/jpeek/metrics/cohesion/OCCTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.jpeek.metrics.cohesion; - -import com.jcabi.matchers.XhtmlMatchers; -import java.io.IOException; -import java.nio.file.Paths; -import org.hamcrest.MatcherAssert; -import org.jpeek.DefaultBase; -import org.jpeek.metrics.FakeBase; -import org.junit.Test; -import org.xembly.Xembler; - -/** - * Test case for {@link OCC}. - * - * @author Vseslav Sekorin (vssekorin@gmail.com) - * @version $Id$ - * @since 0.4 - * @checkstyle AbbreviationAsWordInNameCheck (5 lines) - * @checkstyle JavadocMethodCheck (500 lines) - */ -public final class OCCTest { - - @Test - public void createsBigXmlReport() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new OCC( - new DefaultBase(Paths.get(".")) - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='OCCTest']", - "//class[@id='OCCTest' and @value='0.0000']" - ) - ); - } - - @Test - public void createsXmlReportForYellowClass() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new OCC( - new FakeBase("TwoCommonAttributes") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='TwoCommonAttributes']", - "//class[@id='TwoCommonAttributes' and @value='0.5000']" - ) - ); - } - - @Test - public void createsXmlReportForRedClass() throws IOException { - MatcherAssert.assertThat( - XhtmlMatchers.xhtml( - new Xembler( - new OCC( - new FakeBase("Foo") - ).xembly() - ).xmlQuietly() - ), - XhtmlMatchers.hasXPaths( - "/metric/app/package/class[@id='Foo']", - "//class[@id='Foo' and @value='1.0000']" - ) - ); - } -} diff --git a/src/test/java/org/jpeek/metrics/cohesion/package-info.java b/src/test/java/org/jpeek/metrics/cohesion/package-info.java deleted file mode 100644 index df476142..00000000 --- a/src/test/java/org/jpeek/metrics/cohesion/package-info.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2017 Yegor Bugayenko - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * Cohesion metrics, tests. - * - * @author Yegor Bugayenko (yegor256@gmail.com) - * @version $Id$ - * @since 0.1 - */ -package org.jpeek.metrics.cohesion;