Skip to content

Commit

Permalink
Adds ScanOption.except (for classes)
Browse files Browse the repository at this point in the history
  • Loading branch information
jqno committed Feb 4, 2025
1 parent 6182549 commit 64fb6a4
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,15 @@ public static ScanOption recursive() {
public static ScanOption mustExtend(Class<?> type) {
return new ScanOptions.MustExtend(type);
}

/**
* Removes the given type or types from the list of types to verify.
*
* @param type A type to remove from the list of types to verify.
* @param more More types to remove from the list of types to verify.
* @return The 'except' flag with the associated types.
*/
public static ScanOption except(Class<?> type, Class<?>... more) {
return new ScanOptions.ExceptClasses(type, more);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package nl.jqno.equalsverifier;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import nl.jqno.equalsverifier.internal.reflection.PackageScanOptions;

final class ScanOptions {
Expand All @@ -17,6 +21,16 @@ static class MustExtend implements ScanOption {
}
}

static class ExceptClasses implements ScanOption {
final Set<Class<?>> types;

ExceptClasses(Class<?> type, Class<?>... more) {
this.types = new HashSet<>();
this.types.add(type);
this.types.addAll(Arrays.asList(more));
}
}

public static PackageScanOptions process(ScanOption... options) {
PackageScanOptions result = new PackageScanOptions();
for (ScanOption option : options) {
Expand All @@ -27,6 +41,10 @@ public static PackageScanOptions process(ScanOption... options) {
MustExtend me = (MustExtend) option;
result.mustExtend = me.type;
}
if (option instanceof ExceptClasses) {
ExceptClasses ec = (ExceptClasses) option;
result.exceptClasses.addAll(ec.types);
}
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,11 @@ public MultipleTypeEqualsVerifierApi withResetCaches() {
* @param type A type to remove from the list of types to verify.
* @param more More types to remove from the list of types to verify.
* @return {@code this}, for easy method chaining.
* @deprecated Use {@link EqualsVerifier#forPackage(String, ScanOption...)} with
* {@link ScanOption#except(Class, Class...)} instead.
*/
@CheckReturnValue
@Deprecated
public MultipleTypeEqualsVerifierApi except(Class<?> type, Class<?>... more) {
List<Class<?>> typesToRemove = ListBuilders.buildListOfAtLeastOne(type, more);
removeTypes(typesToRemove);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package nl.jqno.equalsverifier.internal.reflection;

import java.util.HashSet;
import java.util.Set;

public class PackageScanOptions {

public boolean scanRecursively = false;
public Class<?> mustExtend = null;
public Set<Class<?>> exceptClasses = new HashSet<>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.stream.Collectors;

import nl.jqno.equalsverifier.internal.exceptions.ReflectionException;
import nl.jqno.equalsverifier.internal.util.Validations;

/** Scans a package for classes. */
public final class PackageScanner {
Expand All @@ -27,10 +28,14 @@ private PackageScanner() {}
* @return the classes contained in the given package.
*/
public static List<Class<?>> getClassesIn(String packageName, PackageScanOptions options) {
return getDirs(packageName)
List<Class<?>> result = getDirs(packageName)
.stream()
.flatMap(d -> getClassesInDir(packageName, d, options).stream())
.collect(Collectors.toList());

Validations.validateTypesAreKnown(options.exceptClasses, result);
result.removeAll(options.exceptClasses);
return result;
}

private static List<File> getDirs(String packageName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public static void validatePackageContainsClasses(String packageName, List<Class
validate(types.size() == 0, "package " + packageName + " doesn't contain any (non-Test) types.");
}

public static void validateTypesAreKnown(List<Class<?>> types, List<Class<?>> knownTypes) {
public static void validateTypesAreKnown(Collection<Class<?>> types, List<Class<?>> knownTypes) {
List<Class<?>> unknownTypes = types.stream().filter(t -> !knownTypes.contains(t)).collect(Collectors.toList());
String message = "Unknown class(es) found: "
+ unknownTypes.stream().map(t -> t.getCanonicalName()).collect(Collectors.joining(", "));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import nl.jqno.equalsverifier.EqualsVerifier;
import nl.jqno.equalsverifier.testhelpers.packages.subclasses.SuperA;
import nl.jqno.equalsverifier.testhelpers.packages.twoincorrect.IncorrectM;
import nl.jqno.equalsverifier.testhelpers.packages.twoincorrect.IncorrectN;
import org.junit.jupiter.api.Test;

@SuppressWarnings("deprecation")
Expand All @@ -28,4 +30,21 @@ void simpleMustExtend() {
.forPackage("nl.jqno.equalsverifier.integration.extra_features.simple_package", Object.class)
.verify();
}

@Test
void directExceptClass() {
EqualsVerifier
.forPackage("nl.jqno.equalsverifier.testhelpers.packages.twoincorrect")
.except(IncorrectM.class, IncorrectN.class)
.verify();
}

@Test
void simpleExceptClass() {
EqualsVerifier
.simple()
.forPackage("nl.jqno.equalsverifier.testhelpers.packages.twoincorrect")
.except(IncorrectM.class, IncorrectN.class)
.verify();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,37 +178,44 @@ void fail_whenCallingForPackageWithASuperclass_whenPackageHasNoClasses() {

@Test
void succeed_whenCallingForPackageOnAPackageContainingFailingClasses_givenFailingClassesAreExcepted() {
EqualsVerifier.forPackage(INCORRECT_PACKAGE).except(IncorrectM.class, IncorrectN.class).verify();
EqualsVerifier.forPackage(INCORRECT_PACKAGE, ScanOption.except(IncorrectM.class, IncorrectN.class)).verify();
}

@Test
void succeed_whenCallingForPackageRecursivelyOnAPackageContainingFailingClasses_givenFailingClassesAreExcepted() {
EqualsVerifier
.forPackage(INCORRECT_PACKAGE, ScanOption.recursive())
.except(IncorrectM.class, IncorrectN.class, IncorrectO.class, IncorrectP.class)
.forPackage(
INCORRECT_PACKAGE,
ScanOption.recursive(),
ScanOption.except(IncorrectM.class, IncorrectN.class, IncorrectO.class, IncorrectP.class))
.verify();
}

@Test
void succeed_whenCallingForPackageWithASuperclassOnAPackageContainingFailingClasses_givenFailingClassesAreExcepted() {
EqualsVerifier
.forPackage(INCORRECT_PACKAGE, ScanOption.recursive(), ScanOption.mustExtend(Object.class))
.except(IncorrectM.class, IncorrectN.class, IncorrectO.class, IncorrectP.class)
.forPackage(
INCORRECT_PACKAGE,
ScanOption.recursive(),
ScanOption.mustExtend(Object.class),
ScanOption.except(IncorrectM.class, IncorrectN.class, IncorrectO.class, IncorrectP.class))
.verify();
}

@Test
void fail_whenExceptingAClassThatDoesntExistInThePackage() {
ExpectedException
.when(() -> EqualsVerifier.forPackage(CORRECT_PACKAGE).except(IncorrectM.class))
.when(() -> EqualsVerifier.forPackage(CORRECT_PACKAGE, ScanOption.except(IncorrectM.class)))
.assertThrows(IllegalStateException.class)
.assertMessageContains("Unknown class(es) found", "IncorrectM");
}

@Test
void fail_whenExceptingAClassThatDoesntExistInThePackageAndSubPackages() {
ExpectedException
.when(() -> EqualsVerifier.forPackage(CORRECT_PACKAGE, ScanOption.recursive()).except(IncorrectM.class))
.when(
() -> EqualsVerifier
.forPackage(CORRECT_PACKAGE, ScanOption.recursive(), ScanOption.except(IncorrectM.class)))
.assertThrows(IllegalStateException.class)
.assertMessageContains("Unknown class(es) found", "IncorrectM");
}
Expand Down

0 comments on commit 64fb6a4

Please sign in to comment.