bnorm / kotlin-power-assert

Kotlin compiler plugin to enable diagrammed function calls in the Kotlin programming language
Apache License 2.0
581 stars 15 forks source link

Infix transformation doesn't capture full context #99

Closed knizamov closed 7 months ago

knizamov commented 1 year ago

Hi, thanks for your great plugin.

Given infix function:

// some com.my.Assertions.kt file
infix fun <T> T.eq(expected: T) = assertEquals(this, expected)
fun <T> T.eq(expected: T, msg: String) {
    println(msg)
    assertEquals(this, expected)
}

class Tests {
  data class Person(val name: String, val age: Int, val address: Address?)
  data class Address(val street: String, val zipCode: Int)

  @Test
  fun test() {
    val person = Person(
        name = "Name",
        age = 30,
        address = Address(
            street = "street",
            zipCode = 1234,
        ),
    )

    person.address?.street eq "123"
  }
}

It captures only street, not full person.address?.street context:

street eq "123"
      |        |
      |        street
      Address(street=street, zipCode=1234)
Person(name=Name, age=30, address=Address(street=street, zipCode=1234))

While using assert(person.address?.street == "123") prints:

assert(person.address?.street == "123")
       |      |        |      |
       |      |        |      false
       |      |        street
       |      Address(street=street, zipCode=1234)
       Person(name=Name, age=30, address=Address(street=street, zipCode=1234))
bnorm commented 1 year ago

It does look like the person, address, and street information is all being captured and printed in your example but the information is not aligned properly because only street eq "123" is displayed. Probably a bug in the start offset for the expression. Thanks for the report!

bnorm commented 7 months ago

This compiler plugin is now bundled with Kotlin, starting with version 2.0.0-Beta5, where this issue has been fixed: https://youtrack.jetbrains.com/issue/KT-65640/PowerAssert-Infix-function-not-aligned-correctly.

import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi

plugins {
    kotlin("jvm") version "2.0.0-Beta5"
    kotlin("plugin.power-assert") version "2.0.0-Beta5"
}

@OptIn(ExperimentalKotlinGradlePluginApi::class)
powerAssert {
    functions = listOf("kotlin.assert", "kotlin.test.assertTrue")
    excludedSourceSets = listOf("main")
}