https://kotlinlang.org logo
#konsist
Title
# konsist
d

David

10/02/2023, 7:35 AM
Ran in to an issue with another one of my tests. I created this one to ensure we don't use any var properties inside a
data class
Copy code
class DataClasses {
    @Test
    fun `data classes use only immutable parameters`() {
        projectScope().classes(includeNested = true).withDataModifier().assert {
            it.properties(includeNested = false).none { property ->
                property.hasVarModifier
            }
        }
    }
}
However I hit an error on one of my classes:
Copy code
@Parcelize
data class Device(var prop1: String) :
    Parcelable {
        var prop2: String = ""

    override fun somefunction(): Int {
        var prop3 = ""
    }
}
It can properly find
prop1
,
prop2
but also finds
prop3
, any ideas how I can only get the top level variables? I would expect the
prop3
to be removed by
includeNested = false
but this does not seem to be the case.
👀 1
Found one solution, but I don't believe it is the nicest and it won't directly show me which property that failed:
Copy code
@Test
    fun `data classes use only immutable declarations`() {
        projectScope().classes(includeNested = true).withDataModifier().assert { koClassDeclaration
            ->
            koClassDeclaration
                .properties(includeNested = false)
                .filter { koClassDeclaration == it.containingDeclaration }
                .none { it.hasVarModifier }
                
        }
    }
I would be nice to be able to more easily get the direct decedents of a
Declaration
, instead of always getting all of them.
@igor.wojda I guess this test would be a nice addition to the General snippets
n

Natalia Peterwas

10/02/2023, 10:06 AM
Declarations inside functions and blocks are local by default, so the first test should work if you add
includeLocal = false
parameter to `properties()`:
Copy code
@Test
    fun `data classes use only immutable parameters`() {
        projectScope().classes(includeNested = true).withDataModifier().assert {
            it.properties(includeNested = false, includeLocal = false).none { property ->
                property.hasVarModifier
            }
        }
    }
Your version doesn’t work because you only exclude nested declarations (e.g. if you add a nested class inside the
Device
class and have some properties in it - they will be excluded). In this case we also need to exclude local declarations. Let me know if it works now 🙂
BTW you can update this test to have more precise error:
Copy code
@Test
    fun `data classes use only immutable declarations`() {
        getSnippetFile("test")
            .classes(includeNested = true)
            .withDataModifier()
            .properties(includeNested = false, includeLocal = false)
            .assertNot { it.hasVarModifier }
    }
Using this test, if an error occurs, the invalid properties will be displayed, not the class they are in.
d

David

10/02/2023, 11:22 AM
@Natalia Peterwas Thanks for the reply. I tried that before, but didn't get it to work initially, it then ignored
prop2
in my example above. However, now it seems to work fine, not sure if it was because I updated Konsist or some gradle sync issue (or error by me). Seems to work just fine now. 🙃 Also big thanks for your latest update, that makes it so much cleaner and the errors easier to read. Thanks! 🤗
🙌 1
❤️ 2
i

igor.wojda

10/02/2023, 2:01 PM
Thx a lot @David. Feedback like this is our rocket fuel 🚀 that drives our passion to make Konsist better
❤️ 1