+ * The project source directory gets extracted from the build configuration, and
+ * a pom.xml
or build.gradle
in the execution path is
+ * the default build configuration location. The configuration here is the same
+ * as the one in the structural tests and uses {@link AresConfiguration}.
+ *
+ * @return An unwanted simple recursion assertion object (for chaining)
+ */
+ public static UnwantedRecursionAssert assertThatProjectSources() {
+ var path = ProjectSourcesFinder.findProjectSourcesPath().orElseThrow(() -> //$NON-NLS-1$
+ new AssertionError("Could not find project sources folder." //$NON-NLS-1$
+ + " Make sure the build file is configured correctly." //$NON-NLS-1$
+ + " If it is not located in the execution folder directly," //$NON-NLS-1$
+ + " set the location using AresConfiguration methods.")); //$NON-NLS-1$
+ return new UnwantedRecursionAssert(path, null);
+ }
+
+ /**
+ * Creates an unwanted simple recursion node assertion object for all source files at and below
+ * the given directory path.
+ *
+ * @param directory Path to a directory under which all files are considered
+ * @return An unwanted simple recursion assertion object (for chaining)
+ */
+ public static UnwantedRecursionAssert assertThatSourcesIn(Path directory) {
+ Objects.requireNonNull(directory, "The given source path must not be null."); //$NON-NLS-1$
+ return new UnwantedRecursionAssert(directory, null);
+ }
+
+ /**
+ * Creates an unwanted simple recursion assertion object for all source files in the given
+ * package, including all of its sub-packages.
+ *
+ * @param packageName Java package name in the form of, e.g.,
+ * de.tum.in.test.api
, which is resolved
+ * relative to the path of this UnwantedNodesAssert.
+ * @return An unwanted simple recursion assertion object (for chaining)
+ * @implNote The package is split at "." with the resulting segments being
+ * interpreted as directory structure. So
+ * assertThatSourcesIn(Path.of("src/main/java")).withinPackage("net.example.test")
+ * will yield an assert for all source files located at and below the
+ * relative path src/main/java/net/example/test
+ */
+ public UnwantedRecursionAssert withinPackage(String packageName) {
+ Objects.requireNonNull(packageName, "The package name must not be null."); //$NON-NLS-1$
+ var newPath = actual.resolve(Path.of("", packageName.split("\\."))); //$NON-NLS-1$ //$NON-NLS-2$
+ return new UnwantedRecursionAssert(newPath, level, startingMethod, excludedMethods);
+ }
+
+ /**
+ * Configures the language level used by the Java parser
+ *
+ * @param level The language level for the Java parser
+ * @return An unwanted simple recursion assertion object (for chaining)
+ */
+ public UnwantedRecursionAssert withLanguageLevel(LanguageLevel level) {
+ return new UnwantedRecursionAssert(actual, level, startingMethod, excludedMethods);
+ }
+
+ /**
+ * Configures the method to start the recursion check from
+ * @param node The method to start the recursion check from
+ * @return An unwanted simple recursion assertion object (for chaining)
+ */
+ public UnwantedRecursionAssert startingWithMethod(Method node) {
+ return new UnwantedRecursionAssert(actual, level, node, excludedMethods);
+ }
+
+ public UnwantedRecursionAssert excludeMethods(Method... methods) {
+ return new UnwantedRecursionAssert(actual, level, startingMethod, methods);
+ }
+
+ /**
+ * Verifies that the selected Java files do not contain any recursion.
+ *
+ * @return This unwanted simple recursion assertion object (for chaining)
+ */
+ public UnwantedRecursionAssert hasNoRecursion() {
+ if (level == null) {
+ failWithMessage("The 'level' is not set. Please use UnwantedNodesAssert.withLanguageLevel(LanguageLevel)."); //$NON-NLS-1$
+ }
+ Optional