Skip to content
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

JavaClass.Predicates API: missing .extends(String/class/DescribedPredicate) #1169

Open
u3r opened this issue Sep 27, 2023 · 2 comments
Open

Comments

@u3r
Copy link
Contributor

u3r commented Sep 27, 2023

I am trying to write a test that verifies that classes that are inherited from fulfill certain properties.
However currently there is only JavaClass.Predicates.implement for interfaces, JavaClass.Predicates.assigneableTo/From and the latter do also return themselves if matching.

Stupid example demonstrating the problem - this matches each class ending in "FOO" with itself:

@ArchTest
   public ArchRule thisSadlyMatchesAllClassesEndingWithFOO  =
         noClasses()
               .that().haveSimpleNameEndingWith( "FOO" )
               .should( ArchCondition.from( JavaClass.Predicates.assignableTo( JavaClass.Predicates.simpleNameContaining( "FOO" ) ) ) );

My current custom predicate uses this logic:

 @Override 
      public boolean test( JavaClass javaClass ) { // Could be added as JavaClass.Predicates.extends
         return Stream.concat(
                     // leave out javaclass.this which is contained in javaClass.getClassHierarchy()
                     javaClass.getAllRawSuperclasses().stream(),
                     javaClass.getAllRawInterfaces().stream()
               )
               .anyMatch( innerPredicate );
      }

Is there a better way to do it? I've not put up a PR, as I didn't know what to do about performance and memoization of the classHierarchy.

@codecholeric
Copy link
Collaborator

Sorry for the late reply! I don't think there is any better way right now. I guess a strict extends vs assignableTo could make sense 🤔 What's your concrete use case where you need this?

@u3r
Copy link
Contributor Author

u3r commented Jan 7, 2024

I usually use ArchUnit to test for dangerous or unwanted API use ;)
In this concrete case I actually test JUnit testcases for some parallelization edge cases that are QUITE hard to find otherwise:
No (UnitTest)classes should extend classes that define a @BeforeAll method and don't ... <some custom matching logic>
And if I use the assignableTo it obviously fails on most UnitTests defining a @BeforeAll as it includes this

I had this case on other occasions where I want to express don't do this strange stuff to OTHER classes/classes you inherit from - doing it to yourself is fine

Does that help?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants