ceedee
09/21/2023, 8:14 AMKonsist
.scopeFromProject()
.assertArchitecture {
val domain = Layer("Domain", "com.myapp.features.feature01.domain..")
val data = Layer("Data", "com.myapp.features.feature01.data..")
domain.dependsOnNothing()
data.dependsOn(domain)
}
This approach requires me to create some kind of re-usable test where I can paramterize the package for the feature I want to test.
To foster a common project structure, I’d like to just write the test once, like I have only one Detekt configuration for the whole project.
But this would require me to define some kind of a baseline like I did for Detekt for dealing with the legacy codebase.
Is there a way to do this?
Also, I have an additional question regarding incremental development: consider the case that a feature is implemented layer by layer.
Then having a test which already requires the presentation layer will always fail and does not allow me to integrate the partial implementation into my codebase:
Konsist
.scopeFromProject()
.assertArchitecture {
val domain = Layer("Domain", "com.myapp.features.feature01.domain..")
val data = Layer("Data", "com.myapp.features.feature01.data..")
val presentation = Layer("Presentation", "com.myapp.features.feature01.presentation..")
domain.dependsOnNothing()
data.dependsOn(domain)
presentation.dependsOn(domain)
}
Is there a way to allow this kind of development, e.g. by making the presentation layer optional? Currently it throws com.lemonappdev.konsist.core.exception.KoPreconditionFailedException: Layer Presentation doesn't contain any files.
fun KoScope.removeWhitelistedItems(whitelist: List<String>): KoScope {
return slice { fileDeclaration ->
whitelist.none { whitelistedItem ->
fileDeclaration.name == whitelistedItem
}
}
}
using it likes this:
@Test
fun `companion object is last declaration in the class`() {
Konsist
.scopeFromProject()
.removeWhitelistedItems(KonsistBaseline.baselineForCompanionObjectIsNotLastDeclaration)
.classes()
.assert {
val companionObject = it.objects(includeNested = false).lastOrNull { obj ->
obj.hasModifier(KoModifier.COMPANION)
}
if (companionObject != null) {
it.declarations(includeNested = false, includeLocal = false).last() == companionObject
} else {
true
}
}
}
with
object KonsistBaseline {
val baselineForCompanionObjectIsNotLastDeclaration = listOf(
"ClassA",
"ClassB",
...
)
}
Also I have an extension function to create the baseline:
fun <T : KoBaseProvider> List<T>.printBaseline(
violationCriterion: (T) -> Boolean,
nameProvider: (T) -> String
): List<T> {
return print(prefix = "listOf(") {
if (violationCriterion(it)) {
"\"${nameProvider(it)}\","
} else {
""
}
}
}
That one is also not ideal since I need to add a call to it in my test which is repeating the validation of the test. Apart from that it adds many blank lines where the criterion is not violated.igor.wojda
09/21/2023, 7:52 PM