-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Add ParameterizedTest#argumentCountValidation #4045
Merged
marcphilipp
merged 27 commits into
junit-team:main
from
JonasJebing:argument-count-validation-mode
Nov 17, 2024
Merged
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
2e56d56
Issue: #3708 add ParameterizedTest#argumentCountValidation
jonas-jebing-at-ebay 3d40ebe
Merge branch 'main' into argument-count-validation-mode
JonasJebing 98cdf69
address PR comments
JonasJebing 89a7443
gradle spotlessApply
JonasJebing 5c71632
move example to .adoc because it's a test that should error
JonasJebing edd9f46
fix newline char assertion for Windows
JonasJebing beb53ab
gradle spotlessApply
JonasJebing b117b69
Merge branch 'main' into argument-count-validation-mode
JonasJebing 37216f8
Merge branch 'main' into argument-count-validation-mode
JonasJebing f87404f
add change to release-notes 5.12.0-M1
JonasJebing 14a071b
fix ArgumentCountValidationMode javadoc typo
JonasJebing 762c39a
improve ParameterizedTest javadoc
JonasJebing 8a84dc2
use underscores for unused lambda parameter
JonasJebing 09ced82
use root context store for caching config value
JonasJebing 0bf0b05
remove mention of experimental status from release note
JonasJebing f189f07
Merge branch 'main' into argument-count-validation-mode
JonasJebing 36e7729
`@ParameterizedTest`s to Parameterized tests
JonasJebing 851a4db
improve release note
JonasJebing a986bba
move user guide example to ParameterizedTestDemo
JonasJebing 2dafffb
Merge branch 'main' into argument-count-validation-mode
JonasJebing e70240c
move argument count validation to happen later
JonasJebing 3d84b9f
update javadoc to use new ArgumentCountValidator
JonasJebing dd6b55a
retrigger checks
JonasJebing 1151f6b
Merge branch 'main' into argument-count-validation-mode
JonasJebing 906881c
add small ArgumentCountValidator perf optimisations
JonasJebing 89ceaec
Merge branch 'main' into argument-count-validation-mode
JonasJebing 9619c36
Merge branch 'main' into argument-count-validation-mode
JonasJebing File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
junit-jupiter-params/src/main/java/org/junit/jupiter/params/ArgumentCountValidationMode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 validation mode. | ||
* | ||
* <p>The default validation mode may be changed via the | ||
* {@value ArgumentCountValidator#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, | ||
} |
112 changes: 112 additions & 0 deletions
112
junit-jupiter-params/src/main/java/org/junit/jupiter/params/ArgumentCountValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* | ||
* 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 static org.junit.platform.commons.support.AnnotationSupport.findAnnotation; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.Arrays; | ||
import java.util.NoSuchElementException; | ||
import java.util.Optional; | ||
|
||
import org.junit.jupiter.api.extension.ExtensionConfigurationException; | ||
import org.junit.jupiter.api.extension.ExtensionContext; | ||
import org.junit.jupiter.api.extension.InvocationInterceptor; | ||
import org.junit.jupiter.api.extension.ReflectiveInvocationContext; | ||
import org.junit.jupiter.params.provider.Arguments; | ||
import org.junit.platform.commons.logging.Logger; | ||
import org.junit.platform.commons.logging.LoggerFactory; | ||
import org.junit.platform.commons.util.Preconditions; | ||
|
||
class ArgumentCountValidator implements InvocationInterceptor { | ||
private static final Logger logger = LoggerFactory.getLogger(ArgumentCountValidator.class); | ||
|
||
static final String ARGUMENT_COUNT_VALIDATION_KEY = "junit.jupiter.params.argumentCountValidation"; | ||
|
||
private final Arguments arguments; | ||
|
||
ArgumentCountValidator(Arguments arguments) { | ||
this.arguments = arguments; | ||
} | ||
|
||
@Override | ||
public void interceptTestTemplateMethod(InvocationInterceptor.Invocation<Void> invocation, | ||
ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable { | ||
validateArgumentCount(extensionContext, arguments); | ||
invocation.proceed(); | ||
} | ||
|
||
private ExtensionContext.Store getStore(ExtensionContext context) { | ||
return context.getRoot().getStore(ExtensionContext.Namespace.create(getClass())); | ||
} | ||
|
||
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", | ||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of looking up the annotation, we should pass |
||
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.NONE; | ||
ExtensionContext.Store store = getStore(extensionContext); | ||
return store.getOrComputeIfAbsent(key, __ -> { | ||
Optional<String> optionalConfigValue = extensionContext.getConfigurationParameter(key); | ||
if (optionalConfigValue.isPresent()) { | ||
String configValue = optionalConfigValue.get(); | ||
Optional<ArgumentCountValidationMode> enumValue = Arrays.stream( | ||
ArgumentCountValidationMode.values()).filter( | ||
mode -> mode.name().equalsIgnoreCase(configValue)).findFirst(); | ||
if (enumValue.isPresent()) { | ||
logger.config(() -> String.format( | ||
"Using ArgumentCountValidationMode '%s' set via the '%s' configuration parameter.", | ||
enumValue.get().name(), key)); | ||
return enumValue.get(); | ||
} | ||
else { | ||
logger.warn(() -> String.format( | ||
"Invalid ArgumentCountValidationMode '%s' set via the '%s' configuration parameter. " | ||
+ "Falling back to the %s default value.", | ||
configValue, key, fallback.name())); | ||
return fallback; | ||
} | ||
} | ||
else { | ||
return fallback; | ||
} | ||
}, ArgumentCountValidationMode.class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please create a constant for
ExtensionContext.Namespace.create(ArgumentCountValidator.class)
.