Skip to content
Snippets Groups Projects
Commit 4dcc5870 authored by jez04's avatar jez04
Browse files

feta: change project name and update test

parent 233a0643
No related merge requests found
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>vsb-cs-java1</groupId> <groupId>vsb-cs-java1</groupId>
<artifactId>lab07v3</artifactId> <artifactId>lab10v3</artifactId>
<version>0.0.1-SNAPHOST</version> <version>0.0.1-SNAPHOST</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<properties> <properties>
...@@ -22,6 +22,19 @@ ...@@ -22,6 +22,19 @@
<artifactId>javafx-fxml</artifactId> <artifactId>javafx-fxml</artifactId>
<version>23</version> <version>23</version>
</dependency> </dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>23</version>
</dependency>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>11.2.1</version>
</dependency>
<!-- <!--
https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --> https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency> <dependency>
......
...@@ -5,7 +5,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue; ...@@ -5,7 +5,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
...@@ -40,105 +44,100 @@ class ClassStructureTest { ...@@ -40,105 +44,100 @@ class ClassStructureTest {
StructureHelper helper = new StructureHelper(); StructureHelper helper = new StructureHelper();
@Test @Test
void gameControllerExistenceTest() { void detectNioPackageTest() {
helper.classExist("GameController"); assertTrue(helper.getNameOfAllClasses().stream().anyMatch(name -> name.contains("java.nio")),
"Usage of NIO package not detected.");
} }
@Test @Test
void gameControllerFxmlTest() { void detectUsageOfIoPackageTest() {
helper.classExist("GameController"); assertTrue(helper.getNameOfAllClasses().stream().anyMatch(name -> name.contains("java.io")),
Class<?> c = helper.getClass("GameController"); "Usage of java IO package not detected.");
helper.hasPropertyWithAnnotation(c, ".*", FXML.class);
} }
@Test @Test
void gameControllerActionMethodTest() { void detectUsageOfPathClassTest() {
helper.classExist("GameController"); assertTrue(helper.getNameOfAllClasses().stream().anyMatch(name -> name.contains("java.nio.file.Path")),
Class<?> c = helper.getClass("GameController"); "Usage of Path not detected.");
helper.hasMethodRegexp(c, ".*", void.class, ActionEvent.class);
} }
@Test @Test
void gameControllerLambdasTest() { void detectUsageOfFileClassTest() {
helper.classExist("GameController"); assertTrue(helper.getNameOfAllClasses().stream().anyMatch(name -> name.contains("java.nio.file.File")),
Class<?> c = helper.getClass("GameController"); "Usage of NIO File not detected.");
long lamdaCount = helper.countMethodRegexp(c, "lambda\\$.*");
long innerClasscount = helper.countClassesRegexp(".*GameController\\$.*");
assertTrue(lamdaCount + innerClasscount >= 3,
"At least 3 inner classes or lamdas required for GameController but only "
+ (lamdaCount + innerClasscount) + " found.");
} }
@Test @Test
void deadListenerExistenceTest() { void detectUsageOfInputStreamClassTest() {
helper.classExist("DeadListener"); assertTrue(helper.getNameOfAllClasses().stream().map(className -> {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return Object.class;
}).anyMatch(clazz -> InputStream.class.isAssignableFrom(clazz)), "Usage of InputStream not detected.");
} }
@Test @Test
void deadListenerEventMethodTest() { void detectUsageOfReaderClassTest() {
helper.classExist("DeadListener"); assertTrue(helper.getNameOfAllClasses().stream().map(className -> {
Class<?> c = helper.getClass("DeadListener"); try {
helper.hasMethod(c, "lochnessDead"); return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return Object.class;
}).anyMatch(clazz -> Reader.class.isAssignableFrom(clazz)), "Usage of Reader not detected.");
} }
@Test @Test
void sceneCollectionTest() { void detectUsageOfOutputStreamClassTest() {
helper.classExist("lab.Scene"); assertTrue(helper.getNameOfAllClasses().stream().map(className -> {
Class<?> c = helper.getClass("lab.Scene"); try {
long collectionCount = Arrays.asList(c.getDeclaredFields()).stream() return Class.forName(className);
.filter(f -> Collection.class.isAssignableFrom(f.getType())).count(); } catch (Throwable e) {
assertTrue(collectionCount >= 3, "lab.Scene require atleast 3 filed of type/subtype Collection, but only " System.out.println(e.getMessage());
+ collectionCount + " found."); }
return Object.class;
}).anyMatch(clazz -> OutputStream.class.isAssignableFrom(clazz)), "Usage of OutputStream not detected.");
} }
@Test @Test
void sceneMethodAddTest() { void detectUsageOfWriterTest() {
helper.classExist("lab.Scene"); assertTrue(helper.getNameOfAllClasses().stream().map(className -> {
Class<?> c = helper.getClass("lab.Scene"); try {
helper.hasMethod(c, "add", void.class, helper.getClass("DrawableSimulable")); return Class.forName(className);
; } catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
return Object.class;
}).anyMatch(clazz ->
Writer.class.isAssignableFrom(clazz)
), "Usage of Writer not detected.");
} }
@Test
void sceneMethodRemoveTest() {
helper.classExist("lab.Scene");
Class<?> c = helper.getClass("lab.Scene");
helper.hasMethod(c, "remove", void.class, helper.getClass("DrawableSimulable"));
;
}
@Test
void lochnessMethodAddTest() {
helper.classExist("LochNess");
Class<?> c = helper.getClass("LochNess");
helper.hasMethod(c, "addDeadListener");
}
@Test @Test
void lochnessMethodRemoveTest() { void detectUsageOfExceptionClassTest() {
helper.classExist("LochNess"); assertTrue(helper.getNameOfAllClasses().stream().filter(name -> !name.startsWith("javafx.")).map(className -> {
Class<?> c = helper.getClass("LochNess"); try {
helper.hasMethod(c, "removeDeadListener"); return Class.forName(className);
} catch (Throwable e) {
System.out.println(e.getMessage());
}
return Object.class;
}).anyMatch(clazz ->
Exception.class.isAssignableFrom(clazz)
), "Usage of Exception not detected.");
} }
@Test
void lochnessMethodFireTest() {
helper.classExist("LochNess");
Class<?> c = helper.getClass("LochNess");
assertTrue(helper.countMethodRegexp(c, "fire.*") > 0, "Method fire.* in LochNess not found.");
}
@Test
void zIndexMethodTest() {
helper.classExist("DrawableSimulable");
Class<?> c = helper.getClass("DrawableSimulable");
helper.hasMethodRegexp(c, "get[zZ][iI]ndex", int.class, new Class[0]);
}
@Test @Test
void zIndexFieldTest() { void detectUsageOfIOExceptionClassTest() {
helper.classExist("WorldEntity"); assertTrue(helper.getNameOfAllClasses().stream().map(className -> {
Class<?> c = helper.getClass("WorldEntity"); try {
helper.hasProperty(c, "[zZ][iI]ndex", int.class, false); return Class.forName(className);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
return Object.class;
}).anyMatch(clazz -> IOException.class.isAssignableFrom(clazz)), "Usage of IOException not detected.");
} }
} }
...@@ -9,6 +9,7 @@ import java.io.PrintStream; ...@@ -9,6 +9,7 @@ import java.io.PrintStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
...@@ -19,9 +20,10 @@ import java.nio.file.Paths; ...@@ -19,9 +20,10 @@ import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
...@@ -42,6 +44,22 @@ class StructureHelper { ...@@ -42,6 +44,22 @@ class StructureHelper {
assertTrue(allClasses.stream().anyMatch(c -> c.endsWith(name)), "Class/Interface " + name + " not found"); assertTrue(allClasses.stream().anyMatch(c -> c.endsWith(name)), "Class/Interface " + name + " not found");
} }
public Class<?> getClassDirectly(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos, true)) {
e.printStackTrace(ps);
} catch (Exception e2) {
Assertions.fail(e2.getMessage());
}
String stackTrace = baos.toString();
Assertions.fail("Class " + name + " not found.\n" + stackTrace);
return null;
}
}
public Class<?> getClass(String name) { public Class<?> getClass(String name) {
String className = allClasses.stream().filter(c -> c.endsWith(name)).findAny().orElse(null); String className = allClasses.stream().filter(c -> c.endsWith(name)).findAny().orElse(null);
if (className == null) { if (className == null) {
...@@ -111,6 +129,7 @@ class StructureHelper { ...@@ -111,6 +129,7 @@ class StructureHelper {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods()); List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
return methods.stream().filter(m -> m.getName().matches(methodNameRegexp)).count(); return methods.stream().filter(m -> m.getName().matches(methodNameRegexp)).count();
} }
public long countClassesRegexp(String classNameRegexp) { public long countClassesRegexp(String classNameRegexp) {
return getNameOfAllClasses().stream().filter(className -> className.matches(classNameRegexp)).count(); return getNameOfAllClasses().stream().filter(className -> className.matches(classNameRegexp)).count();
} }
...@@ -155,16 +174,21 @@ class StructureHelper { ...@@ -155,16 +174,21 @@ class StructureHelper {
"Class " + clazz.getName() + " not extends class " + parentName); "Class " + clazz.getName() + " not extends class " + parentName);
} }
public void hasExtends(Class<?> clazz, Class<?> parent) {
assertTrue(clazz.getSuperclass().equals(parent),
"Class " + clazz.getName() + " not extends class " + parent.getCanonicalName());
}
public void hasMethod(Class<?> interfaceDef, String methodName) { public void hasMethod(Class<?> interfaceDef, String methodName) {
List<Method> methods = Arrays.asList(interfaceDef.getMethods()); List<Method> methods = Arrays.asList(interfaceDef.getMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName); assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
} }
public Set<String> getNameOfAllClasses() { public Set<String> getNameOfAllClasses() {
List<String> initClassesName = new ArrayList<>(); Set<String> allClassesName = new TreeSet<>();
dynamicaliFoundSomeClass(initClassesName); dynamicaliFoundSomeClass(allClassesName);
initClassesName.addAll(List.of("lab.Routines", "lab.App", "lab.DrawingThread")); // allClassesName.addAll(List.of("cz.vsb.fei.lab.App", "lab.Routines", "lab.App", "lab.DrawingThread"));
for (String className : initClassesName) { for (String className : allClassesName) {
try { try {
Class.forName(className); Class.forName(className);
break; break;
...@@ -172,7 +196,6 @@ class StructureHelper { ...@@ -172,7 +196,6 @@ class StructureHelper {
System.out.println(String.format("Class '%s' cannot be loaded: %s", className, e.getMessage())); System.out.println(String.format("Class '%s' cannot be loaded: %s", className, e.getMessage()));
} }
} }
Set<String> allClasses = new HashSet<>();
for (Package p : Package.getPackages()) { for (Package p : Package.getPackages()) {
if (p.getName().startsWith("java.") || p.getName().startsWith("com.") || p.getName().startsWith("jdk.") if (p.getName().startsWith("java.") || p.getName().startsWith("com.") || p.getName().startsWith("jdk.")
|| p.getName().startsWith("javafx.") || p.getName().startsWith("org.") || p.getName().startsWith("javafx.") || p.getName().startsWith("org.")
...@@ -184,22 +207,29 @@ class StructureHelper { ...@@ -184,22 +207,29 @@ class StructureHelper {
Configuration conf = new ConfigurationBuilder().addScanners(Scanners.SubTypes.filterResultsBy(pc -> true)) Configuration conf = new ConfigurationBuilder().addScanners(Scanners.SubTypes.filterResultsBy(pc -> true))
.forPackages(p.getName()); .forPackages(p.getName());
Reflections reflections = new Reflections(conf); Reflections reflections = new Reflections(conf);
allClasses.addAll(reflections.getAll(Scanners.SubTypes.filterResultsBy(c -> { allClassesName.addAll(reflections.getAll(Scanners.SubTypes.filterResultsBy(c -> {
System.out.println(c); System.out.println(">>> " + c);
return true; return true;
}))); })));
} }
for (String string : allClasses) { for (String string : allClassesName) {
System.out.println(string); System.out.println(string);
} }
return allClasses; return allClassesName;
} }
public void dynamicaliFoundSomeClass(List<String> initClassesName) { private static final List<String> dirsToSkip = List.of("jez04", "META-INF");
private static final List<String> filesToSkip = List.of("module-info.class");
public void dynamicaliFoundSomeClass(Set<String> allClassesName) {
URL myClassUrl = StructureHelper.class.getResource("ClassStructureTest.class"); URL myClassUrl = StructureHelper.class.getResource("ClassStructureTest.class");
myClassUrl.getFile(); myClassUrl.getFile();
try { try {
Path classRoot = Paths.get(myClassUrl.toURI()).getParent().getParent().getParent().getParent(); Path classRoot = Paths.get(myClassUrl.toURI());
while (!"test-classes".equals(classRoot.getFileName().toString())
&& !"classes".equals(classRoot.getFileName().toString())) {
classRoot = classRoot.getParent();
}
if ("test-classes".equals(classRoot.getFileName().toString())) { if ("test-classes".equals(classRoot.getFileName().toString())) {
classRoot = classRoot.getParent().resolve("classes"); classRoot = classRoot.getParent().resolve("classes");
} }
...@@ -209,7 +239,7 @@ class StructureHelper { ...@@ -209,7 +239,7 @@ class StructureHelper {
@Override @Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (List.of("jez04", "META-INF").contains(dir.getFileName().toString())) { if (dirsToSkip.contains(dir.getFileName().toString())) {
return FileVisitResult.SKIP_SUBTREE; return FileVisitResult.SKIP_SUBTREE;
} }
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
...@@ -217,18 +247,20 @@ class StructureHelper { ...@@ -217,18 +247,20 @@ class StructureHelper {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("VISIT: " + file); if (filesToSkip.contains(file.getFileName().toString())) {
if ("module-info.class".equals(file.getFileName().toString())) {
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
if (!file.getFileName().toString().endsWith(".class")) { if (!file.getFileName().toString().endsWith(".class")) {
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
if (file.getFileName().toString().contains("$")) {
return FileVisitResult.CONTINUE;
}
String foundClassName = classRootFinal.relativize(file).toString(); String foundClassName = classRootFinal.relativize(file).toString();
foundClassName = foundClassName.substring(0, foundClassName.length() - 6) foundClassName = foundClassName.substring(0, foundClassName.length() - 6)
.replace(File.separatorChar, '.'); .replace(File.separatorChar, '.');
initClassesName.add(foundClassName); addClassAndAllRef(allClassesName, foundClassName);
return FileVisitResult.TERMINATE; return FileVisitResult.CONTINUE;
} }
@Override @Override
...@@ -245,4 +277,32 @@ class StructureHelper { ...@@ -245,4 +277,32 @@ class StructureHelper {
e.printStackTrace(); e.printStackTrace();
} }
} }
private void addClassAndAllRef(Set<String> allClassesName, String foundClassName) {
allClassesName.add(foundClassName);
try {
Class<?> foundClass = Class.forName(foundClassName);
List.of(foundClass.getInterfaces()).stream().map(Class::getCanonicalName).forEach(allClassesName::add);
List.of(foundClass.getDeclaredClasses()).stream().map(Class::getCanonicalName).forEach(allClassesName::add);
List.of(foundClass.getDeclaredFields()).stream().map(Field::getType)
.map(clazz -> clazz.isArray() ? clazz.componentType() : clazz).filter(Predicate.not(Class::isPrimitive))
.map(Class::getCanonicalName).forEach(allClassesName::add);
List.of(foundClass.getDeclaredMethods()).stream().map(Method::getReturnType)
.map(clazz -> clazz.isArray() ? clazz.componentType() : clazz).filter(Predicate.not(Class::isPrimitive))
.map(Class::getCanonicalName).forEach(allClassesName::add);
List.of(foundClass.getDeclaredMethods()).stream().flatMap(m -> List.of(m.getParameters()).stream())
.map(Parameter::getType).map(clazz -> clazz.isArray() ? clazz.componentType() : clazz)
.filter(Predicate.not(Class::isPrimitive)).map(Class::getCanonicalName)
.forEach(allClassesName::add);
List.of(foundClass.getDeclaredMethods()).stream().flatMap(m -> List.of(m.getExceptionTypes()).stream())
.map(clazz -> clazz.isArray() ? clazz.componentType() : clazz)
.filter(Predicate.not(Class::isPrimitive)).map(Class::getCanonicalName)
.forEach(allClassesName::add);
if(foundClass.getSuperclass() != null) {
allClassesName.add(foundClass.getSuperclass().getCanonicalName());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} }
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment