Skip to content

Commit

Permalink
Adds ScanOption.except (for predicates)
Browse files Browse the repository at this point in the history
  • Loading branch information
jqno committed Feb 4, 2025
1 parent 64fb6a4 commit acd3265
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package nl.jqno.equalsverifier;

import java.util.function.Predicate;

/**
* Contains a number of options that can be set in {@link EqualsVerifier#forPackage(String, ScanOption...)}. These
* options affect the way in which EqualsVerifier scans the given package.
Expand Down Expand Up @@ -35,4 +37,14 @@ public static ScanOption mustExtend(Class<?> type) {
public static ScanOption except(Class<?> type, Class<?>... more) {
return new ScanOptions.ExceptClasses(type, more);
}

/**
* Removes all types matching the given Predicate.
*
* @param exclusionPredicate A Predicate matching classes to remove from the list of types to verify.
* @return The 'except' flag with the associated Predicate.
*/
public static ScanOption except(Predicate<Class<?>> exclusionPredicate) {
return new ScanOptions.ExclusionPredicate(exclusionPredicate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

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

Expand Down Expand Up @@ -31,6 +32,14 @@ static class ExceptClasses implements ScanOption {
}
}

static class ExclusionPredicate implements ScanOption {
final Predicate<Class<?>> exclusionPredicate;

ExclusionPredicate(Predicate<Class<?>> exclusionPredicate) {
this.exclusionPredicate = exclusionPredicate;
}
}

public static PackageScanOptions process(ScanOption... options) {
PackageScanOptions result = new PackageScanOptions();
for (ScanOption option : options) {
Expand All @@ -45,6 +54,10 @@ public static PackageScanOptions process(ScanOption... options) {
ExceptClasses ec = (ExceptClasses) option;
result.exceptClasses.addAll(ec.types);
}
if (option instanceof ExclusionPredicate) {
ExclusionPredicate ep = (ExclusionPredicate) option;
result.exclusionPredicate = ep.exclusionPredicate;
}
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,11 @@ public MultipleTypeEqualsVerifierApi except(Class<?> type, Class<?>... more) {
*
* @param exclusionPredicate A Predicate matching classes 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(Predicate)} instead.
*/
@CheckReturnValue
@Deprecated
public MultipleTypeEqualsVerifierApi except(Predicate<Class<?>> exclusionPredicate) {
List<Class<?>> typesToRemove = types.stream().filter(exclusionPredicate).collect(Collectors.toList());
removeTypes(typesToRemove);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

public class PackageScanOptions {

public boolean scanRecursively = false;
public Class<?> mustExtend = null;
public Set<Class<?>> exceptClasses = new HashSet<>();
public Predicate<Class<?>> exclusionPredicate = c -> false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

import java.io.File;
import java.net.URL;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import nl.jqno.equalsverifier.internal.exceptions.ReflectionException;
Expand Down Expand Up @@ -35,6 +37,7 @@ public static List<Class<?>> getClassesIn(String packageName, PackageScanOptions

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,21 @@ void simpleExceptClass() {
.except(IncorrectM.class, IncorrectN.class)
.verify();
}

@Test
void directExceptPredicate() {
EqualsVerifier
.forPackage("nl.jqno.equalsverifier.testhelpers.packages.twoincorrect")
.except(c -> c.getSimpleName().contains("Incorrect"))
.verify();
}

@Test
void simpleExceptPredicate() {
EqualsVerifier
.simple()
.forPackage("nl.jqno.equalsverifier.testhelpers.packages.twoincorrect")
.except(c -> c.getSimpleName().contains("Incorrect"))
.verify();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -222,21 +222,25 @@ void fail_whenExceptingAClassThatDoesntExistInThePackageAndSubPackages() {

@Test
void succeed_whenCallingForPackageOnAPackageContainingFailingClasses_givenFailingClassesAreExceptedByPredicate() {
EqualsVerifier.forPackage(INCORRECT_PACKAGE).except(c -> c.getSimpleName().contains("Incorrect")).verify();
EqualsVerifier
.forPackage(INCORRECT_PACKAGE, ScanOption.except(c -> c.getSimpleName().contains("Incorrect")))
.verify();
}

@Test
void succeed_whenCallingForPackageRecursivelyOnAPackageContainingFailingClasses_givenFailingClassesAreExceptedByPredicate() {
EqualsVerifier
.forPackage(INCORRECT_PACKAGE, ScanOption.recursive())
.except(c -> c.getSimpleName().contains("Incorrect"))
.forPackage(
INCORRECT_PACKAGE,
ScanOption.recursive(),
ScanOption.except(c -> c.getSimpleName().contains("Incorrect")))
.verify();
}

@Test
void fail_whenCallingForPackageOnAPackageContainingFailingClasses_givenFailingClassesAreNotExceptedByPredicate() {
ExpectedException
.when(() -> EqualsVerifier.forPackage(INCORRECT_PACKAGE).except(c -> false).verify())
.when(() -> EqualsVerifier.forPackage(INCORRECT_PACKAGE, ScanOption.except(c -> false)).verify())
.assertFailure()
.assertMessageContains("EqualsVerifier found a problem in 2 classes");
}
Expand All @@ -246,21 +250,29 @@ void fail_whenCallingForPackageRecursivelyOnAPackageContainingFailingClasses_giv
ExpectedException
.when(
() -> EqualsVerifier
.forPackage(INCORRECT_PACKAGE, ScanOption.recursive())
.except(c -> false)
.forPackage(INCORRECT_PACKAGE, ScanOption.recursive(), ScanOption.except(c -> false))
.verify())
.assertFailure()
.assertMessageContains("EqualsVerifier found a problem in 4 classes");
}

@Test
void succeed_whenCallingForPackageOnAPackageContainingFailingClasses_givenAllClassesAreExceptedByPredicate() {
EqualsVerifier.forPackage(INCORRECT_PACKAGE).except(c -> true).verify();
void fail_whenCallingForPackageOnAPackageContainingFailingClasses_givenAllClassesAreExceptedByPredicate() {
ExpectedException
.when(() -> EqualsVerifier.forPackage(INCORRECT_PACKAGE, ScanOption.except(c -> true)).verify())
.assertThrows(IllegalStateException.class)
.assertMessageContains(INCORRECT_PACKAGE, "doesn't contain any (non-Test) types");
}

@Test
void succeed_whenCallingForPackageRecursivelyOnAPackageContainingFailingClasses_givenAllClassesAreExceptedByPredicate() {
EqualsVerifier.forPackage(INCORRECT_PACKAGE, ScanOption.recursive()).except(c -> true).verify();
void fail_whenCallingForPackageRecursivelyOnAPackageContainingFailingClasses_givenAllClassesAreExceptedByPredicate() {
ExpectedException
.when(
() -> EqualsVerifier
.forPackage(INCORRECT_PACKAGE, ScanOption.recursive(), ScanOption.except(c -> true))
.verify())
.assertThrows(IllegalStateException.class)
.assertMessageContains(INCORRECT_PACKAGE, "doesn't contain any (non-Test) types");
}

@Test
Expand Down

0 comments on commit acd3265

Please sign in to comment.