From b4ce1c12b6700f9426d1332027e6e02db2e39959 Mon Sep 17 00:00:00 2001 From: Brian Norman Date: Sat, 24 Apr 2021 12:31:26 -0500 Subject: [PATCH] Cleanup and additional tests --- .../bnorm/power/PowerAssertCallTransformer.kt | 187 +++++------------- .../bnorm/power/delegate/FunctionDelegate.kt | 56 ++++++ .../power/delegate/LambdaFunctionDelegate.kt | 44 +++++ .../power/delegate/SimpleFunctionDelegate.kt | 39 ++++ .../power/diagram/IrTemporaryVariable.kt | 16 ++ .../main/kotlin/com/bnorm/power/irUtils.kt | 51 +++++ .../bnorm/power/ArithmeticExpressionTest.kt | 16 ++ .../com/bnorm/power/AssertBooleanTest.kt | 44 ----- .../com/bnorm/power/AssertLibraryTest.kt | 180 +++++++++++++++++ .../com/bnorm/power/DebugFunctionTest.kt | 16 ++ .../bnorm/power/MultiParameterFunctionTest.kt | 16 ++ .../kotlin/com/bnorm/power/RegexMatchTest.kt | 16 ++ .../test/kotlin/com/bnorm/power/compiler.kt | 16 ++ 13 files changed, 517 insertions(+), 180 deletions(-) create mode 100644 kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt create mode 100644 kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/LambdaFunctionDelegate.kt create mode 100644 kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SimpleFunctionDelegate.kt delete mode 100644 kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertBooleanTest.kt create mode 100644 kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertLibraryTest.kt 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 4b9be5b2d84..28153473382 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 @@ -16,6 +16,9 @@ package com.bnorm.power +import com.bnorm.power.delegate.FunctionDelegate +import com.bnorm.power.delegate.LambdaFunctionDelegate +import com.bnorm.power.delegate.SimpleFunctionDelegate import com.bnorm.power.diagram.IrTemporaryVariable import com.bnorm.power.diagram.Node import com.bnorm.power.diagram.buildDiagramNesting @@ -32,28 +35,18 @@ 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.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.backend.js.utils.asString -import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope -import org.jetbrains.kotlin.ir.builders.declarations.buildFun -import org.jetbrains.kotlin.ir.builders.irBlockBody -import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irCallOp -import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.builders.irString import org.jetbrains.kotlin.ir.builders.parent -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction 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.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation -import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl -import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType @@ -68,7 +61,6 @@ 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.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions class PowerAssertCallTransformer( @@ -81,17 +73,27 @@ class PowerAssertCallTransformer( override fun visitCall(expression: IrCall): IrExpression { val function = expression.symbol.owner val fqName = function.kotlinFqName - if (function.valueParameters.isEmpty() || functions.none { fqName == it }) + if (function.valueParameters.isEmpty() || functions.none { fqName == it }) { return super.visitCall(expression) + } // Find a valid delegate function or do not translate // TODO better way to determine which delegate to actually use val delegates = findDelegates(function) - val delegate = delegates.maxByOrNull { it.function.valueParameters.size } ?: run { - val valueType = function.valueParameters[0].type.asString() + val delegate = delegates.maxByOrNull { it.function.valueParameters.size } + if (delegate == null) { + val valueTypesTruncated = function.valueParameters.subList(0, function.valueParameters.size - 1) + .joinToString(", ") { it.type.asString() } + val valueTypesAll = function.valueParameters.joinToString(", ") { it.type.asString() } messageCollector.warn( - expression, - "Unable to find overload for function $fqName callable as $fqName($valueType, String) or $fqName($valueType, () -> String) for power-assert transformation" + expression = expression, + message = """ + |Unable to find overload of function $fqName for power-assert transformation: + | - $fqName($valueTypesTruncated, String) + | - $fqName($valueTypesTruncated, () -> String) + | - $fqName($valueTypesAll, String) + | - $fqName($valueTypesAll, () -> String) + """.trimMargin() ) return super.visitCall(expression) } @@ -110,7 +112,7 @@ class PowerAssertCallTransformer( .map { arg -> arg?.let { buildTree(it) } } } - // If all roots are null, all parameters are constants and expression need not be transformed + // If all roots are null, there are no transformable parameters if (roots.all { it == null }) { messageCollector.info(expression, "Expression is constant and will not be power-assert transformed") return super.visitCall(expression) @@ -118,7 +120,7 @@ class PowerAssertCallTransformer( val symbol = currentScope!!.scope.scopeOwnerSymbol val builder = DeclarationIrBuilder(context, symbol, expression.startOffset, expression.endOffset) - return builder.diagram(expression, delegate, symbol, messageArgument, roots) + return builder.diagram(expression, delegate, messageArgument, roots) // .also { println(expression.dump()) } // .also { println(it.dump()) } // .also { println(expression.dumpKotlinLike()) } @@ -128,7 +130,6 @@ class PowerAssertCallTransformer( private fun DeclarationIrBuilder.diagram( original: IrCall, delegate: FunctionDelegate, - scopeSymbol: IrSymbol, messageArgument: IrExpression?, roots: List, index: Int = 0, @@ -136,63 +137,43 @@ class PowerAssertCallTransformer( variables: List = listOf() ): IrExpression { if (index >= roots.size) { - val lambda = messageArgument?.asSimpleLambda() - val title = when { - messageArgument is IrConst<*> -> messageArgument - messageArgument is IrStringConcatenation -> messageArgument - lambda != null -> lambda.deepCopyWithSymbols(parent).inline(parent) - .transform(ReturnableBlockTransformer(context, scopeSymbol), null) - messageArgument != null -> { - val invoke = messageArgument.type.classOrNull!!.owner.functions - .single { it.name == OperatorNameConventions.INVOKE } - irCallOp(invoke.symbol, invoke.returnType, messageArgument) - } - // TODO what should the default message be? - roots.size == 1 && original.getValueArgument(0)!!.type.isBoolean() -> irString("Assertion failed") - else -> null - } - - val prefix = title?.deepCopyWithSymbols(parent) + val prefix = buildMessagePrefix(messageArgument, roots, original)?.deepCopyWithSymbols(parent) val diagram = irDiagramString(file, fileSource, prefix, original, variables) return delegate.buildCall(this, original, arguments, diagram) } else { val root = roots[index] if (root == null) { - return diagram( - original, - delegate, - scopeSymbol, - messageArgument, - roots, - index + 1, - arguments + original.getValueArgument(index), - variables - ) + val newArguments = arguments + original.getValueArgument(index) + return diagram(original, delegate, messageArgument, roots, index + 1, newArguments, variables) } else { return buildDiagramNesting(root) { argument, newVariables -> - diagram( - original, - delegate, - scopeSymbol, - messageArgument, - roots, - index + 1, - arguments + argument, - variables + newVariables - ) + val newArguments = arguments + argument + diagram(original, delegate, messageArgument, roots, index + 1, newArguments, variables + newVariables) } } } } - private interface FunctionDelegate { - val function: IrFunction - fun buildCall( - builder: IrBuilderWithScope, - original: IrCall, - arguments: List, - message: IrExpression - ): IrExpression + private fun DeclarationIrBuilder.buildMessagePrefix( + messageArgument: IrExpression?, + roots: List, + original: IrCall + ): IrExpression? { + val lambda = messageArgument?.asSimpleLambda() + return when { + messageArgument is IrConst<*> -> messageArgument + messageArgument is IrStringConcatenation -> messageArgument + lambda != null -> lambda.deepCopyWithSymbols(parent).inline(parent) + .transform(ReturnableBlockTransformer(context, scope.scopeOwnerSymbol), null) + messageArgument != null -> { + val invoke = messageArgument.type.classOrNull!!.owner.functions + .single { it.name == OperatorNameConventions.INVOKE } + irCallOp(invoke.symbol, invoke.returnType, messageArgument) + } + // TODO what should the default message be? + roots.size == 1 && original.getValueArgument(0)!!.type.isBoolean() -> irString("Assertion failed") + else -> null + } } private fun findDelegates(function: IrFunction): List { @@ -203,81 +184,15 @@ class PowerAssertCallTransformer( .mapNotNull { overload -> val parameters = overload.owner.valueParameters if (parameters.size !in values.size..values.size + 1) return@mapNotNull null - if (!parameters.zip(values) - .all { (param, value) -> value.type.isAssignableTo(param.type) } - ) return@mapNotNull null + if (!parameters.zip(values).all { (param, value) -> value.type.isAssignableTo(param.type) }) { + return@mapNotNull null + } val messageParameter = parameters.last() return@mapNotNull when { - isStringSupertype(messageParameter.type) -> { - object : FunctionDelegate { - override val function = overload.owner - override fun buildCall( - builder: IrBuilderWithScope, - original: IrCall, - arguments: List, - message: IrExpression - ): IrExpression = with(builder) { - irCall(overload, type = original.type).apply { - dispatchReceiver = original.dispatchReceiver?.deepCopyWithSymbols(parent) - extensionReceiver = original.extensionReceiver?.deepCopyWithSymbols(parent) - for (i in 0 until original.typeArgumentsCount) { - putTypeArgument(i, original.getTypeArgument(i)) - } - for ((i, argument) in arguments.withIndex()) { - putValueArgument(i, argument?.deepCopyWithSymbols(builder.scope.getLocalDeclarationParent())) - } - putValueArgument(parameters.size - 1, message) - } - } - } - } - isStringFunction(messageParameter.type) -> { - object : FunctionDelegate { - override val function = overload.owner - override fun buildCall( - builder: IrBuilderWithScope, - original: IrCall, - arguments: List, - message: IrExpression - ): IrExpression = with(builder) { - val scope = this - val lambda = builder.context.irFactory.buildFun { - name = Name.special("") - returnType = context.irBuiltIns.stringType - visibility = DescriptorVisibilities.LOCAL - origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA - }.apply { - val bodyBuilder = DeclarationIrBuilder(this@PowerAssertCallTransformer.context, symbol) - body = bodyBuilder.irBlockBody { - +irReturn(message) - } - parent = scope.parent - } - val expression = IrFunctionExpressionImpl( - original.startOffset, - original.endOffset, - messageParameter.type, - lambda, - IrStatementOrigin.LAMBDA - ) - irCall(overload, type = original.type).apply { - dispatchReceiver = original.dispatchReceiver?.deepCopyWithSymbols(parent) - extensionReceiver = original.extensionReceiver?.deepCopyWithSymbols(parent) - for (i in 0 until original.typeArgumentsCount) { - putTypeArgument(i, original.getTypeArgument(i)) - } - for ((i, argument) in arguments.withIndex()) { - putValueArgument(i, argument?.deepCopyWithSymbols(builder.scope.getLocalDeclarationParent())) - } - putValueArgument(parameters.size - 1, expression) - } - } - } - } - else -> { - null - } + isStringSupertype(messageParameter.type) -> SimpleFunctionDelegate(overload) + isStringFunction(messageParameter.type) -> LambdaFunctionDelegate(overload, messageParameter) + else -> null } } } 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 new file mode 100644 index 00000000000..387402d0852 --- /dev/null +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/FunctionDelegate.kt @@ -0,0 +1,56 @@ +/* + * 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 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.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols + +interface FunctionDelegate { + val function: IrFunction + + fun buildCall( + builder: IrBuilderWithScope, + original: IrCall, + arguments: List, + message: IrExpression + ): IrExpression + + fun IrBuilderWithScope.irCallCopy( + overload: IrSimpleFunctionSymbol, + original: IrCall, + arguments: List, + expression: IrExpression + ): IrExpression { + return irCall(overload, type = original.type).apply { + dispatchReceiver = original.dispatchReceiver?.deepCopyWithSymbols(parent) + extensionReceiver = original.extensionReceiver?.deepCopyWithSymbols(parent) + for (i in 0 until original.typeArgumentsCount) { + putTypeArgument(i, original.getTypeArgument(i)) + } + for ((i, argument) in arguments.withIndex()) { + putValueArgument(i, argument?.deepCopyWithSymbols(parent)) + } + putValueArgument(arguments.size, expression) + } + } +} 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 new file mode 100644 index 00000000000..d18bab6df73 --- /dev/null +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/LambdaFunctionDelegate.kt @@ -0,0 +1,44 @@ +/* + * 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.declarations.IrValueParameter +import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol + +class LambdaFunctionDelegate( + 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 expression = irLambda(context.irBuiltIns.stringType, messageParameter.type) { + +irReturn(message) + } + irCallCopy(overload, original, arguments, expression) + } +} 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 new file mode 100644 index 00000000000..c1c60c66851 --- /dev/null +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/delegate/SimpleFunctionDelegate.kt @@ -0,0 +1,39 @@ +/* + * 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 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.IrValueParameter +import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols + +class SimpleFunctionDelegate( + private val overload: IrSimpleFunctionSymbol +) : FunctionDelegate { + override val function = overload.owner + + override fun buildCall( + builder: IrBuilderWithScope, + original: IrCall, + arguments: List, + message: IrExpression + ): IrExpression = builder.irCallCopy(overload, original, arguments, message) +} diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/diagram/IrTemporaryVariable.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/diagram/IrTemporaryVariable.kt index 84218e17816..27f3ac3d270 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/diagram/IrTemporaryVariable.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/diagram/IrTemporaryVariable.kt @@ -1,3 +1,19 @@ +/* + * 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.diagram import org.jetbrains.kotlin.ir.builders.IrStatementsBuilder diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/irUtils.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/irUtils.kt index 05043ab0ba8..4ee01c8747b 100644 --- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/irUtils.kt +++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/irUtils.kt @@ -1,7 +1,58 @@ +/* + * Copyright (C) 2020 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 org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope +import org.jetbrains.kotlin.ir.builders.declarations.buildFun +import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irString +import org.jetbrains.kotlin.ir.builders.parent +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression +import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin +import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionExpressionImpl +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.name.Name fun IrBuilderWithScope.irString(builderAction: StringBuilder.() -> Unit) = irString(buildString { builderAction() }) + +fun IrBuilderWithScope.irLambda( + returnType: IrType, + lambdaType: IrType, + startOffset: Int = this.startOffset, + endOffset: Int = this.endOffset, + block: IrBlockBodyBuilder.() -> Unit +): IrFunctionExpression { + val scope = this + val lambda = context.irFactory.buildFun { + name = Name.special("") + this.returnType = returnType + visibility = DescriptorVisibilities.LOCAL + origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA + }.apply { + val bodyBuilder = DeclarationIrBuilder(context, symbol) + body = bodyBuilder.irBlockBody { + block() + } + parent = scope.parent + } + return IrFunctionExpressionImpl(startOffset, endOffset, lambdaType, lambda, IrStatementOrigin.LAMBDA) +} 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 8f10802d574..1b9c9c30ae4 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 @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2020 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 org.junit.Test diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertBooleanTest.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertBooleanTest.kt deleted file mode 100644 index ade3f26a4de..00000000000 --- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertBooleanTest.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.bnorm.power - -import org.jetbrains.kotlin.name.FqName -import org.junit.Test - -class AssertBooleanTest { - @Test - fun `test assertTrue transformation`() { - assertMessage( - """ - import kotlin.test.assertTrue - - fun main() { - assertTrue(1 != 1) - }""", - """ - Assertion failed - assertTrue(1 != 1) - | - false - """.trimIndent(), - PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertTrue"))) - ) - } - - @Test - fun `test assertFalse transformation`() { - assertMessage( - """ - import kotlin.test.assertFalse - - fun main() { - assertFalse(1 == 1) - }""", - """ - Assertion failed - assertFalse(1 == 1) - | - true - """.trimIndent(), - PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertFalse"))) - ) - } -} 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 new file mode 100644 index 00000000000..4f67a686e1f --- /dev/null +++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/AssertLibraryTest.kt @@ -0,0 +1,180 @@ +/* + * 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 org.jetbrains.kotlin.name.FqName +import org.junit.Test + +class AssertLibraryTest { + @Test + fun `test assertTrue transformation`() { + assertMessage( + """ + import kotlin.test.assertTrue + + fun main() { + assertTrue(1 != 1) + }""", + """ + Assertion failed + assertTrue(1 != 1) + | + false + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertTrue"))) + ) + } + + @Test + fun `test assertTrue transformation with message`() { + assertMessage( + """ + import kotlin.test.assertTrue + + fun main() { + assertTrue(1 != 1, "Message:") + }""", + """ + Message: + assertTrue(1 != 1, "Message:") + | + false + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertTrue"))) + ) + } + + @Test + fun `test assertFalse transformation`() { + assertMessage( + """ + import kotlin.test.assertFalse + + fun main() { + assertFalse(1 == 1) + }""", + """ + Assertion failed + assertFalse(1 == 1) + | + true + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertFalse"))) + ) + } + + @Test + fun `test assertFalse transformation with message`() { + assertMessage( + """ + import kotlin.test.assertFalse + + fun main() { + assertFalse(1 == 1, "Message:") + }""", + """ + Message: + assertFalse(1 == 1, "Message:") + | + true + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertFalse"))) + ) + } + + @Test + fun `test assertEquals transformation`() { + assertMessage( + """ + import kotlin.test.assertEquals + + fun main() { + val greeting = "Hello" + val name = "World" + assertEquals(greeting, name) + }""", + """ + assertEquals(greeting, name) + | | + | World + Hello expected:<[Hello]> but was:<[World]> + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertEquals"))) + ) + } + + @Test + fun `test assertEquals transformation with message`() { + assertMessage( + """ + import kotlin.test.assertEquals + + fun main() { + val greeting = "Hello" + val name = "World" + assertEquals(greeting, name, "Message:") + }""", + """ + Message: + assertEquals(greeting, name, "Message:") + | | + | World + Hello expected:<[Hello]> but was:<[World]> + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertEquals"))) + ) + } + + @Test + fun `test assertNotNull transformation`() { + assertMessage( + """ + import kotlin.test.assertNotNull + + fun main() { + val name: String? = null + assertNotNull(name) + }""", + """ + assertNotNull(name) + | + null + """.trimIndent(), + PowerAssertComponentRegistrar(setOf(FqName("kotlin.test.assertNotNull"))) + ) + } + + @Test + fun `test assertNotNull transformation with message`() { + assertMessage( + """ + import kotlin.test.assertNotNull + + fun main() { + val name: String? = null + assertNotNull(name, "Message:") + }""", + """ + Message: + assertNotNull(name, "Message:") + | + null + """.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 89932becd69..d720e3e744d 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 @@ -1,3 +1,19 @@ +/* + * 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 com.tschuchort.compiletesting.KotlinCompilation 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 fb7a7a8f662..1a2ce2b21d1 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 @@ -1,3 +1,19 @@ +/* + * 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 com.tschuchort.compiletesting.KotlinCompilation 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 ac40b07389e..8207d6bfd29 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 @@ -1,3 +1,19 @@ +/* + * 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 org.junit.Test 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 5726ed12b5f..cfc28e034e9 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 @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2020 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 com.tschuchort.compiletesting.KotlinCompilation