I'm currently trying to migrate my `ArchUnit` Test...
# konsist
p
I'm currently trying to migrate my
ArchUnit
Tests to
Konsist
to check if all requirements are fullfiled. How would you solve the following requirement: All classes that are not in a given package should not use a specified class (or in other words) depend on it.
Copy code
Konsist.scopeFromProduction()
            .files
            .filterNot { it.packagee?.fullyQualifiedName == "com.example.package" }
            .assertNot {
                it.imports.map { import -> import.name }.contains("com.example.package.TestClass")
            }
i
Try this
Copy code
Konsist
            .scopeFromProject()
            .classes()
            .withoutPackage("com.myapp")
            .assertNot { 
                it.containingFile.hasImports("com.unwantedimport") 
            }
BTW wildcard can be used in packages •
.withoutPackage("com.myapp")
-
com.myapp
package •
.withoutPackage("com.myapp..")
-
com.myapp
package and all subpackages https://docs.konsist.lemonappdev.com/features/packageselector
BTW I wonder how this will go for you. Please share your thoughts and overall feeling when you are done BTW2 actually this ArchUnit -> Konsist migration may provide interesting content for the article
💯 1
p
Perfect solution. This is working better as expected. I will share my thoughts as soon as I have migrated the remaining cases that are mainly related to the dependencies between packages inside a module (not between multiple modules).
❤️ 1
What I really like is the automatically caching of the classes so that it is not necessary to put the declaration outside of the test class to not impact performance ❤️
👍 1
At the moment the
hasImports
method is working for checking that there are a defined list of imports are used in the given file.
Copy code
override fun hasImports(vararg names: String): Boolean = when {
        names.isEmpty() -> imports.isNotEmpty()
        else -> names.all {
            imports.any { import -> LocationUtil.resideInLocation(it, import.name) }
        }
    }
But this does not work I want to use it to define something like "should only use imports or none", because in this case
imports.any
returns false and an assertion failure is returned. Is this intended?
My solution is something like
Copy code
fun KoFileDeclaration.hasOnlyImportsOrNone(vararg names: String): Boolean {
        if (this.imports.isEmpty()) {
            return true
        }
        return imports.all { import ->
            names.any { name ->
                LocationUtil.resideInLocation(name, import.name)
            }
        }
    }
i
We are working on improving declaration querying and verification APIs. I will take this feedback into consideration. You should see improved API with the next release targeted for latter this week
p
Thank you 👍 Until now the switch from ArchUnit is very smooth.
❤️ 1
n
We analysed this case in more detail and this seems to be the perfect case for the extension - Konsist tries to have flexible and extendable API, but we can’t add such methods as this will no scale well. That’s being said it look like the current API is flexible enough to support this case 🙂 BTW Consider filtering classes that have imports before
assert
, so check is only performed
hasImports
as classes that actually have imports
Copy code
.classes()
.withImports() 
.assert {
    it.hasImports("com.myapp")
}
p
Yes absolutely. I implemented my necessary cases as extension functions that work well for my requirements. I think it is not necessary to provide too much default functions. Better way is to provide an extensible API because the requirements are different.