-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Introduce Converter
in junit-platform-commons
#4219
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
base: main
Are you sure you want to change the base?
Conversation
There is plenty of work to do 🙃 The current highlights:
Any feedback would be highly appreciated! |
c31ca83
to
b19cba8
Compare
b19cba8
to
a7a8aa3
Compare
3304ad5
to
c886b7a
Compare
junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/ArgumentConverter.java
Outdated
Show resolved
Hide resolved
c886b7a
to
7ea91b8
Compare
Thanks for the draft! 👍 The tests are failing due to:
That's because
|
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.
Looks very promising! 👍
...m-commons/src/main/java/org/junit/platform/commons/support/conversion/ConversionSupport.java
Outdated
Show resolved
Hide resolved
...m-commons/src/main/java/org/junit/platform/commons/support/conversion/ConversionSupport.java
Show resolved
Hide resolved
...m-commons/src/main/java/org/junit/platform/commons/support/conversion/ConversionSupport.java
Outdated
Show resolved
Hide resolved
...ns/src/main/java/org/junit/platform/commons/support/conversion/DefaultConversionService.java
Outdated
Show resolved
Hide resolved
|
||
import org.junit.platform.commons.support.conversion.TypedConversionService; | ||
|
||
// FIXME delete |
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.
This would make a good test case, though. We have existing tests that register services for tests using an extra class loader:
junit5/platform-tests/src/test/java/org/junit/platform/launcher/core/LauncherFactoryTests.java
Lines 353 to 366 in 16c6f72
private static void withTestServices(Runnable runnable) { | |
var current = Thread.currentThread().getContextClassLoader(); | |
var url = LauncherFactoryTests.class.getClassLoader().getResource("testservices/"); | |
try (var classLoader = new URLClassLoader(new URL[] { url }, current)) { | |
Thread.currentThread().setContextClassLoader(classLoader); | |
runnable.run(); | |
} | |
catch (IOException e) { | |
throw new UncheckedIOException(e); | |
} | |
finally { | |
Thread.currentThread().setContextClassLoader(current); | |
} | |
} |
We could generalize and move that method to a test utility class (e.g. in junit-jupiter-api/src/testFixtures
) so it can be reused here.
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.
Another possible integration test could be inspired by #3605.
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.
We could generalize and move that method to a test utility class (e.g. in
junit-jupiter-api/src/testFixtures
) so it can be reused here.
@marcphilipp fine if I do it in a separate PR? Mostly to keep the size of this one under control 🙃
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.
Raised #4544.
When you add that, you'll also have to add it to |
2e17c2b
to
0c2faa7
Compare
I've been lagging behind with this one but I should be able to spend time on it in the upcoming weekend. |
0c2faa7
to
098c972
Compare
098c972
to
8ed6eb6
Compare
...m-commons/src/main/java/org/junit/platform/commons/support/conversion/ConversionSupport.java
Show resolved
Hide resolved
...-jupiter-params/src/main/java/org/junit/jupiter/params/converter/TypedArgumentConverter.java
Outdated
Show resolved
Hide resolved
8ed6eb6
to
940d018
Compare
Would you like to include this in 5.13 too? I should have enough time in the upcoming days to finalize it. |
0a36152
to
e380b8f
Compare
After renaming to I propose to refactor the WDYT? |
That's pretty much the vision I had all along: to have single abstraction/API. So, yes, that sounds good to me. 👍 Though... the devil is in details. 😉 |
public Class<?> getType() { | ||
return type; | ||
} |
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.
For now, most of the code relies on getType()
, but I plan to check if dedicated APIs could better encapsulate some use cases (similar to getWrapperType
or isPrimitive
).
} | ||
return null; | ||
} | ||
return convert(source, TypeDescriptor.forType(targetType), getClassLoader(classLoader)); |
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.
I wonder if the deprecated convert
should delegate to the other convert
method or should invoke DefaultConverter
directly, skipping the new service loader logic. For now, I went with the former.
...-platform-commons/src/main/java/org/junit/platform/commons/support/conversion/Converter.java
Outdated
Show resolved
Hide resolved
...form-commons/src/main/java/org/junit/platform/commons/support/conversion/TypedConverter.java
Outdated
Show resolved
Hide resolved
...ons/src/main/java/org/junit/platform/commons/support/conversion/StringToObjectConverter.java
Show resolved
Hide resolved
* @see TypedConverter | ||
*/ | ||
@API(status = EXPERIMENTAL, since = "1.13") | ||
public interface Converter { |
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.
Didn't we decide to make this generic
as in Converter<S, T>
?
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.
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.
I had the same in mind but wasn't entirely confident about this direction yesterday, especially before refactoring StringToObjectConversion
.
But now the refactoring is done so I can sketch it and see what happens 🙂
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.
Started in 8b78923, there is still work to do.
@marcphilipp @sbrannen could you please check if this is the direction you have in mind?
It's worth mentioning that TypedConverter
is still available to allow simpler implementations of basic converters.
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.
Thanks! I left some comments in #4219 (review) below
6001a2c
to
5190e37
Compare
public static TypeDescriptor forClass(Class<?> clazz) { | ||
return new TypeDescriptor(clazz); | ||
} | ||
|
||
public static TypeDescriptor forInstance(Object instance) { | ||
return new TypeDescriptor(instance.getClass()); | ||
} | ||
|
||
public static TypeDescriptor forField(Field field) { | ||
return new TypeDescriptor(field.getType()); | ||
} | ||
|
||
public static TypeDescriptor forParameter(Parameter parameter) { | ||
return new TypeDescriptor(parameter.getType()); | ||
} |
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.
General null
handling is currently missing
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
TypeDescriptor that = (TypeDescriptor) o; | ||
return this.type.equals(that.type); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return this.type.hashCode(); | ||
} |
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.
I noticed EqualsAndHashCodeAssertions
under junit-jupiter-api
to test equals
/hashCode
. It seems I can use the same in junit-platform-commons
.
Out of curiosity, was EqualsVerifier ever considered for such tests?
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.
I noticed
EqualsAndHashCodeAssertions
underjunit-jupiter-api
to testequals
/hashCode
. It seems I can use the same injunit-platform-commons
.
👍
Out of curiosity, was EqualsVerifier ever considered for such tests?
I don't think it was discussed but it might be a good addition or even replacement but probably in a separate PR.
af01791
to
0034d7d
Compare
0034d7d
to
791778e
Compare
...form-commons/src/main/java/org/junit/platform/commons/support/conversion/TypeDescriptor.java
Outdated
Show resolved
Hide resolved
...m-commons/src/main/java/org/junit/platform/commons/support/conversion/ConversionSupport.java
Outdated
Show resolved
Hide resolved
267ee7f
to
8b78923
Compare
} | ||
|
||
public String getTypeName() { | ||
return type.getName(); |
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.
Shouldn't this method also be @Nullable
and check for NONE
?
|
||
@Override | ||
public final boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { | ||
return canConvert(targetType.getType()); |
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.
It still doesn't sit well with me that targetType.getType()
can be null
. Should we add a getRequiredType()
method so that Converter
implementations don't have to verify it's not null?
|
||
@Override | ||
protected @Nullable Locale convert(@Nullable String source) { | ||
return source != null ? Locale.forLanguageTag(source) : null; |
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.
This class should return false
from canConvert
when source
is null
, shouldn't it?
...-platform-commons/src/main/java/org/junit/platform/commons/support/conversion/Converter.java
Outdated
Show resolved
Hide resolved
@scordio Thanks! I've changed the setting. |
Now that Before exploring this in detail, I wanted to check your opinion first. |
8b78923
to
789d5d5
Compare
I think that could be useful and worth giving a try. 👍 |
Overview
ConversionService
SPI #853String
toNumber
conversion #3605I hereby agree to the terms of the JUnit Contributor License Agreement.
Definition of Done
@API
annotations