Skip to content

Fail on classpath resource names that are blank after removing leading slash #4761

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

marcphilipp
Copy link
Member

@marcphilipp marcphilipp commented Jul 12, 2025

Fixes #4752.


I hereby agree to the terms of the JUnit Contributor License Agreement.


Definition of Done

@marcphilipp marcphilipp force-pushed the marc/4752-classpath-resource-name-validation branch from 3e6aa83 to e123ed6 Compare July 12, 2025 16:59
@marcphilipp marcphilipp changed the title Fail on classpath resource names that are blank after removing leading / Fail on classpath resource names that are blank after removing leading slash Jul 12, 2025
try {
return toSource(selector);
}
catch (Exception e) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be necessary but we should do our best to avoid throwing an exception while reporting a discovery issue.

Copy link
Contributor

@mpkorstanje mpkorstanje Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is both too much and not enough.

A broad try-catch would make sense if JUnit would be invoking third-party implementations. But the current the toSource method only supports a select number of selector implementations, all owned by JUnit. If the preconditions for those selectors align with those of the test sources, this could never happen. There is not even a test you could write to make this fail.

At the same time, any third-parties can implement custom selectors, but they'll have to do their own issue reporting.

Would it make sense to add DiscoverySelector.toTestSource()? This would allow JUnit to test the toSource implementation on its own selectors and would allow third-party selectors to also provide a source.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A broad try-catch would make sense if JUnit would be invoking third-party implementations. But the current the toSource method only supports a select number of selector implementations, all owned by JUnit. If the preconditions for those selectors align with those of the test sources, this could never happen. There is not even a test you could write to make this fail.

There was, actually. 😉 I found another inconsistency with PackageSelector which allowed "" and PackageSource which didn't.

Another problem is the normalization that FileSource and DirectorySource are doing by calling File.getCanonicalFile(). For now, I've reduced the scope of the try-catch block to those.

At the same time, any third-parties can implement custom selectors, but they'll have to do their own issue reporting.

They would still benefit from the built-in issue reporting but the reported discovery issue would not have a TestSource.

Would it make sense to add DiscoverySelector.toTestSource()? This would allow JUnit to test the toSource implementation on its own selectors and would allow third-party selectors to also provide a source.

I thought about it. I don't remember the specifics but we decided to introduce another FilePosition for use in DiscoverySelector implementations because they shouldn't reference the one in the ..support.descriptor package (see #2146 (comment)). If we now introduced toSource(), all selector implementations would have to reference that package.

Another option could be to introduce a ServiceLoader-based "converter" for DiscoverySelector to TestSource. But, if this is the only use case, I'm not sure it would be justified. If you feel strongly about needing a solution for third-party selector implementations, please open a new issue and we can discuss it for 6.0 (or later).

Copy link
Contributor

@mpkorstanje mpkorstanje Jul 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got no strong feelings about this.

Oh and nice catch.

Copy link
Contributor

@mpkorstanje mpkorstanje left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will work as expected.

I've made a suggestion for a DiscoverySelector.toSource() method, but that could be pushed to v6.

try {
return toSource(selector);
}
catch (Exception e) {
Copy link
Contributor

@mpkorstanje mpkorstanje Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is both too much and not enough.

A broad try-catch would make sense if JUnit would be invoking third-party implementations. But the current the toSource method only supports a select number of selector implementations, all owned by JUnit. If the preconditions for those selectors align with those of the test sources, this could never happen. There is not even a test you could write to make this fail.

At the same time, any third-parties can implement custom selectors, but they'll have to do their own issue reporting.

Would it make sense to add DiscoverySelector.toTestSource()? This would allow JUnit to test the toSource implementation on its own selectors and would allow third-party selectors to also provide a source.

@@ -67,7 +67,7 @@ public void selectorProcessed(UniqueId engineId, DiscoverySelector selector, Sel
if (result.getStatus() == FAILED) {
this.issues.add(DiscoveryIssue.builder(Severity.ERROR, selector + " resolution failed") //
Copy link
Contributor

@mpkorstanje mpkorstanje Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a implicit toString call here to a 3rd party implementation which could throw. So the same caution that prompted toSourceSafely, should probably put a try-catch around it.

And I only just now realized that DiscoverySelector.toString() should have been implemented in Cucumber. 😉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if a toString() method throws an exception, I'm happy to let the entire discovery fail for that engine... 🤭

try {
return toSource(selector);
}
catch (Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect a rethrowIfUnrecoverable here.

Copy link
Member Author

@marcphilipp marcphilipp Jul 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 4eb5925

@marcphilipp marcphilipp force-pushed the marc/4752-classpath-resource-name-validation branch from 090e4d9 to b5f7605 Compare July 13, 2025 11:55
@marcphilipp marcphilipp force-pushed the marc/4752-classpath-resource-name-validation branch from b5f7605 to 4eb5925 Compare July 13, 2025 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ClasspathResourceSelector is more lenient than ClasspathResourceSource
2 participants