Hypothèses: Java11, JUnit5, sbt
J'en ai assez de la méthode des monstres, alors j'ai écrit quelque chose comme ça ... Préparons-le au début du projet.
À la suite de la préparation de quelque chose comme ça J'ai divisé les méthodes et réduit le nombre de lignes par méthode pour le moment, Au lieu de cela, il pourrait être transformé en une variable globale en élargissant la portée de la variable afin qu'elle puisse être référencée par diverses méthodes. Il y a un problème qui ... Peut-être que c'est encore mieux de préparer celui-ci cette fois? Je pense.
Coller ↓ dans la bibliothèque Dépendances de build.sbt
build.sbt
"org.junit.jupiter" % "junit-jupiter-api" % "5.5.0",
"org.junit.jupiter"%"junit-jupiter-engine" % "5.5.0",
"org.javassist" % "javassist" % "3.25.0-GA",
package com.github.momosetkn;
import javassist.ClassPool;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
class MonsterMethodAlert {
@Test
void test() throws Exception {
var cp = ClassPool.getDefault();
var fail = false;
for (var className : getClassNameList()) {
var cc = cp.get(className);
for (var method : cc.getMethods()) {
// java.lang.Object.Les méthodes sous le package Java telles que equals sont exclues
if (method.getDeclaringClass().getName().startsWith("java"))
continue;
var methodInfo = method.getMethodInfo();
var start = methodInfo.getLineNumber(Integer.MIN_VALUE);
var end = methodInfo.getLineNumber(Integer.MAX_VALUE);
var line = end - start + 1;
if (line >= 25) {
System.err.println(String.format("%s%C'est une méthode monstre de la ligne s", className + "#" + methodInfo.getName(), line));
fail = true;
}
}
}
if (fail)
throw new Exception("Méthode Monster détectée");
}
private List<String> getClassNameList() throws IOException, URISyntaxException {
var list = new ArrayList<String>();
var classLoader = Thread.currentThread().getContextClassLoader();
var targetUrls = classLoader.getResources("");
var CLASS_EXT = ".class";
while (targetUrls.hasMoreElements()) {
var url = targetUrls.nextElement();
if (!url.getProtocol().equals("file")) {
continue;
}
var targetPath = Paths.get(url.toURI());
Files.walkFileTree(targetPath, new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path foundPath, BasicFileAttributes attrs) throws IOException {
if (foundPath.toString().endsWith(CLASS_EXT)){
var relativizeStr = targetPath.relativize(foundPath).toString();
list.add(
relativizeStr
.substring(0, relativizeStr.length() - CLASS_EXT.length())
.replace(File.separatorChar, '.')
);
}
return super.visitFile(foundPath, attrs);
}
});
}
return list;
}
}
Example#main est une méthode de monstre de 36 lignes
java.lang.Exception:Méthode Monster détectée
at com.github.momosetkn.MonsterMethodAlert.test(MonsterMethodAlert.java:37)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:436)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:112)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
En regardant l'implémentation de javassist.bytecode.MethodInfo # getLineNumber
,
Il semble que la valeur numérique passée à l'argument soit transmise à la méthode suivante.
https://github.com/jboss-javassist/javassist/blob/rel_3_25_0_ga/src/main/javassist/bytecode/LineNumberAttribute.java#L77
Il semble qu'il ne soit jugé qu'en le tournant en boucle et en le dépassant, donc
Nous transmettons ʻInteger.MIN_VALUE et ʻInteger.MAX_VALUE
.
début et fin sont
100: public void method(){
101: //début est le nombre de lignes ici
102: //
103: //la fin est le nombre de lignes ici
104: }
Puisque 103-102 = 2, il est traité comme une méthode avec 1 ajouté et 3 lignes.
Les anciennes versions de Javassist ne suivent pas la nouvelle version de Java, alors rendez-la aussi nouvelle que possible.
Je veux rechercher récursivement la liste des classes sous le package \ -Qiita Mémo Javassist \ (Mémo Javassiste de Hishidama )
Recommended Posts