-
-
Couldn't load subscription status.
- Fork 1.6k
Add ParameterizedTest#argumentCountValidation #4045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
2e56d56
3d40ebe
98cdf69
89a7443
5c71632
edd9f46
beb53ab
b117b69
37216f8
f87404f
14a071b
762c39a
8a84dc2
09ced82
0bf0b05
f189f07
36e7729
851a4db
a986bba
2dafffb
e70240c
3d84b9f
dd6b55a
1151f6b
906881c
89ceaec
9619c36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| /* | ||
| * Copyright 2015-2024 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 v2.0 which | ||
| * accompanies this distribution and is available at | ||
| * | ||
| * https://www.eclipse.org/legal/epl-v20.html | ||
| */ | ||
|
|
||
| package org.junit.jupiter.params; | ||
|
|
||
| import org.apiguardian.api.API; | ||
| import org.junit.jupiter.params.provider.ArgumentsSource; | ||
|
|
||
| /** | ||
| * Enumeration of argument count validation modes for {@link ParameterizedTest @ParameterizedTest}. | ||
| * | ||
| * <p>When an {@link ArgumentsSource} provides more arguments than declared by the test method, | ||
| * there might be a bug in the test method or the {@link ArgumentsSource}. | ||
| * By default, the additional arguments are ignored. | ||
| * {@link ArgumentCountValidationMode} allows you to control how additional arguments are handled. | ||
| * | ||
| * @since 5.12 | ||
| * @see ParameterizedTest | ||
| */ | ||
| @API(status = API.Status.EXPERIMENTAL, since = "5.12") | ||
| public enum ArgumentCountValidationMode { | ||
| /** | ||
| * Use the default cleanup mode. | ||
| * | ||
| * <p>The default cleanup mode may be changed via the | ||
| * {@value ParameterizedTestExtension#ARGUMENT_COUNT_VALIDATION_KEY} configuration parameter | ||
| * (see the User Guide for details on configuration parameters). | ||
| */ | ||
| DEFAULT, | ||
|
|
||
| /** | ||
| * Use the "none" argument count validation mode. | ||
| * | ||
| * <p>When there are more arguments provided than declared by the test method, | ||
| * these additional arguments are ignored. | ||
| */ | ||
| NONE, | ||
|
|
||
| /** | ||
| * Use the strict argument count validation mode. | ||
| * | ||
| * <p>When there are more arguments provided than declared by the test method, this raises an error. | ||
| */ | ||
| STRICT, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,9 +15,13 @@ | |
| import static org.junit.platform.commons.support.AnnotationSupport.isAnnotated; | ||
|
|
||
| import java.lang.reflect.Method; | ||
| import java.util.Arrays; | ||
| import java.util.NoSuchElementException; | ||
| import java.util.Optional; | ||
| import java.util.concurrent.atomic.AtomicLong; | ||
| import java.util.stream.Stream; | ||
|
|
||
| import org.junit.jupiter.api.extension.ExtensionConfigurationException; | ||
| import org.junit.jupiter.api.extension.ExtensionContext; | ||
| import org.junit.jupiter.api.extension.ExtensionContext.Namespace; | ||
| import org.junit.jupiter.api.extension.TestTemplateInvocationContext; | ||
|
|
@@ -26,6 +30,8 @@ | |
| import org.junit.jupiter.params.provider.ArgumentsProvider; | ||
| import org.junit.jupiter.params.provider.ArgumentsSource; | ||
| import org.junit.jupiter.params.support.AnnotationConsumerInitializer; | ||
| import org.junit.platform.commons.logging.Logger; | ||
| import org.junit.platform.commons.logging.LoggerFactory; | ||
| import org.junit.platform.commons.util.ExceptionUtils; | ||
| import org.junit.platform.commons.util.Preconditions; | ||
|
|
||
|
|
@@ -34,10 +40,13 @@ | |
| */ | ||
| class ParameterizedTestExtension implements TestTemplateInvocationContextProvider { | ||
|
|
||
| private static final Logger logger = LoggerFactory.getLogger(ParameterizedTestExtension.class); | ||
|
|
||
| private static final String METHOD_CONTEXT_KEY = "context"; | ||
| static final String ARGUMENT_MAX_LENGTH_KEY = "junit.jupiter.params.displayname.argument.maxlength"; | ||
| static final String DEFAULT_DISPLAY_NAME = "{default_display_name}"; | ||
| static final String DISPLAY_NAME_PATTERN_KEY = "junit.jupiter.params.displayname.default"; | ||
| static final String ARGUMENT_COUNT_VALIDATION_KEY = "junit.jupiter.params.argumentCountValidation"; | ||
|
|
||
| @Override | ||
| public boolean supportsTestTemplate(ExtensionContext context) { | ||
|
|
@@ -86,6 +95,7 @@ public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContex | |
| .map(provider -> AnnotationConsumerInitializer.initialize(templateMethod, provider)) | ||
| .flatMap(provider -> arguments(provider, extensionContext)) | ||
| .map(arguments -> { | ||
| validateArgumentCount(extensionContext, arguments); | ||
marcphilipp marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| invocationCount.incrementAndGet(); | ||
marcphilipp marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return createInvocationContext(formatter, methodContext, arguments, invocationCount.intValue()); | ||
| }) | ||
|
|
@@ -99,6 +109,55 @@ private ExtensionContext.Store getStore(ExtensionContext context) { | |
| return context.getStore(Namespace.create(ParameterizedTestExtension.class, context.getRequiredTestMethod())); | ||
| } | ||
|
|
||
| private void validateArgumentCount(ExtensionContext extensionContext, Arguments arguments) { | ||
| ArgumentCountValidationMode argumentCountValidationMode = getArgumentCountValidationMode(extensionContext); | ||
| switch (argumentCountValidationMode) { | ||
| case DEFAULT: | ||
| case NONE: | ||
| return; | ||
| case STRICT: | ||
| int testParamCount = extensionContext.getRequiredTestMethod().getParameterCount(); | ||
| int argumentsCount = arguments.get().length; | ||
| Preconditions.condition(testParamCount == argumentsCount, () -> String.format( | ||
| "Configuration error: the @ParameterizedTest has %s argument(s) but there were %s argument(s) provided./nNote: the provided arguments are %s", | ||
marcphilipp marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| testParamCount, argumentsCount, Arrays.toString(arguments.get()))); | ||
| break; | ||
| default: | ||
| throw new ExtensionConfigurationException( | ||
| "Unsupported argument count validation mode: " + argumentCountValidationMode); | ||
| } | ||
| } | ||
|
|
||
| private ArgumentCountValidationMode getArgumentCountValidationMode(ExtensionContext extensionContext) { | ||
| ParameterizedTest parameterizedTest = findAnnotation(// | ||
| extensionContext.getRequiredTestMethod(), ParameterizedTest.class// | ||
| ).orElseThrow(NoSuchElementException::new); | ||
| if (parameterizedTest.argumentCountValidation() != ArgumentCountValidationMode.DEFAULT) { | ||
| return parameterizedTest.argumentCountValidation(); | ||
| } | ||
| else { | ||
| return getArgumentCountValidationModeConfiguration(extensionContext); | ||
| } | ||
| } | ||
|
|
||
| private ArgumentCountValidationMode getArgumentCountValidationModeConfiguration(ExtensionContext extensionContext) { | ||
| String key = ARGUMENT_COUNT_VALIDATION_KEY; | ||
| ArgumentCountValidationMode fallback = ArgumentCountValidationMode.DEFAULT; | ||
| Optional<String> optionalValue = extensionContext.getConfigurationParameter(key); | ||
| if (optionalValue.isPresent()) { | ||
| String value = optionalValue.get(); | ||
| return Arrays.stream(ArgumentCountValidationMode.values()).filter( | ||
| mode -> mode.name().equalsIgnoreCase(value)).findFirst().orElseGet(() -> { | ||
| logger.warn(() -> String.format( | ||
| "Ignored invalid configuration '%s' set via the '%s' configuration parameter.", value, key)); | ||
|
||
| return fallback; | ||
| }); | ||
| } | ||
| else { | ||
| return fallback; | ||
| } | ||
marcphilipp marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| private TestTemplateInvocationContext createInvocationContext(ParameterizedTestNameFormatter formatter, | ||
| ParameterizedTestMethodContext methodContext, Arguments arguments, int invocationIndex) { | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.