https://kotlinlang.org logo
#getting-started
Title
# getting-started
l

Lukasz Kalnik

07/18/2022, 9:33 AM
Is there an online tool to pretty print the
data class
toString()
output? I have a lot of nested data classes and when a test fails it's quite cumbersome to compare the linear outputs of the standard
toString()
implementation of a data class.
j

Joffrey

07/18/2022, 9:34 AM
Did you try to compare within IntelliJ? AFAIR you can enable soft wraps and see a nice diff
But otherwise, no, I don't know of any such pretty printer
l

Lukasz Kalnik

07/18/2022, 9:35 AM
Yes, I have soft wraps activated and I compare in IntelliJ, but it looks like this:
Copy code
org.opentest4j.AssertionFailedError: 
expected: SensorAutomationScreenState(isEditMode=false, name=, connectorsWithSensors=[ConnectorWithSensors(connectorInfo=Connector(id=controlDeviceConnectorId1, name=controlDeviceConnectorName1, productType=AIR), sensors=[ItemSelection(id=controlDeviceId1, name=controlDeviceName1, selected=true, enabled=true), ItemSelection(id=controlDeviceId2, name=controlDeviceName2, selected=true, enabled=true)]), ConnectorWithSensors(connectorInfo=Connector(id=controlDeviceConnectorId2, name=controlDeviceConnectorName2, productType=AIR), sensors=[ItemSelection(id=controlDeviceId3, name=controlDeviceName3, selected=false, enabled=true)])], time=ANYTIME, scenes=Scenes(supportedScenes=[ItemSelection(id=sceneId2, name=sceneName2, selected=false, enabled=true)], unsupportedScenes=[ItemSelection(id=sceneId1, name=sceneName1, selected=false, enabled=false), ItemSelection(id=sceneId3, name=sceneName3, selected=false, enabled=true), ItemSelection(id=sceneId4, name=sceneName4, selected=false, enabled=false)]), noMotionScenes=Scenes(supportedScenes=[ItemSelection(id=sceneId2, name=sceneName2, selected=false, enabled=true)], unsupportedScenes=[ItemSelection(id=sceneId1, name=sceneName1, selected=false, enabled=false), ItemSelection(id=sceneId3, name=sceneName3, selected=false, enabled=true), ItemSelection(id=sceneId4, name=sceneName4, selected=false, enabled=false)]), noMotionDelay=5, isSaveButtonEnabled=false, showDeleteButton=false, showConfirmDeleteAutomationDialog=false, location=null, showNotSupportedScenes=false, showNotSupportedNoMotionScenes=false, sceneNotSupportedDialogState=SceneNotSupportedDialogState(show=false, sceneNames=))
 but was: SensorAutomationScreenState(isEditMode=false, name=, connectorsWithSensors=[ConnectorWithSensors(connectorInfo=Connector(id=controlDeviceConnectorId1, name=controlDeviceConnectorName1, productType=AIR), sensors=[ItemSelection(id=controlDeviceId1, name=controlDeviceName1, selected=true, enabled=true), ItemSelection(id=controlDeviceId2, name=controlDeviceName2, selected=true, enabled=true)]), ConnectorWithSensors(connectorInfo=Connector(id=controlDeviceConnectorId2, name=controlDeviceConnectorName2, productType=AIR), sensors=[ItemSelection(id=controlDeviceId3, name=controlDeviceName3, selected=false, enabled=false)])], time=ANYTIME, scenes=Scenes(supportedScenes=[ItemSelection(id=sceneId2, name=sceneName2, selected=false, enabled=true)], unsupportedScenes=[ItemSelection(id=sceneId1, name=sceneName1, selected=false, enabled=false), ItemSelection(id=sceneId3, name=sceneName3, selected=false, enabled=false), ItemSelection(id=sceneId4, name=sceneName4, selected=false, enabled=false)]), noMotionScenes=Scenes(supportedScenes=[ItemSelection(id=sceneId2, name=sceneName2, selected=false, enabled=true)], unsupportedScenes=[ItemSelection(id=sceneId1, name=sceneName1, selected=false, enabled=false), ItemSelection(id=sceneId3, name=sceneName3, selected=false, enabled=false), ItemSelection(id=sceneId4, name=sceneName4, selected=false, enabled=false)]), noMotionDelay=5, isSaveButtonEnabled=false, showDeleteButton=false, showConfirmDeleteAutomationDialog=false, location=null, showNotSupportedScenes=false, showNotSupportedNoMotionScenes=false, sceneNotSupportedDialogState=SceneNotSupportedDialogState(show=false, sceneNames=))
j

Joffrey

07/18/2022, 9:37 AM
I get this in IDEA:
You can clearly see the problem with 3 booleans
Sometimes in the test failure message you have a "compare" link that opens this kind of comparison window. However, I don't always see it, and I haven't figured out in which case I get it. It might depend on the assertion library.
l

Lukasz Kalnik

07/18/2022, 9:39 AM
I use AssertJ
👌 1
But thanks for the hint, I just copy-pasted it into a Blank Diff Window and see the difference. This is a really nice tip, thank you for your help!
👍 1
o

Oliver.O

07/18/2022, 10:31 AM
You could also try https://github.com/bnorm/kotlin-power-assert or (if your classes can be made
@Serializable
for kotlinx.serialization) serialize them with
Json { prettyPrint = true }
and use the result for printing.
1
🙏 1
v

Vampire

07/18/2022, 12:43 PM
Sometimes in the test failure message you have a "compare" link that opens this kind of comparison window. However, I don't always see it, and I haven't figured out in which case I get it. It might depend on the assertion library.
@Joffrey yes and no. The exceptions have to be of a certain subtype for the compare link to appear, but usually assertion libraries should match that criteria. The most often cause is, that you delegeat test execution to Gradle where the compare tool integration is broken as the exceptions get changed on the fly unfortunately. If you use the IntelliJ test runner, the compare tool integration works, but you might miss important configuration for the test task in the build script. https://youtrack.jetbrains.com/issue/IDEA-221624/No-diff-tool-integration-when-delegating-tests-to-Gradle
j

Joffrey

07/18/2022, 12:47 PM
@Vampire oh thanks! Now I finally know why (somehow I didn't care enough to Google it for long 😅). Yeah I usually set up IDEA to run tests using Gradle in order to match the actual configuration, and not have surprises on the CI
2 Views