Skip to content

Commit 3214f05

Browse files
Add include matching to ClassNamePatternFilterUtils (#4115)
Issue: #3717 --------- Signed-off-by: yongjunhong <[email protected]> Co-authored-by: Marc Philipp <[email protected]>
1 parent 37e6e09 commit 3214f05

File tree

4 files changed

+195
-13
lines changed

4 files changed

+195
-13
lines changed

junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public final class Constants {
9191
* @see #DEACTIVATE_CONDITIONS_PATTERN_PROPERTY_NAME
9292
* @see org.junit.jupiter.api.extension.ExecutionCondition
9393
*/
94-
public static final String DEACTIVATE_ALL_CONDITIONS_PATTERN = ClassNamePatternFilterUtils.DEACTIVATE_ALL_PATTERN;
94+
public static final String DEACTIVATE_ALL_CONDITIONS_PATTERN = ClassNamePatternFilterUtils.ALL_PATTERN;
9595

9696
/**
9797
* Property name used to set the default display name generator class name: {@value}

junit-platform-commons/src/main/java/org/junit/platform/commons/util/ClassNamePatternFilterUtils.java

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private ClassNamePatternFilterUtils() {
4141
/* no-op */
4242
}
4343

44-
public static final String DEACTIVATE_ALL_PATTERN = "*";
44+
public static final String ALL_PATTERN = "*";
4545

4646
/**
4747
* Create a {@link Predicate} that can be used to exclude (i.e., filter out)
@@ -51,7 +51,7 @@ private ClassNamePatternFilterUtils() {
5151
* @param patterns a comma-separated list of patterns
5252
*/
5353
public static <T> Predicate<T> excludeMatchingClasses(String patterns) {
54-
return excludeMatchingClasses(patterns, object -> object.getClass().getName());
54+
return matchingClasses(patterns, object -> object.getClass().getName(), FilterType.EXCLUDE);
5555
}
5656

5757
/**
@@ -61,26 +61,57 @@ public static <T> Predicate<T> excludeMatchingClasses(String patterns) {
6161
* @param patterns a comma-separated list of patterns
6262
*/
6363
public static Predicate<String> excludeMatchingClassNames(String patterns) {
64-
return excludeMatchingClasses(patterns, Function.identity());
64+
return matchingClasses(patterns, Function.identity(), FilterType.EXCLUDE);
6565
}
6666

67-
private static <T> Predicate<T> excludeMatchingClasses(String patterns, Function<T, String> classNameGetter) {
67+
/**
68+
* Create a {@link Predicate} that can be used to include (i.e., filter in)
69+
* objects of type {@code T} whose fully qualified class names match any of
70+
* the supplied patterns.
71+
*
72+
* @param patterns a comma-separated list of patterns
73+
*/
74+
public static <T> Predicate<T> includeMatchingClasses(String patterns) {
75+
return matchingClasses(patterns, object -> object.getClass().getName(), FilterType.INCLUDE);
76+
}
77+
78+
/**
79+
* Create a {@link Predicate} that can be used to include (i.e., filter in)
80+
* fully qualified class names matching any of the supplied patterns.
81+
*
82+
* @param patterns a comma-separated list of patterns
83+
*/
84+
public static Predicate<String> includeMatchingClassNames(String patterns) {
85+
return matchingClasses(patterns, Function.identity(), FilterType.INCLUDE);
86+
}
87+
88+
private enum FilterType {
89+
INCLUDE, EXCLUDE
90+
}
91+
92+
private static <T> Predicate<T> matchingClasses(String patterns, Function<T, String> classNameProvider,
93+
FilterType type) {
6894
// @formatter:off
6995
return Optional.ofNullable(patterns)
7096
.filter(StringUtils::isNotBlank)
7197
.map(String::trim)
72-
.map(trimmedPatterns -> createPredicateFromPatterns(trimmedPatterns, classNameGetter))
73-
.orElse(object -> true);
98+
.map(trimmedPatterns -> createPredicateFromPatterns(trimmedPatterns, classNameProvider, type))
99+
.orElse(type == FilterType.EXCLUDE ? __ -> true : __ -> false);
74100
// @formatter:on
75101
}
76102

77-
private static <T> Predicate<T> createPredicateFromPatterns(String patterns,
78-
Function<T, String> classNameProvider) {
79-
if (DEACTIVATE_ALL_PATTERN.equals(patterns)) {
80-
return object -> false;
103+
private static <T> Predicate<T> createPredicateFromPatterns(String patterns, Function<T, String> classNameProvider,
104+
FilterType mode) {
105+
if (ALL_PATTERN.equals(patterns)) {
106+
return __ -> mode == FilterType.INCLUDE;
81107
}
108+
82109
List<Pattern> patternList = convertToRegularExpressions(patterns);
83-
return object -> patternList.stream().noneMatch(it -> it.matcher(classNameProvider.apply(object)).matches());
110+
return object -> {
111+
boolean isMatchingAnyPattern = patternList.stream().anyMatch(
112+
pattern -> pattern.matcher(classNameProvider.apply(object)).matches());
113+
return (mode == FilterType.INCLUDE) == isMatchingAnyPattern;
114+
};
84115
}
85116

86117
private static List<Pattern> convertToRegularExpressions(String patterns) {

junit-platform-launcher/src/main/java/org/junit/platform/launcher/LauncherConstants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public class LauncherConstants {
146146
* @see #DEACTIVATE_LISTENERS_PATTERN_PROPERTY_NAME
147147
* @see org.junit.platform.launcher.TestExecutionListener
148148
*/
149-
public static final String DEACTIVATE_ALL_LISTENERS_PATTERN = ClassNamePatternFilterUtils.DEACTIVATE_ALL_PATTERN;
149+
public static final String DEACTIVATE_ALL_LISTENERS_PATTERN = ClassNamePatternFilterUtils.ALL_PATTERN;
150150

151151
/**
152152
* Property name used to enable support for

platform-tests/src/test/java/org/junit/platform/commons/util/ClassNamePatternFilterUtilsTests.java

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,155 @@ void alwaysExcludedClassName(String pattern) {
169169
.isEmpty();
170170
}
171171

172+
//@formatter:off
173+
@ValueSource(strings = {
174+
"org.junit.jupiter.*",
175+
"org.junit.platform.*.NonExistentClass",
176+
"*.NonExistentClass*",
177+
"*NonExistentClass*",
178+
"AExecutionConditionClass, BExecutionConditionClass"
179+
})
180+
//@formatter:on
181+
@ParameterizedTest
182+
void neverIncludedConditions(String pattern) {
183+
List<? extends ExecutionCondition> executionConditions = List.of(new AExecutionConditionClass(),
184+
new BExecutionConditionClass());
185+
assertThat(executionConditions).filteredOn(ClassNamePatternFilterUtils.includeMatchingClasses(pattern)) //
186+
.isEmpty();
187+
}
188+
189+
//@formatter:off
190+
@ValueSource(strings = {
191+
"org.junit.platform.*",
192+
"*.platform.*",
193+
"*",
194+
"*AExecutionConditionClass, *BExecutionConditionClass",
195+
"*ExecutionConditionClass"
196+
})
197+
//@formatter:on
198+
@ParameterizedTest
199+
void alwaysIncludedConditions(String pattern) {
200+
List<? extends ExecutionCondition> executionConditions = List.of(new AExecutionConditionClass(),
201+
new BExecutionConditionClass());
202+
assertThat(executionConditions).filteredOn(ClassNamePatternFilterUtils.includeMatchingClasses(pattern)) //
203+
.hasSize(2);
204+
}
205+
206+
//@formatter:off
207+
@ValueSource(strings = {
208+
"org.junit.jupiter.*",
209+
"org.junit.platform.*.NonExistentClass",
210+
"*.NonExistentClass*",
211+
"*NonExistentClass*",
212+
"ATestExecutionListenerClass, BTestExecutionListenerClass"
213+
})
214+
//@formatter:on
215+
@ParameterizedTest
216+
void neverIncludedListeners(String pattern) {
217+
List<? extends TestExecutionListener> executionConditions = List.of(new ATestExecutionListenerClass(),
218+
new BTestExecutionListenerClass());
219+
assertThat(executionConditions).filteredOn(ClassNamePatternFilterUtils.includeMatchingClasses(pattern)) //
220+
.isEmpty();
221+
}
222+
223+
//@formatter:off
224+
@ValueSource(strings = {
225+
"org.junit.platform.*",
226+
"*.platform.*",
227+
"*",
228+
"*ATestExecutionListenerClass, *BTestExecutionListenerClass",
229+
"*TestExecutionListenerClass"
230+
})
231+
//@formatter:on
232+
@ParameterizedTest
233+
void alwaysIncludedListeners(String pattern) {
234+
List<? extends TestExecutionListener> executionConditions = List.of(new ATestExecutionListenerClass(),
235+
new BTestExecutionListenerClass());
236+
assertThat(executionConditions).filteredOn(ClassNamePatternFilterUtils.includeMatchingClasses(pattern)) //
237+
.hasSize(2);
238+
}
239+
240+
//@formatter:off
241+
@ValueSource(strings = {
242+
"org.junit.jupiter.*",
243+
"org.junit.platform.*.NonExistentClass",
244+
"*.NonExistentClass*",
245+
"*NonExistentClass*",
246+
"AVanillaEmpty, BVanillaEmpty"
247+
})
248+
//@formatter:on
249+
@ParameterizedTest
250+
void neverIncludedClass(String pattern) {
251+
var executionConditions = List.of(new AVanillaEmpty(), new BVanillaEmpty());
252+
assertThat(executionConditions).filteredOn(ClassNamePatternFilterUtils.includeMatchingClasses(pattern)) //
253+
.isEmpty();
254+
}
255+
256+
//@formatter:off
257+
@ValueSource(strings = {
258+
"org.junit.platform.*",
259+
"*.platform.*",
260+
"*",
261+
"*AVanillaEmpty, *BVanillaEmpty",
262+
"*VanillaEmpty"
263+
})
264+
//@formatter:on
265+
@ParameterizedTest
266+
void alwaysIncludedClass(String pattern) {
267+
var executionConditions = List.of(new AVanillaEmpty(), new BVanillaEmpty());
268+
assertThat(executionConditions).filteredOn(ClassNamePatternFilterUtils.includeMatchingClasses(pattern)) //
269+
.hasSize(2);
270+
}
271+
272+
//@formatter:off
273+
@ValueSource(strings = {
274+
"org.junit.jupiter.*",
275+
"org.junit.platform.*.NonExistentClass",
276+
"*.NonExistentClass*",
277+
"*NonExistentClass*",
278+
"AVanillaEmpty, BVanillaEmpty"
279+
})
280+
//@formatter:on
281+
@ParameterizedTest
282+
void neverIncludedClassName(String pattern) {
283+
var executionConditions = List.of("org.junit.platform.commons.util.classes.AVanillaEmpty",
284+
"org.junit.platform.commons.util.classes.BVanillaEmpty");
285+
assertThat(executionConditions).filteredOn(ClassNamePatternFilterUtils.includeMatchingClassNames(pattern)) //
286+
.isEmpty();
287+
}
288+
289+
//@formatter:off
290+
@ValueSource(strings = {
291+
"org.junit.platform.*",
292+
"*.platform.*",
293+
"*",
294+
"*AVanillaEmpty, *BVanillaEmpty",
295+
"*VanillaEmpty"
296+
})
297+
//@formatter:on
298+
@ParameterizedTest
299+
void alwaysIncludedClassName(String pattern) {
300+
var executionConditions = List.of("org.junit.platform.commons.util.classes.AVanillaEmpty",
301+
"org.junit.platform.commons.util.classes.BVanillaEmpty");
302+
assertThat(executionConditions).filteredOn(ClassNamePatternFilterUtils.includeMatchingClassNames(pattern)) //
303+
.hasSize(2);
304+
}
305+
306+
//@formatter:off
307+
@ValueSource(strings = {
308+
"org.junit.platform.*",
309+
"*.platform.*",
310+
"*",
311+
"*AVanillaEmpty, *BVanillaEmpty",
312+
"*VanillaEmpty"
313+
})
314+
//@formatter:on
315+
@ParameterizedTest
316+
void includeAndExcludeSame(String pattern) {
317+
var executionConditions = List.of("org.junit.platform.commons.util.classes.AVanillaEmpty",
318+
"org.junit.platform.commons.util.classes.BVanillaEmpty");
319+
assertThat(executionConditions).filteredOn(ClassNamePatternFilterUtils.includeMatchingClassNames(pattern)) //
320+
.hasSize(2);
321+
}
322+
172323
}

0 commit comments

Comments
 (0)