Forbidden words
As the saying goes, naming things is one of the harder things in programming. I think there is a case to be made that naming things is pretty easy, but being consistent about naming things is pretty hard. When introducing a new concept in programming, I find myself using several different variants of a term in different places, even in the same merge request. Settling on a definition within your team or domain is one thing, but these naming rules need enforcement, at least in my case.
Well, there's a test for that! While it is evidently impossible to eliminate all wrong terms, it is possible to enforce the disuse of specific 'forbidden' words. This allows you to eliminate common terminology mistakes from your code base: Agreements on capitalisation, language used (in a non-English environment), et cetera. Enforcing (and by extension, documenting) terminology rules ultimately makes your code a little easier to understand.
The test below does just that. In this example, we have two forbidden words: eventtimestamp as well as eventTime. The correct variant for these is eventTimestamp. Any combination of words can be added.
I'm using Konsist (which will probably deserve a blog post of its own at some point), to retrieve the project root, but there are probably ways of doing that without introducing a library. AssertJ is used as the assertion library, which has a convenient withFailMessage method to be clear about what forbidden word is used where, and what the word should be.
class TypoArchTest {
val forbiddenWordMap = mapOf(
// pairs of what the word should be to what variants are not allowed
Pair("eventTimestamp", setOf("eventtimestamp", "eventTime")),
)
@Test
fun `the code should not contain any forbidden words`() {
File(Konsist.projectRootPath + "/app/src").walk().forEach { file ->
if (!file.isDirectory && file.name != this::class.simpleName + ".kt") {
forbiddenWordMap.forEach { (correct, forbiddenWords) ->
forbiddenWords.forEach { forbiddenWord ->
assertThat(file.readText())
.withFailMessage { "${file.name} contains forbidden word $forbiddenWord, moet zijn $correct" }
.doesNotContain(verbodenWoord)
}
}
}
}
}
}