All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openrewrite.RefactorVisitorTest.kt Maven / Gradle / Ivy

There is a newer version: 8.42.0
Show newest version
/*
 * Copyright 2020 the original author or authors.
 * 

* 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 *

* https://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 org.openrewrite import org.junit.jupiter.api.BeforeEach import java.io.File import java.lang.RuntimeException /** * Provides a standardized shape for test classes that exercise refactoring visitors to take. */ interface RefactorVisitorTest { val visitors: Iterable> get() = emptyList() private fun assertBeforeAndAfterAreDifferent(before: String, after:String) { if(before.trimIndent() == after.trimIndent()) { throw RuntimeException( "'before' and 'after' are equal. " + "Looks like you're trying to assert that the visitors should make no changes. " + "Instead of RefactorVisitorTest.assertRefactored(), use RefactorVisitorTest.assertUnchanged()") } } /** * Parse the "before" text, apply the visitors, assert that the result is "after" */ fun assertRefactored( parser: Parser, visitors: Iterable> = this.visitors, visitorsMapped: Iterable<(S) -> RefactorVisitor> = emptyList(), visitorsMappedToMany: Iterable<(S) -> Iterable>> = emptyList(), dependencies: List = listOf(), before: String, after: String) { assertBeforeAndAfterAreDifferent(before, after) before.trimIndent() .whenParsedBy(parser) .whichDependsOn(*dependencies.toTypedArray()) .whenVisitedBy(visitors) .let { visitorsMapped.fold(it) { acc, visitorMapping -> acc.whenVisitedByMapped(visitorMapping) } } .let { visitorsMappedToMany.fold(it) { acc, visitorMapping -> acc.whenVisitedByMany(visitorMapping) } } .isRefactoredTo(after.trimIndent()) } /** * Just like the other assertRefactored, but for when you want "after" to be lazily-evaluated. * This is niche, for those situations where the result should depend on something figured out during refactoring */ fun assertRefactored( parser: Parser, visitors: Iterable>, visitorsMapped: Iterable<(S) -> RefactorVisitor>, visitorsMappedToMany: Iterable<(S) -> Iterable>>, dependencies: List, before: String, after: () -> String) { // To lazily evaluate after() and maintain consistency with the other versions of assertRefactored, // curry in a trimIndent() and assertBeforeAndAfterAreDifferent() to be evaluated no sooner than after() is val afterTrimmed: ()->String = { val afterText = after().trimIndent() assertBeforeAndAfterAreDifferent(before, afterText) afterText } before.trimIndent() .whenParsedBy(parser) .whichDependsOn(*dependencies.toTypedArray()) .whenVisitedBy(visitors) .let { visitorsMapped.fold(it) { acc, visitorMapping -> acc.whenVisitedByMapped(visitorMapping) } } .let { visitorsMappedToMany.fold(it) { acc, visitorMapping -> acc.whenVisitedByMany(visitorMapping) } } .isRefactoredTo(afterTrimmed) } /** * Parse the "before" text, apply the visitors, assert that there are no changes */ fun assertUnchanged(parser: Parser, visitors: Iterable> = this.visitors, visitorsMapped: Iterable<(S) -> RefactorVisitor> = emptyList(), visitorsMappedToMany: Iterable<(S) -> Iterable>> = emptyList(), dependencies: List = listOf(), before: String) { before.trimIndent() .whenParsedBy(parser) .whichDependsOn(*dependencies.toTypedArray()) .whenVisitedBy(visitors) .let { visitorsMapped.fold(it) { acc, visitorMapping -> acc.whenVisitedByMapped(visitorMapping) } } .let { visitorsMappedToMany.fold(it) { acc, visitorMapping -> acc.whenVisitedByMany(visitorMapping) } } .isUnchanged } /** * Parse the "before" text, apply the visitors, assert that the result is "after" */ fun assertRefactored( parser: Parser, visitors: Iterable> = this.visitors, visitorsMapped: Iterable<(S) -> RefactorVisitor> = emptyList(), visitorsMappedToMany: Iterable<(S) -> Iterable>> = emptyList(), dependencies: List = listOf(), before: File, after: String) { assertBeforeAndAfterAreDifferent(before.readText(), after) before.toPath() .whenParsedBy(parser) .whichDependsOn(*dependencies.map { it.toPath() }.toTypedArray()) .whenVisitedBy(visitors) .let { visitorsMapped.fold(it) { acc, visitorMapping -> acc.whenVisitedByMapped(visitorMapping) } } .let { visitorsMappedToMany.fold(it) { acc, visitorMapping -> acc.whenVisitedByMany(visitorMapping) } } .isRefactoredTo(after.trimIndent()) } /** * Parse the "before" text, apply the visitors, assert that there are no changes */ fun assertUnchanged( parser: Parser, visitors: Iterable> = this.visitors, visitorsMapped: Iterable<(S) -> RefactorVisitor> = emptyList(), visitorsMappedToMany: Iterable<(S) -> Iterable>> = emptyList(), dependencies: List = listOf(), before: File) { before.toPath() .whenParsedBy(parser) .whichDependsOn(*dependencies.map { it.toPath() }.toTypedArray()) .whenVisitedBy(visitors) .let { visitorsMapped.fold(it) { acc, visitorMapping -> acc.whenVisitedByMapped(visitorMapping) } } .let { visitorsMappedToMany.fold(it) { acc, visitorMapping -> acc.whenVisitedByMany(visitorMapping) } } .isUnchanged } } interface RefactorVisitorTestForParser : RefactorVisitorTest { val parser: Parser fun assertRefactored( visitors: Iterable> = this.visitors, visitorsMapped: Iterable<(S) -> RefactorVisitor> = emptyList(), visitorsMappedToMany: Iterable<(S) -> Iterable>> = emptyList(), dependencies: List = listOf(), before: String, after: String) { return assertRefactored(parser, visitors, visitorsMapped, visitorsMappedToMany, dependencies, before, after) } fun assertRefactored( visitors: Iterable> = this.visitors, visitorsMapped: Iterable<(S) -> RefactorVisitor> = emptyList(), visitorsMappedToMany: Iterable<(S) -> Iterable>> = emptyList(), dependencies: List = listOf(), before: String, after: ()->String) { return assertRefactored(parser, visitors, visitorsMapped, visitorsMappedToMany, dependencies, before, after) } fun assertRefactored( visitors: Iterable> = this.visitors, visitorsMapped: Iterable<(S) -> RefactorVisitor> = emptyList(), visitorsMappedToMany: Iterable<(S) -> Iterable>> = emptyList(), dependencies: List = listOf(), before: File, after: String) { return assertRefactored(parser, visitors, visitorsMapped, visitorsMappedToMany, dependencies, before, after) } fun assertUnchanged( visitors: Iterable> = this.visitors, visitorsMapped: Iterable<(S) -> RefactorVisitor> = emptyList(), visitorsMappedToMany: Iterable<(S) -> Iterable>> = emptyList(), dependencies: List = listOf(), before: String ) { return assertUnchanged(parser, visitors, visitorsMapped, visitorsMappedToMany, dependencies, before) } fun assertUnchanged( visitors: Iterable> = this.visitors, visitorsMapped: Iterable<(S) -> RefactorVisitor> = emptyList(), visitorsMappedToMany: Iterable<(S) -> Iterable>> = emptyList(), dependencies: List = listOf(), before: File ) { return assertUnchanged(parser, visitors, visitorsMapped, visitorsMappedToMany, dependencies, before) } @BeforeEach fun beforeEach() { parser.reset() } }