Skip to content

Commit

Permalink
#40: Introduce composite ClassFilter
Browse files Browse the repository at this point in the history
------------------------------------------------------------------------
On behalf of the community, the JUnit Lambda Team thanks
Klarna AB (http://www.klarna.com) for supporting
the JUnit crowdfunding campaign!
------------------------------------------------------------------------
  • Loading branch information
marcphilipp committed Jan 8, 2016
1 parent 15132f7 commit 1213ccf
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 33 deletions.
Expand Up @@ -10,6 +10,11 @@

package org.junit.gen5.engine;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.joining;

import java.util.List;

public class ClassFilters {

private ClassFilters() {
Expand All @@ -19,4 +24,24 @@ public static ClassFilter classNameMatches(String regex) {
return new ClassNameFilter(regex);
}

public static ClassFilter allOf(ClassFilter... filters) {
return allOf(asList(filters));
}

public static ClassFilter allOf(List<ClassFilter> filters) {
if (filters.isEmpty()) {
return anyClass();
}
if (filters.size() == 1) {
return filters.get(0);
}
return new PredicateBasedClassFilter(
testClass -> filters.stream().allMatch(filter -> filter.acceptClass(testClass)),
() -> filters.stream().map(ClassFilter::getDescription).collect(joining(") and (", "(", ")")));
}

public static ClassFilter anyClass() {
return new PredicateBasedClassFilter(c -> true, () -> "Any class");
}

}
@@ -0,0 +1,36 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.junit.gen5.engine;

import java.util.function.Predicate;
import java.util.function.Supplier;

class PredicateBasedClassFilter implements ClassFilter {

private final Predicate<? super Class<?>> predicate;
private final Supplier<String> descriptionSupplier;

PredicateBasedClassFilter(Predicate<? super Class<?>> predicate, Supplier<String> descriptionSupplier) {
this.predicate = predicate;
this.descriptionSupplier = descriptionSupplier;
}

@Override
public String getDescription() {
return descriptionSupplier.get();
}

@Override
public boolean acceptClass(Class<?> testClass) {
return predicate.test(testClass);
}

}
@@ -0,0 +1,83 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.junit.gen5.engine;

import static org.junit.gen5.api.Assertions.*;

import java.util.Collection;
import java.util.StringJoiner;

import org.junit.gen5.api.Test;

class ClassFiltersTests {

@Test
void classNameMatches() {
String regex = "^java\\.lang\\..*";

ClassFilter filter = ClassFilters.classNameMatches(regex);

assertEquals("Filter class names with regular expression: " + regex, filter.getDescription());
assertTrue(filter.acceptClass(String.class));
assertFalse(filter.acceptClass(Collection.class));
}

@Test
void anyClass() {
ClassFilter filter = ClassFilters.anyClass();

assertEquals("Any class", filter.getDescription());
assertTrue(filter.acceptClass(String.class));
assertTrue(filter.acceptClass(this.getClass()));
}

@Test
void allOfWithoutFilter() {
ClassFilter[] noFilters = {};

ClassFilter filter = ClassFilters.allOf(noFilters);

assertEquals("Any class", filter.getDescription());
assertTrue(filter.acceptClass(String.class));
assertTrue(filter.acceptClass(Object.class));
}

@Test
void allOfWithSingleFilter() {
ClassFilter singleFilter = ClassFilters.classNameMatches(".*ring.*");

ClassFilter filter = ClassFilters.allOf(singleFilter);

assertSame(singleFilter, filter);
}

@Test
void allOfWithMultipleFiltersIsConjunction() {
ClassFilter firstFilter = ClassFilters.classNameMatches(".*ring.*");
ClassFilter secondFilter = ClassFilters.classNameMatches(".*Join.*");

ClassFilter filter = ClassFilters.allOf(firstFilter, secondFilter);

assertFalse(filter.acceptClass(String.class));
assertTrue(filter.acceptClass(StringJoiner.class));
}

@Test
void allOfWithMultipleFiltersHasReadableDescription() {
ClassFilter firstFilter = new PredicateBasedClassFilter(o -> false, () -> "1st");
ClassFilter secondFilter = new PredicateBasedClassFilter(o -> true, () -> "2nd");

ClassFilter filter = ClassFilters.allOf(firstFilter, secondFilter);

assertEquals("(1st) and (2nd)", filter.getDescription());
}

}

This file was deleted.

Expand Up @@ -22,6 +22,7 @@
import java.util.function.IntFunction;

import org.junit.gen5.engine.ClassFilter;
import org.junit.gen5.engine.ClassFilters;
import org.junit.gen5.engine.EngineDescriptor;
import org.junit.gen5.engine.TestPlanSpecification;
import org.junit.gen5.engine.TestPlanSpecificationElementVisitor;
Expand All @@ -40,16 +41,15 @@ public JUnit4TestPlanSpecificationResolver(EngineDescriptor engineDescriptor) {
}

public void resolve(TestPlanSpecification specification) {
List<ClassFilter> classFilters = specification.getEngineFilters().stream().filter(
ClassFilter.class::isInstance).map(ClassFilter.class::cast).collect(toList());
ClassFilter classFilter = buildClassFilter(specification);
RunnerBuilder runnerBuilder = new DefensiveAllDefaultPossibilitiesBuilder();
specification.accept(new TestPlanSpecificationElementVisitor() {

private final IsPotentialJUnit4TestClass classTester = new IsPotentialJUnit4TestClass();

@Override
public void visitClass(Class<?> testClass) {
if (classFilters.stream().allMatch(filter -> filter.acceptClass(testClass))) {
if (classFilter.acceptClass(testClass)) {
Runner runner = runnerBuilder.safeRunnerForClass(testClass);
// TODO #40 Filter Runner as well?
if (runner != null) {
Expand All @@ -70,6 +70,16 @@ public void visitPackage(String packageName) {
});
}

private ClassFilter buildClassFilter(TestPlanSpecification specification) {
// @formatter:off
return ClassFilters.allOf(specification.getEngineFilters()
.stream()
.filter(ClassFilter.class::isInstance)
.map(ClassFilter.class::cast)
.collect(toList()));
// @formatter:on
}

private RunnerTestDescriptor createCompleteRunnerTestDescriptor(Class<?> testClass, Runner runner) {
RunnerTestDescriptor runnerTestDescriptor = new RunnerTestDescriptor(engineDescriptor, testClass, runner);
addChildrenRecursively(runnerTestDescriptor);
Expand Down

0 comments on commit 1213ccf

Please sign in to comment.