From e346df26d3e0832f6cf13559dfb98f2a4c9a64e6 Mon Sep 17 00:00:00 2001 From: Brian Norman Date: Fri, 26 Nov 2021 14:02:24 -0600 Subject: [PATCH 1/4] Switch to JUnit 5 as test runner --- kotlin-power-assert-plugin/build.gradle.kts | 6 +++++- .../kotlin/com/bnorm/power/ArithmeticExpressionTest.kt | 2 +- .../test/kotlin/com/bnorm/power/AssertLibraryTest.kt | 10 +++++----- .../test/kotlin/com/bnorm/power/DebugFunctionTest.kt | 2 +- .../src/test/kotlin/com/bnorm/power/LamdaTest.kt | 2 +- .../com/bnorm/power/MultiParameterFunctionTest.kt | 2 +- .../src/test/kotlin/com/bnorm/power/RegexMatchTest.kt | 2 +- .../src/test/kotlin/com/bnorm/power/compiler.kt | 2 +- .../src/test/kotlin/com/bnorm/power/test.kt | 2 +- sample/build.gradle.kts | 6 +++++- 10 files changed, 22 insertions(+), 14 deletions(-) diff --git a/kotlin-power-assert-plugin/build.gradle.kts b/kotlin-power-assert-plugin/build.gradle.kts index eedd1cb82d7..8be2694da57 100644 --- a/kotlin-power-assert-plugin/build.gradle.kts +++ b/kotlin-power-assert-plugin/build.gradle.kts @@ -15,7 +15,7 @@ dependencies { kapt("com.google.auto.service:auto-service:1.0.1") compileOnly("com.google.auto.service:auto-service-annotations:1.0.1") - testImplementation(kotlin("test-junit")) + testImplementation(kotlin("test-junit5")) testImplementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.4.6") } @@ -24,6 +24,10 @@ tasks.withType { kotlinOptions.jvmTarget = "1.8" } +tasks.withType { + useJUnitPlatform() +} + tasks.dokka { outputFormat = "html" outputDirectory = "$buildDir/javadoc" diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/ArithmeticExpressionTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/ArithmeticExpressionTest.kt index 1b9c9c30ae4..54adad9f94b 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/ArithmeticExpressionTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/ArithmeticExpressionTest.kt @@ -16,7 +16,7 @@ package com.bnorm.power -import org.junit.Test +import kotlin.test.Test import kotlin.test.assertEquals class ArithmeticExpressionTest { diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertLibraryTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertLibraryTest.kt index 4f67a686e1f..adfd7dec779 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertLibraryTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertLibraryTest.kt @@ -16,8 +16,8 @@ package com.bnorm.power +import kotlin.test.Test import org.jetbrains.kotlin.name.FqName -import org.junit.Test class AssertLibraryTest { @Test @@ -111,7 +111,7 @@ class AssertLibraryTest { assertEquals(greeting, name) | | | World - Hello expected:<[Hello]> but was:<[World]> + Hello ==> expected: but was: """.trimIndent(), PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertEquals"))) ) @@ -133,7 +133,7 @@ class AssertLibraryTest { assertEquals(greeting, name, "Message:") | | | World - Hello expected:<[Hello]> but was:<[World]> + Hello ==> expected: but was: """.trimIndent(), PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertEquals"))) ) @@ -152,7 +152,7 @@ class AssertLibraryTest { """ assertNotNull(name) | - null + null ==> expected: not """.trimIndent(), PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertNotNull"))) ) @@ -172,7 +172,7 @@ class AssertLibraryTest { Message: assertNotNull(name, "Message:") | - null + null ==> expected: not """.trimIndent(), PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertNotNull"))) ) diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/DebugFunctionTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/DebugFunctionTest.kt index d720e3e744d..bf2c63669ea 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/DebugFunctionTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/DebugFunctionTest.kt @@ -19,10 +19,10 @@ package com.bnorm.power import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.SourceFile import org.jetbrains.kotlin.name.FqName -import org.junit.Test import java.io.ByteArrayOutputStream import java.io.PrintStream import java.lang.reflect.InvocationTargetException +import kotlin.test.Test import kotlin.test.assertEquals class DebugFunctionTest { diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/LamdaTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/LamdaTest.kt index 9e2dce2f85e..4769e631efa 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/LamdaTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/LamdaTest.kt @@ -16,8 +16,8 @@ package com.bnorm.power +import kotlin.test.Test import org.jetbrains.kotlin.name.FqName -import org.junit.Test class LamdaTest { @Test diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/MultiParameterFunctionTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/MultiParameterFunctionTest.kt index 1a2ce2b21d1..88072af6064 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/MultiParameterFunctionTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/MultiParameterFunctionTest.kt @@ -19,10 +19,10 @@ package com.bnorm.power import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.SourceFile import org.jetbrains.kotlin.name.FqName -import org.junit.Test import java.io.ByteArrayOutputStream import java.io.PrintStream import java.lang.reflect.InvocationTargetException +import kotlin.test.Test import kotlin.test.assertEquals class MultiParameterFunctionTest { diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/RegexMatchTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/RegexMatchTest.kt index 8207d6bfd29..ca23e36f646 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/RegexMatchTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/RegexMatchTest.kt @@ -16,7 +16,7 @@ package com.bnorm.power -import org.junit.Test +import kotlin.test.Test import kotlin.test.assertEquals class RegexMatchTest { diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/compiler.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/compiler.kt index cfc28e034e9..01570df154a 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/compiler.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/compiler.kt @@ -62,7 +62,7 @@ fun executeAssertion( } fail("should have thrown assertion") } catch (t: Throwable) { - return t.message!! + return t.message ?: "" } } diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt index 556305bea79..d8904dcea70 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt @@ -16,8 +16,8 @@ package com.bnorm.power +import kotlin.test.Test import org.jetbrains.kotlin.name.FqName -import org.junit.Test class CompilerTest { @Test diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts index 09de93c4719..da6a027d5b1 100644 --- a/sample/build.gradle.kts +++ b/sample/build.gradle.kts @@ -32,7 +32,7 @@ kotlin { } val jvmTest by getting { dependencies { - implementation(kotlin("test-junit")) + implementation(kotlin("test-junit5")) } } val jsTest by getting { @@ -49,6 +49,10 @@ kotlin { } } +tasks.withType { + useJUnitPlatform() +} + configure { functions = listOf( "kotlin.assert", From 479f37276c37c8db6440de7c293db980b54008c1 Mon Sep 17 00:00:00 2001 From: Brian Norman Date: Fri, 26 Nov 2021 14:37:56 -0600 Subject: [PATCH 2/4] Support Java Suppliers as message arguments --- .../bnorm/power/PowerAssertCallTransformer.kt | 50 +++-- .../SamConversionLambdaFunctionDelegate.kt | 47 ++++ .../internal/ReturnableBlockTransformer.kt | 98 --------- .../bnorm/power/{test.kt => AssertTest.kt} | 2 +- .../com/bnorm/power/Junit5AssertionsTest.kt | 201 ++++++++++++++++++ ...LibraryTest.kt => KotlinTestAssertTest.kt} | 2 +- 6 files changed, 284 insertions(+), 116 deletions(-) create mode 100644 kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SamConversionLambdaFunctionDelegate.kt delete mode 100644 kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/internal/ReturnableBlockTransformer.kt rename kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/{test.kt => AssertTest.kt} (99%) create mode 100644 kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt rename kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/{AssertLibraryTest.kt => KotlinTestAssertTest.kt} (99%) diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt index f3a838fe779..2216c7d36c3 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt @@ -18,6 +18,7 @@ package com.bnorm.power import com.bnorm.power.delegate.FunctionDelegate import com.bnorm.power.delegate.LambdaFunctionDelegate +import com.bnorm.power.delegate.SamConversionLambdaFunctionDelegate import com.bnorm.power.delegate.SimpleFunctionDelegate import com.bnorm.power.diagram.IrTemporaryVariable import com.bnorm.power.diagram.Node @@ -26,18 +27,15 @@ import com.bnorm.power.diagram.buildTree import com.bnorm.power.diagram.info import com.bnorm.power.diagram.irDiagramString import com.bnorm.power.diagram.substring -import com.bnorm.power.internal.ReturnableBlockTransformer import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext -import org.jetbrains.kotlin.backend.common.ir.asInlinable -import org.jetbrains.kotlin.backend.common.ir.inline import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.backend.js.utils.asString -import org.jetbrains.kotlin.ir.builders.irBlock +import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irString import org.jetbrains.kotlin.ir.builders.parent import org.jetbrains.kotlin.ir.declarations.IrFile @@ -46,20 +44,25 @@ import org.jetbrains.kotlin.ir.declarations.path import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation +import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrTypeArgument import org.jetbrains.kotlin.ir.types.IrTypeProjection import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl +import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.isBoolean import org.jetbrains.kotlin.ir.types.isSubtypeOf +import org.jetbrains.kotlin.ir.types.isSubtypeOfClass import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols +import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.ir.util.isFunctionOrKFunction import org.jetbrains.kotlin.ir.util.kotlinFqName -import org.jetbrains.kotlin.ir.util.patchDeclarationParents +import org.jetbrains.kotlin.ir.util.parentClassOrNull import org.jetbrains.kotlin.name.FqName class PowerAssertCallTransformer( @@ -122,10 +125,6 @@ class PowerAssertCallTransformer( val symbol = currentScope!!.scope.scopeOwnerSymbol val builder = DeclarationIrBuilder(context, symbol, expression.startOffset, expression.endOffset) return builder.diagram(expression, delegate, messageArgument, roots) -// .also { println(expression.dump()) } -// .also { println(it.dump()) } -// .also { println(expression.dumpKotlinLike()) } -// .also { println(it.dumpKotlinLike()) } } private fun DeclarationIrBuilder.diagram( @@ -163,12 +162,14 @@ class PowerAssertCallTransformer( return when { messageArgument is IrConst<*> -> messageArgument messageArgument is IrStringConcatenation -> messageArgument - messageArgument != null -> irBlock { - +messageArgument.deepCopyWithSymbols(parent) - .asInlinable(this) - .inline(parent) - .patchDeclarationParents(scope.getLocalDeclarationParent()) - }.transform(ReturnableBlockTransformer(context, scope.scopeOwnerSymbol), null) + messageArgument is IrFunctionExpression -> { + val invoke = messageArgument.type.classOrNull!!.functions + .filter { it.owner.name.toString() == "invoke" } + .single() + irCall(invoke).apply { dispatchReceiver = messageArgument } + } + // SAMs conversion can be unwrapped to IrFunctionExpression + messageArgument is IrTypeOperatorCall -> buildMessagePrefix(messageArgument.argument, roots, original) // TODO what should the default message be? roots.size == 1 && original.getValueArgument(0)!!.type.isBoolean() -> irString("Assertion failed") else -> null @@ -179,7 +180,16 @@ class PowerAssertCallTransformer( val values = function.valueParameters if (values.isEmpty()) return emptyList() - return context.referenceFunctions(function.kotlinFqName) + // Java static functions require searching by class + val parentClassFunctions = (function.parentClassOrNull + ?.let { context.referenceClass(it.kotlinFqName) } + ?.functions ?: emptySequence()) + .filter { it.owner.kotlinFqName == function.kotlinFqName } + .toList() + val possible = (context.referenceFunctions(function.kotlinFqName) + parentClassFunctions) + .distinct() + + return possible .mapNotNull { overload -> val parameters = overload.owner.valueParameters if (parameters.size !in values.size..values.size + 1) return@mapNotNull null @@ -191,6 +201,8 @@ class PowerAssertCallTransformer( return@mapNotNull when { isStringSupertype(messageParameter.type) -> SimpleFunctionDelegate(overload) isStringFunction(messageParameter.type) -> LambdaFunctionDelegate(overload, messageParameter) + isStringJavaSupplierFunction(messageParameter.type) -> + SamConversionLambdaFunctionDelegate(overload, messageParameter) else -> null } } @@ -199,6 +211,12 @@ class PowerAssertCallTransformer( private fun isStringFunction(type: IrType): Boolean = type.isFunctionOrKFunction() && type is IrSimpleType && (type.arguments.size == 1 && isStringSupertype(type.arguments.first())) + private fun isStringJavaSupplierFunction(type: IrType): Boolean { + val javaSupplier = context.referenceClass(FqName("java.util.function.Supplier")) + return javaSupplier != null && type.isSubtypeOfClass(javaSupplier) + && type is IrSimpleType && (type.arguments.size == 1 && isStringSupertype(type.arguments.first())) + } + private fun isStringSupertype(argument: IrTypeArgument): Boolean = argument is IrTypeProjection && isStringSupertype(argument.type) diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SamConversionLambdaFunctionDelegate.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SamConversionLambdaFunctionDelegate.kt new file mode 100644 index 00000000000..5fca3ad1fdf --- /dev/null +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SamConversionLambdaFunctionDelegate.kt @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 Brian Norman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bnorm.power.delegate + +import com.bnorm.power.irLambda +import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope +import org.jetbrains.kotlin.ir.builders.irReturn +import org.jetbrains.kotlin.ir.builders.typeOperator +import org.jetbrains.kotlin.ir.declarations.IrValueParameter +import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrTypeOperator +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol + +class SamConversionLambdaFunctionDelegate( + private val overload: IrSimpleFunctionSymbol, + private val messageParameter: IrValueParameter +) : FunctionDelegate { + override val function = overload.owner + + override fun buildCall( + builder: IrBuilderWithScope, + original: IrCall, + arguments: List, + message: IrExpression + ): IrExpression = with(builder) { + val lambda = irLambda(context.irBuiltIns.stringType, messageParameter.type) { + +irReturn(message) + } + val expression = typeOperator(messageParameter.type, lambda, IrTypeOperator.SAM_CONVERSION, messageParameter.type) + irCallCopy(overload, original, arguments, expression) + } +} diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/internal/ReturnableBlockTransformer.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/internal/ReturnableBlockTransformer.kt deleted file mode 100644 index f5df2377e6e..00000000000 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/internal/ReturnableBlockTransformer.kt +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - * - * Copied from https://github.com/JetBrains/kotlin/blob/1.4.20/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ReturnableBlockLowering.kt - */ - -package com.bnorm.power.internal - -import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext -import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder -import org.jetbrains.kotlin.backend.common.lower.irComposite -import org.jetbrains.kotlin.ir.builders.* -import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.expressions.impl.* -import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol -import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.transformStatement - -// TODO Remove when inlining works correctly on Kotlin/JS and Kotlin/Native -class ReturnableBlockTransformer(val context: IrGeneratorContext, val containerSymbol: IrSymbol? = null) : IrElementTransformerVoidWithContext() { - private var labelCnt = 0 - private val returnMap = mutableMapOf IrExpression>() - - override fun visitReturn(expression: IrReturn): IrExpression { - expression.transformChildrenVoid() - return returnMap[expression.returnTargetSymbol]?.invoke(expression) ?: expression - } - - override fun visitContainerExpression(expression: IrContainerExpression): IrExpression { - if (expression !is IrReturnableBlock) return super.visitContainerExpression(expression) - - val scopeSymbol = currentScope?.scope?.scopeOwnerSymbol ?: containerSymbol - val builder = DeclarationIrBuilder(context, scopeSymbol!!) - val variable by lazy { - builder.scope.createTmpVariable(expression.type, "tmp\$ret\$${labelCnt++}", true) - } - - val loop by lazy { - IrDoWhileLoopImpl( - expression.startOffset, - expression.endOffset, - context.irBuiltIns.unitType, - expression.origin - ).apply { - label = "l\$ret\$${labelCnt++}" - condition = builder.irBoolean(false) - } - } - - var hasReturned = false - - returnMap[expression.symbol] = { returnExpression -> - hasReturned = true - builder.irComposite(returnExpression) { - +irSet(variable.symbol, returnExpression.value) - +irBreak(loop) - } - } - - val newStatements = expression.statements.mapIndexed { i, s -> - if (i == expression.statements.lastIndex && s is IrReturn && s.returnTargetSymbol == expression.symbol) { - s.transformChildrenVoid() - if (!hasReturned) s.value else { - builder.irSet(variable.symbol, s.value) - } - } else { - s.transformStatement(this) - } - } - - returnMap.remove(expression.symbol) - - if (!hasReturned) { - return IrCompositeImpl( - expression.startOffset, - expression.endOffset, - expression.type, - expression.origin, - newStatements - ) - } else { - loop.body = IrBlockImpl( - expression.startOffset, - expression.endOffset, - context.irBuiltIns.unitType, - expression.origin, - newStatements - ) - - return builder.irComposite(expression, expression.origin) { - +variable - +loop - +irGet(variable) - } - } - } -} diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt similarity index 99% rename from kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt rename to kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt index d8904dcea70..6a04e851d5b 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt @@ -19,7 +19,7 @@ package com.bnorm.power import kotlin.test.Test import org.jetbrains.kotlin.name.FqName -class CompilerTest { +class AssertTest { @Test fun memberFunctions() { assertMessage( diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt new file mode 100644 index 00000000000..f584fd634d5 --- /dev/null +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2021 Brian Norman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bnorm.power + +import kotlin.test.Test +import org.jetbrains.kotlin.name.FqName + +class Junit5AssertionsTest { + @Test + fun `test JUnit5 Assertions#assertTrue transformation`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertTrue + + fun main() { + assertTrue(1 != 1) + }""", + """ + Assertion failed + assertTrue(1 != 1) + | + false ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertTrue"))) + ) + } + + @Test + fun `test JUnit5 Assertions#assertTrue transformation with message`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertTrue + + fun main() { + assertTrue(1 != 1, "Message:") + }""", + """ + Message: + assertTrue(1 != 1, "Message:") + | + false ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertTrue"))) + ) + } + + @Test + fun `test JUnit5 Assertions#assertTrue transformation with message supplier`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertTrue + + fun main() { + assertTrue(1 != 1) { "Message:" } + }""", + """ + Message: + assertTrue(1 != 1) { "Message:" } + | + false ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertTrue"))) + ) + } + + @Test + fun `test JUnit5 Assertions#assertFalse transformation`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertFalse + + fun main() { + assertFalse(1 == 1) + }""", + """ + Assertion failed + assertFalse(1 == 1) + | + true ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertFalse"))) + ) + } + + @Test + fun `test JUnit5 Assertions#assertFalse transformation with message`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertFalse + + fun main() { + assertFalse(1 == 1, "Message:") + }""", + """ + Message: + assertFalse(1 == 1, "Message:") + | + true ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertFalse"))) + ) + } + + @Test + fun `test JUnit5 Assertions#assertFalse transformation with message supplier`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertFalse + + fun main() { + assertFalse(1 == 1) { "Message:" } + }""", + """ + Message: + assertFalse(1 == 1) { "Message:" } + | + true ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertFalse"))) + ) + } + + @Test + fun `test JUnit5 Assertions#assertEquals transformation`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertEquals + + fun main() { + val greeting = "Hello" + val name = "World" + assertEquals(greeting, name) + }""", + """ + assertEquals(greeting, name) + | | + | World + Hello ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertEquals"))) + ) + } + + @Test + fun `test JUnit5 Assertions#assertEquals transformation with message`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertEquals + + fun main() { + val greeting = "Hello" + val name = "World" + assertEquals(greeting, name, "Message:") + }""", + """ + Message: + assertEquals(greeting, name, "Message:") + | | + | World + Hello ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertEquals"))) + ) + } + + @Test + fun `test JUnit5 Assertions#assertEquals transformation with message supplier`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertEquals + + fun main() { + val greeting = "Hello" + val name = "World" + assertEquals(greeting, name) { "Message:" } + }""", + """ + Message: + assertEquals(greeting, name) { "Message:" } + | | + | World + Hello ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertEquals"))) + ) + } +} diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertLibraryTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt similarity index 99% rename from kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertLibraryTest.kt rename to kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt index adfd7dec779..ec6b3a0205e 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertLibraryTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt @@ -19,7 +19,7 @@ package com.bnorm.power import kotlin.test.Test import org.jetbrains.kotlin.name.FqName -class AssertLibraryTest { +class KotlinTestAssertTest { @Test fun `test assertTrue transformation`() { assertMessage( From 2179d1e80a01e9dbb264e1510f737d324a4bed95 Mon Sep 17 00:00:00 2001 From: Brian Norman Date: Fri, 26 Nov 2021 15:09:26 -0600 Subject: [PATCH 3/4] Support message lambda as a local variable --- .../bnorm/power/PowerAssertCallTransformer.kt | 27 +++- .../bnorm/power/delegate/FunctionDelegate.kt | 3 + .../power/delegate/LambdaFunctionDelegate.kt | 2 +- .../SamConversionLambdaFunctionDelegate.kt | 2 +- .../power/delegate/SimpleFunctionDelegate.kt | 4 +- .../test/kotlin/com/bnorm/power/AssertTest.kt | 17 +++ .../com/bnorm/power/Junit5AssertionsTest.kt | 129 ++++++++++++++++++ .../com/bnorm/power/KotlinTestAssertTest.kt | 84 ++++++++++++ 8 files changed, 258 insertions(+), 10 deletions(-) diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt index 2216c7d36c3..f0622578ccc 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt @@ -40,11 +40,13 @@ import org.jetbrains.kotlin.ir.builders.irString import org.jetbrains.kotlin.ir.builders.parent import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.declarations.path import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression +import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol @@ -137,7 +139,8 @@ class PowerAssertCallTransformer( variables: List = listOf() ): IrExpression { if (index >= roots.size) { - val prefix = buildMessagePrefix(messageArgument, roots, original)?.deepCopyWithSymbols(parent) + val prefix = buildMessagePrefix(messageArgument, delegate.messageParameter, roots, original) + ?.deepCopyWithSymbols(parent) val diagram = irDiagramString(file, fileSource, prefix, original, variables) return delegate.buildCall(this, original, arguments, diagram) } else { @@ -156,20 +159,30 @@ class PowerAssertCallTransformer( private fun DeclarationIrBuilder.buildMessagePrefix( messageArgument: IrExpression?, + messageParameter: IrValueParameter, roots: List, original: IrCall ): IrExpression? { return when { messageArgument is IrConst<*> -> messageArgument messageArgument is IrStringConcatenation -> messageArgument - messageArgument is IrFunctionExpression -> { - val invoke = messageArgument.type.classOrNull!!.functions - .filter { it.owner.name.toString() == "invoke" } + messageArgument is IrGetValue -> { + if (messageArgument.type.isAssignableTo(context.irBuiltIns.stringType)) { + return messageArgument + } else { + val invoke = messageParameter.type.classOrNull!!.functions + .filter { !it.owner.isFakeOverride } // TODO best way to find single access method? + .single() + irCall(invoke).apply { dispatchReceiver = messageArgument } + } + } + // Kotlin Lambda or SAMs conversion lambda + messageArgument is IrFunctionExpression || messageArgument is IrTypeOperatorCall -> { + val invoke = messageParameter.type.classOrNull!!.functions + .filter { !it.owner.isFakeOverride } // TODO best way to find single access method? .single() irCall(invoke).apply { dispatchReceiver = messageArgument } } - // SAMs conversion can be unwrapped to IrFunctionExpression - messageArgument is IrTypeOperatorCall -> buildMessagePrefix(messageArgument.argument, roots, original) // TODO what should the default message be? roots.size == 1 && original.getValueArgument(0)!!.type.isBoolean() -> irString("Assertion failed") else -> null @@ -199,7 +212,7 @@ class PowerAssertCallTransformer( val messageParameter = parameters.last() return@mapNotNull when { - isStringSupertype(messageParameter.type) -> SimpleFunctionDelegate(overload) + isStringSupertype(messageParameter.type) -> SimpleFunctionDelegate(overload, messageParameter) isStringFunction(messageParameter.type) -> LambdaFunctionDelegate(overload, messageParameter) isStringJavaSupplierFunction(messageParameter.type) -> SamConversionLambdaFunctionDelegate(overload, messageParameter) diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt index 956527f47b8..6efda54ba8f 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt @@ -20,6 +20,8 @@ import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.parent import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrValueParameter +import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol @@ -27,6 +29,7 @@ import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols interface FunctionDelegate { val function: IrFunction + val messageParameter: IrValueParameter fun buildCall( builder: IrBuilderWithScope, diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/LambdaFunctionDelegate.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/LambdaFunctionDelegate.kt index d18bab6df73..b2db4479aca 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/LambdaFunctionDelegate.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/LambdaFunctionDelegate.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol class LambdaFunctionDelegate( private val overload: IrSimpleFunctionSymbol, - private val messageParameter: IrValueParameter + override val messageParameter: IrValueParameter, ) : FunctionDelegate { override val function = overload.owner diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SamConversionLambdaFunctionDelegate.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SamConversionLambdaFunctionDelegate.kt index 5fca3ad1fdf..62e1a6da3bf 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SamConversionLambdaFunctionDelegate.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SamConversionLambdaFunctionDelegate.kt @@ -28,7 +28,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol class SamConversionLambdaFunctionDelegate( private val overload: IrSimpleFunctionSymbol, - private val messageParameter: IrValueParameter + override val messageParameter: IrValueParameter, ) : FunctionDelegate { override val function = overload.owner diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SimpleFunctionDelegate.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SimpleFunctionDelegate.kt index 186da244b66..9e82956565c 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SimpleFunctionDelegate.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SimpleFunctionDelegate.kt @@ -17,12 +17,14 @@ package com.bnorm.power.delegate import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope +import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol class SimpleFunctionDelegate( - private val overload: IrSimpleFunctionSymbol + private val overload: IrSimpleFunctionSymbol, + override val messageParameter: IrValueParameter, ) : FunctionDelegate { override val function = overload.owner diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt index 6a04e851d5b..1294ef8e526 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt @@ -77,6 +77,23 @@ assert(1 == 2) { "Not equal" } ) } + @Test + fun customLocalVariableMessage() { + assertMessage( + """ +fun main() { + val lambda = { "Not equal" } + assert(1 == 2, lambda) +}""", + """ +Not equal +assert(1 == 2, lambda) + | + false +""".trimIndent() + ) + } + @Test fun booleanExpressionsShortCircuit() { assertMessage( diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt index f584fd634d5..2fedb0a5867 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt @@ -58,6 +58,26 @@ class Junit5AssertionsTest { ) } + @Test + fun `test JUnit5 Assertions#assertTrue transformation with local variable message`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertTrue + + fun main() { + val message = "Message:" + assertTrue(1 != 1, message) + }""", + """ + Message: + assertTrue(1 != 1, message) + | + false ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertTrue"))) + ) + } + @Test fun `test JUnit5 Assertions#assertTrue transformation with message supplier`() { assertMessage( @@ -77,6 +97,27 @@ class Junit5AssertionsTest { ) } + @Test + fun `test JUnit5 Assertions#assertTrue transformation with local variable message supplier`() { + assertMessage( + """ + import java.util.function.Supplier + import org.junit.jupiter.api.Assertions.assertTrue + + fun main() { + val supplier = Supplier { "Message:" } + assertTrue(1 != 1, supplier) + }""", + """ + Message: + assertTrue(1 != 1, supplier) + | + false ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertTrue"))) + ) + } + @Test fun `test JUnit5 Assertions#assertFalse transformation`() { assertMessage( @@ -115,6 +156,26 @@ class Junit5AssertionsTest { ) } + @Test + fun `test JUnit5 Assertions#assertFalse transformation with local variable message`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertFalse + + fun main() { + val message = "Message:" + assertFalse(1 == 1, message) + }""", + """ + Message: + assertFalse(1 == 1, message) + | + true ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertFalse"))) + ) + } + @Test fun `test JUnit5 Assertions#assertFalse transformation with message supplier`() { assertMessage( @@ -134,6 +195,27 @@ class Junit5AssertionsTest { ) } + @Test + fun `test JUnit5 Assertions#assertFalse transformation with local variable message supplier`() { + assertMessage( + """ + import java.util.function.Supplier + import org.junit.jupiter.api.Assertions.assertFalse + + fun main() { + val supplier = Supplier { "Message:" } + assertFalse(1 == 1, supplier) + }""", + """ + Message: + assertFalse(1 == 1, supplier) + | + true ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertFalse"))) + ) + } + @Test fun `test JUnit5 Assertions#assertEquals transformation`() { assertMessage( @@ -177,6 +259,29 @@ class Junit5AssertionsTest { ) } + @Test + fun `test JUnit5 Assertions#assertEquals transformation with local variable message`() { + assertMessage( + """ + import org.junit.jupiter.api.Assertions.assertEquals + + fun main() { + val greeting = "Hello" + val name = "World" + val message = "Message:" + assertEquals(greeting, name, message) + }""", + """ + Message: + assertEquals(greeting, name, message) + | | + | World + Hello ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertEquals"))) + ) + } + @Test fun `test JUnit5 Assertions#assertEquals transformation with message supplier`() { assertMessage( @@ -198,4 +303,28 @@ class Junit5AssertionsTest { PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertEquals"))) ) } + + @Test + fun `test JUnit5 Assertions#assertEquals transformation with local variable message supplier`() { + assertMessage( + """ + import java.util.function.Supplier + import org.junit.jupiter.api.Assertions.assertEquals + + fun main() { + val greeting = "Hello" + val name = "World" + val supplier = Supplier { "Message:" } + assertEquals(greeting, name, supplier) + }""", + """ + Message: + assertEquals(greeting, name, supplier) + | | + | World + Hello ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("org.junit.jupiter.api.Assertions.assertEquals"))) + ) + } } diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt index ec6b3a0205e..0cba082e92c 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt @@ -58,6 +58,26 @@ class KotlinTestAssertTest { ) } + @Test + fun `test assertTrue transformation with local variable message`() { + assertMessage( + """ + import kotlin.test.assertTrue + + fun main() { + val message = "Message:" + assertTrue(1 != 1, message) + }""", + """ + Message: + assertTrue(1 != 1, message) + | + false + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertTrue"))) + ) + } + @Test fun `test assertFalse transformation`() { assertMessage( @@ -96,6 +116,26 @@ class KotlinTestAssertTest { ) } + @Test + fun `test assertFalse transformation with local variable message`() { + assertMessage( + """ + import kotlin.test.assertFalse + + fun main() { + val message = "Message:" + assertFalse(1 == 1, message) + }""", + """ + Message: + assertFalse(1 == 1, message) + | + true + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertFalse"))) + ) + } + @Test fun `test assertEquals transformation`() { assertMessage( @@ -139,6 +179,29 @@ class KotlinTestAssertTest { ) } + @Test + fun `test assertEquals transformation with local variable message`() { + assertMessage( + """ + import kotlin.test.assertEquals + + fun main() { + val greeting = "Hello" + val name = "World" + val message = "Message:" + assertEquals(greeting, name, message) + }""", + """ + Message: + assertEquals(greeting, name, message) + | | + | World + Hello ==> expected: but was: + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertEquals"))) + ) + } + @Test fun `test assertNotNull transformation`() { assertMessage( @@ -177,4 +240,25 @@ class KotlinTestAssertTest { PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertNotNull"))) ) } + + @Test + fun `test assertNotNull transformation with local variable message`() { + assertMessage( + """ + import kotlin.test.assertNotNull + + fun main() { + val name: String? = null + val message = "Message:" + assertNotNull(name, message) + }""", + """ + Message: + assertNotNull(name, message) + | + null ==> expected: not + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertNotNull"))) + ) + } } From c6c383041874f7921b667003a987f219a39530ab Mon Sep 17 00:00:00 2001 From: Brian Norman Date: Fri, 26 Nov 2021 15:53:57 -0600 Subject: [PATCH 4/4] ktlint errors --- .editorconfig | 7 +++++++ .../com/bnorm/power/PowerAssertCallTransformer.kt | 12 +++++++----- .../com/bnorm/power/delegate/FunctionDelegate.kt | 1 - .../src/test/kotlin/com/bnorm/power/AssertTest.kt | 12 ++++++------ .../kotlin/com/bnorm/power/Junit5AssertionsTest.kt | 2 +- .../kotlin/com/bnorm/power/KotlinTestAssertTest.kt | 2 +- .../src/test/kotlin/com/bnorm/power/LamdaTest.kt | 2 +- 7 files changed, 23 insertions(+), 15 deletions(-) diff --git a/.editorconfig b/.editorconfig index 03e22d69f1b..78092e35a49 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,16 @@ root = true [*] +charset = utf-8 end_of_line = lf insert_final_newline = true [*.{kt,kts}] indent_style = space indent_size = 2 + +ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL +ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ +ij_kotlin_name_count_to_use_star_import = 2147483647 +ij_kotlin_name_count_to_use_star_import_for_members = 2147483647 +ij_kotlin_packages_to_use_import_on_demand = unset diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt index f0622578ccc..7e4567a8e3c 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt @@ -194,9 +194,11 @@ class PowerAssertCallTransformer( if (values.isEmpty()) return emptyList() // Java static functions require searching by class - val parentClassFunctions = (function.parentClassOrNull - ?.let { context.referenceClass(it.kotlinFqName) } - ?.functions ?: emptySequence()) + val parentClassFunctions = ( + function.parentClassOrNull + ?.let { context.referenceClass(it.kotlinFqName) } + ?.functions ?: emptySequence() + ) .filter { it.owner.kotlinFqName == function.kotlinFqName } .toList() val possible = (context.referenceFunctions(function.kotlinFqName) + parentClassFunctions) @@ -226,8 +228,8 @@ class PowerAssertCallTransformer( private fun isStringJavaSupplierFunction(type: IrType): Boolean { val javaSupplier = context.referenceClass(FqName("java.util.function.Supplier")) - return javaSupplier != null && type.isSubtypeOfClass(javaSupplier) - && type is IrSimpleType && (type.arguments.size == 1 && isStringSupertype(type.arguments.first())) + return javaSupplier != null && type.isSubtypeOfClass(javaSupplier) && + type is IrSimpleType && (type.arguments.size == 1 && isStringSupertype(type.arguments.first())) } private fun isStringSupertype(argument: IrTypeArgument): Boolean = diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt index 6efda54ba8f..f0cb155ae77 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.parent import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrValueParameter -import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt index 1294ef8e526..a4726792610 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertTest.kt @@ -16,8 +16,8 @@ package com.bnorm.power -import kotlin.test.Test import org.jetbrains.kotlin.name.FqName +import kotlin.test.Test class AssertTest { @Test @@ -86,11 +86,11 @@ fun main() { assert(1 == 2, lambda) }""", """ -Not equal -assert(1 == 2, lambda) - | - false -""".trimIndent() + Not equal + assert(1 == 2, lambda) + | + false + """.trimIndent() ) } diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt index 2fedb0a5867..a95873a1073 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/Junit5AssertionsTest.kt @@ -16,8 +16,8 @@ package com.bnorm.power -import kotlin.test.Test import org.jetbrains.kotlin.name.FqName +import kotlin.test.Test class Junit5AssertionsTest { @Test diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt index 0cba082e92c..5032dcee952 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/KotlinTestAssertTest.kt @@ -16,8 +16,8 @@ package com.bnorm.power -import kotlin.test.Test import org.jetbrains.kotlin.name.FqName +import kotlin.test.Test class KotlinTestAssertTest { @Test diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/LamdaTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/LamdaTest.kt index 4769e631efa..763dc1f90ae 100644 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/LamdaTest.kt +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/LamdaTest.kt @@ -16,8 +16,8 @@ package com.bnorm.power -import kotlin.test.Test import org.jetbrains.kotlin.name.FqName +import kotlin.test.Test class LamdaTest { @Test