Skip to content

Commit

Permalink
refactor: use classgraph in ExtendAbstractTest
Browse files Browse the repository at this point in the history
Replace custom implementation with classgraph. This solution is easier to understand.
  • Loading branch information
remcowesterhoud committed Mar 15, 2022
1 parent 6287137 commit 26ce3f7
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 63 deletions.
10 changes: 8 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<dependency.agrona.version>1.14.0</dependency.agrona.version>
<dependency.assertj.version>3.22.0</dependency.assertj.version>
<dependency.awaitility.version>4.2.0</dependency.awaitility.version>
<dependency.classgraph.version>4.8.141</dependency.classgraph.version>
<dependency.commons.version>3.12.0</dependency.commons.version>
<dependency.errorprone.version>2.11.0</dependency.errorprone.version>
<dependency.eze.version>0.6.0</dependency.eze.version>
Expand Down Expand Up @@ -278,13 +279,18 @@
<version>${dependency.testcontainers.version}</version>
</dependency>

<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>${dependency.classgraph.version}</version>
</dependency>

<!-- Only for dependency convergence issues -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${dependency.guava.version}</version>
</dependency>

<!-- Only for dependency convergence issues -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
Expand Down
10 changes: 8 additions & 2 deletions qa/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,14 @@
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,80 +15,76 @@
*/
package io.camunda.zeebe.process.test.qa;

import com.google.common.reflect.ClassPath;
import io.camunda.zeebe.process.test.extension.ZeebeProcessTest;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo;
import io.github.classgraph.ClassInfoList;
import java.util.stream.Stream;
import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

class ExtendAbstractsTest {

public static final String EMBEDDED = "embedded";
public static final String TESTCONTAINER = "testcontainer";
public static final Class<ZeebeProcessTest> EMBEDDED_ANNOTATION = ZeebeProcessTest.class;
public static final Class<io.camunda.zeebe.process.test.extension.testcontainer.ZeebeProcessTest>
TESTCONTAINER_ANNOTATION =
io.camunda.zeebe.process.test.extension.testcontainer.ZeebeProcessTest.class;
private static final String BASE_PACKAGE = "io.camunda.zeebe.process.test.qa";
private static final String ABSTRACTS = "abstracts";
private static final String ABSTRACT_PACKAGE = "io.camunda.zeebe.process.test.qa.abstracts";
private static final String EMBEDDED_PACKAGE = "io.camunda.zeebe.process.test.qa.embedded";
private static final String TESTCONTAINER_PACKAGE =
"io.camunda.zeebe.process.test.qa.testcontainer";

@Test
void testAbstractClassesAreExtendedWithBothExtensions() throws IOException {
final Map<String, List<Class<?>>> classes = new HashMap<>();
classes.put(ABSTRACTS, new ArrayList<>());
classes.put(EMBEDDED, new ArrayList<>());
classes.put(TESTCONTAINER, new ArrayList<>());
private static final ClassInfoList EXTENDING_CLASSES =
new ClassGraph()
.acceptPackages(EMBEDDED_PACKAGE, TESTCONTAINER_PACKAGE)
.ignoreClassVisibility()
.enableAnnotationInfo()
.scan()
.getAllStandardClasses()
.filter(info -> !info.isInnerClass());

ClassPath.from(ClassLoader.getSystemClassLoader()).getTopLevelClasses().stream()
.filter(clazz -> clazz.getPackageName().startsWith(BASE_PACKAGE))
.forEach(
classInfo -> {
if (classInfo.getPackageName().contains(BASE_PACKAGE + "." + ABSTRACTS)) {
classes.get(ABSTRACTS).add(classInfo.load());
} else if (classInfo.getPackageName().contains(BASE_PACKAGE + "." + EMBEDDED)) {
classes.get(EMBEDDED).add(classInfo.load());
} else if (classInfo.getPackageName().contains(BASE_PACKAGE + "." + TESTCONTAINER)) {
classes.get(TESTCONTAINER).add(classInfo.load());
}
});
@ParameterizedTest(name = "{0}")
@MethodSource("provideAbstractClasses")
void testAbstractClassIsExtendedWithBothExtensions(
final String className, final Class<?> abstractClass) {
final ClassInfoList embeddedClass =
EXTENDING_CLASSES
.filter(info -> info.getPackageName().contains("embedded"))
.filter(info -> info.extendsSuperclass(abstractClass))
.filter(info -> info.hasAnnotation(EMBEDDED_ANNOTATION));

final ClassInfoList testcontainerClass =
EXTENDING_CLASSES
.filter(info -> info.getPackageName().contains("testcontainer"))
.filter(info -> info.extendsSuperclass(abstractClass))
.filter(info -> info.hasAnnotation(TESTCONTAINER_ANNOTATION));

final SoftAssertions softly = new SoftAssertions();
classes
.get(ABSTRACTS)
.forEach(
abstractClass -> {
assertExtendingClass(
abstractClass, classes.get(EMBEDDED), EMBEDDED, EMBEDDED_ANNOTATION, softly);
assertExtendingClass(
abstractClass,
classes.get(TESTCONTAINER),
TESTCONTAINER,
TESTCONTAINER_ANNOTATION,
softly);
});
softly
.assertThat(embeddedClass)
.withFailMessage(
"Expected 1 embedded implementation of %s, but found %d: %s",
className, embeddedClass.size(), embeddedClass)
.hasSize(1);
softly
.assertThat(testcontainerClass)
.withFailMessage(
"Expected 1 testcontainer implementation of %s, but found %d: %s",
className, embeddedClass.size(), embeddedClass)
.hasSize(1);
softly.assertAll();
}

private void assertExtendingClass(
final Class<?> abstractClass,
final List<Class<?>> classes,
final String classPackage,
final Class<? extends Annotation> annotation,
final SoftAssertions softly) {
final Optional<Class<?>> clazzOptional =
classes.stream().filter(abstractClass::isAssignableFrom).findFirst();
softly
.assertThat(clazzOptional)
.withFailMessage(
"Package %s.%s does not contain a class extending %s",
BASE_PACKAGE, classPackage, abstractClass)
.isNotEmpty();
clazzOptional.ifPresent(clazz -> softly.assertThat(clazz).hasAnnotation(annotation));
private static Stream<Arguments> provideAbstractClasses() {
return new ClassGraph()
.acceptPackages(ABSTRACT_PACKAGE)
.scan()
.getAllStandardClasses()
.filter(ClassInfo::isAbstract)
.filter(info -> !info.isInnerClass())
.stream()
.map(info -> Arguments.of(info.getSimpleName(), info.loadClass()));
}
}

0 comments on commit 26ce3f7

Please sign in to comment.