[KPM] Implement SimpleProjectToProjectDependencyResolutionTest
KT-51386
This commit is contained in:
committed by
Space
parent
e55bba9c4c
commit
d7ce7387f7
+4
-1
@@ -33,6 +33,9 @@ sealed interface IdeaKotlinSourceDependency : IdeaKotlinDependency {
|
||||
val kotlinFragmentName: String
|
||||
}
|
||||
|
||||
val IdeaKotlinSourceDependency.path: String
|
||||
get() = "${buildId.takeIf { it != ":" }.orEmpty()}$projectPath/$kotlinModuleName/$kotlinFragmentName"
|
||||
|
||||
sealed interface IdeaKotlinBinaryCoordinates : Serializable {
|
||||
val group: String
|
||||
val module: String
|
||||
@@ -70,7 +73,7 @@ data class IdeaKotlinSourceDependencyImpl(
|
||||
) : IdeaKotlinSourceDependency {
|
||||
|
||||
override fun toString(): String {
|
||||
return "project://$buildId:$projectPath:$kotlinModuleName:$kotlinFragmentName"
|
||||
return "fragment: $path"
|
||||
}
|
||||
|
||||
@InternalKotlinGradlePluginApi
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.kpm.idea.testFixtures
|
||||
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinBinaryCoordinates
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinBinaryDependency
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinResolvedBinaryDependency
|
||||
import java.io.File
|
||||
|
||||
fun buildIdeaKotlinBinaryDependencyMatchers(notation: Any?): List<IdeaKotlinBinaryDependencyMatcher> {
|
||||
return when (notation) {
|
||||
null -> emptyList()
|
||||
is IdeaKotlinBinaryDependencyMatcher -> listOf(notation)
|
||||
is String -> listOf(IdeaKotlinBinaryDependencyMatcher.Coordinates(parseIdeaKotlinBinaryCoordinates(notation)))
|
||||
is Regex -> listOf(IdeaKotlinBinaryDependencyMatcher.CoordinatesRegex(notation))
|
||||
is File -> listOf(IdeaKotlinBinaryDependencyMatcher.BinaryFile(notation))
|
||||
is Iterable<*> -> notation.flatMap { child -> buildIdeaKotlinBinaryDependencyMatchers(child) }
|
||||
else -> error("Can't build ${IdeaKotlinBinaryDependencyMatcher::class.simpleName} from $notation")
|
||||
}
|
||||
}
|
||||
|
||||
interface IdeaKotlinBinaryDependencyMatcher : IdeaKotlinDependencyMatcher<IdeaKotlinBinaryDependency>{
|
||||
class Coordinates(
|
||||
private val coordinates: IdeaKotlinBinaryCoordinates
|
||||
) : IdeaKotlinBinaryDependencyMatcher {
|
||||
override val description: String = coordinates.toString()
|
||||
|
||||
override fun matches(dependency: IdeaKotlinBinaryDependency): Boolean {
|
||||
return coordinates == dependency.coordinates
|
||||
}
|
||||
}
|
||||
|
||||
class CoordinatesRegex(
|
||||
private val regex: Regex
|
||||
) : IdeaKotlinBinaryDependencyMatcher {
|
||||
override val description: String = regex.pattern
|
||||
|
||||
override fun matches(dependency: IdeaKotlinBinaryDependency): Boolean {
|
||||
return regex.matches(dependency.coordinates.toString())
|
||||
}
|
||||
}
|
||||
|
||||
class BinaryFile(
|
||||
private val binaryFile: File
|
||||
) : IdeaKotlinBinaryDependencyMatcher {
|
||||
override val description: String = binaryFile.path
|
||||
|
||||
override fun matches(dependency: IdeaKotlinBinaryDependency): Boolean {
|
||||
return dependency is IdeaKotlinResolvedBinaryDependency && dependency.binaryFile == binaryFile
|
||||
}
|
||||
}
|
||||
|
||||
class InDirectory(
|
||||
private val parentFile: File
|
||||
) : IdeaKotlinBinaryDependencyMatcher {
|
||||
constructor(parentFilePath: String) : this(File(parentFilePath))
|
||||
|
||||
override val description: String = "$parentFile/**"
|
||||
|
||||
override fun matches(dependency: IdeaKotlinBinaryDependency): Boolean {
|
||||
return dependency is IdeaKotlinResolvedBinaryDependency &&
|
||||
dependency.binaryFile.absoluteFile.normalize().canonicalPath.startsWith(
|
||||
parentFile.absoluteFile.normalize().canonicalPath
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-64
@@ -5,71 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.kpm.idea.testFixtures
|
||||
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinBinaryCoordinates
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinBinaryDependency
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinDependency
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinResolvedBinaryDependency
|
||||
import java.io.File
|
||||
|
||||
fun buildIdeaKotlinDependencyMatchers(any: Any?): List<IdeaKotlinDependencyMatcher> {
|
||||
return when (any) {
|
||||
null -> emptyList()
|
||||
is IdeaKotlinDependencyMatcher -> listOf(any)
|
||||
is String -> listOf(IdeaKotlinDependencyMatcher.Coordinates(parseIdeaKotlinBinaryCoordinates(any)))
|
||||
is Regex -> listOf(IdeaKotlinDependencyMatcher.CoordinatesRegex(any))
|
||||
is File -> listOf(IdeaKotlinDependencyMatcher.BinaryFile(any))
|
||||
is Iterable<*> -> any.flatMap { child -> buildIdeaKotlinDependencyMatchers(child) }
|
||||
else -> error("Can't build ${IdeaKotlinDependencyMatcher::class.simpleName} from $any")
|
||||
}
|
||||
}
|
||||
|
||||
interface IdeaKotlinDependencyMatcher {
|
||||
interface IdeaKotlinDependencyMatcher<in T : IdeaKotlinDependency> {
|
||||
val description: String
|
||||
fun matches(dependency: IdeaKotlinDependency): Boolean
|
||||
|
||||
class Coordinates(
|
||||
private val coordinates: IdeaKotlinBinaryCoordinates
|
||||
) : IdeaKotlinDependencyMatcher {
|
||||
override val description: String = coordinates.toString()
|
||||
|
||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||
return dependency is IdeaKotlinBinaryDependency && coordinates == dependency.coordinates
|
||||
}
|
||||
}
|
||||
|
||||
class CoordinatesRegex(
|
||||
private val regex: Regex
|
||||
) : IdeaKotlinDependencyMatcher {
|
||||
override val description: String = regex.pattern
|
||||
|
||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||
return dependency is IdeaKotlinBinaryDependency && regex.matches(dependency.coordinates.toString())
|
||||
}
|
||||
}
|
||||
|
||||
class BinaryFile(
|
||||
private val binaryFile: File
|
||||
) : IdeaKotlinDependencyMatcher {
|
||||
override val description: String = binaryFile.path
|
||||
|
||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||
return dependency is IdeaKotlinResolvedBinaryDependency && dependency.binaryFile == binaryFile
|
||||
}
|
||||
}
|
||||
|
||||
class InDirectory(
|
||||
private val parentFile: File
|
||||
) : IdeaKotlinDependencyMatcher {
|
||||
constructor(parentFilePath: String) : this(File(parentFilePath))
|
||||
|
||||
override val description: String = "$parentFile/**"
|
||||
|
||||
override fun matches(dependency: IdeaKotlinDependency): Boolean {
|
||||
return dependency is IdeaKotlinResolvedBinaryDependency &&
|
||||
dependency.binaryFile.absoluteFile.normalize().canonicalPath.startsWith(
|
||||
parentFile.absoluteFile.normalize().canonicalPath
|
||||
)
|
||||
}
|
||||
}
|
||||
fun matches(dependency: T): Boolean
|
||||
}
|
||||
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package org.jetbrains.kotlin.gradle.kpm.idea.testFixtures
|
||||
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinSourceDependency
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.path
|
||||
|
||||
fun buildIdeaKotlinSourceDependencyMatchers(notation: Any?): List<IdeaKotlinSourceDependencyMatcher> {
|
||||
return when (notation) {
|
||||
null -> emptyList()
|
||||
is Iterable<*> -> notation.flatMap { buildIdeaKotlinSourceDependencyMatchers(it) }
|
||||
is String -> listOf(IdeaKotlinSourceDependencyMatcher.FragmentPath(notation))
|
||||
is Regex -> listOf(IdeaKotlinSourceDependencyMatcher.FragmentPathRegex(notation))
|
||||
else -> error("Can't build ${IdeaKotlinSourceDependencyMatcher::class.simpleName} from $notation")
|
||||
}
|
||||
}
|
||||
|
||||
interface IdeaKotlinSourceDependencyMatcher : IdeaKotlinDependencyMatcher<IdeaKotlinSourceDependency> {
|
||||
class FragmentPath(private val path: String) : IdeaKotlinSourceDependencyMatcher {
|
||||
override val description: String = path
|
||||
|
||||
override fun matches(dependency: IdeaKotlinSourceDependency): Boolean {
|
||||
return path == dependency.path
|
||||
}
|
||||
}
|
||||
|
||||
class FragmentPathRegex(private val pathRegex: Regex) : IdeaKotlinSourceDependencyMatcher {
|
||||
override val description: String = pathRegex.pattern
|
||||
|
||||
override fun matches(dependency: IdeaKotlinSourceDependency): Boolean {
|
||||
return pathRegex.matches(dependency.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
-5
@@ -3,6 +3,8 @@
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("DuplicatedCode")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.kpm.idea.testFixtures
|
||||
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.*
|
||||
@@ -24,7 +26,7 @@ fun IdeaKotlinModule.assertContainsFragment(name: String): IdeaKotlinFragment {
|
||||
|
||||
fun IdeaKotlinFragment.assertResolvedBinaryDependencies(
|
||||
binaryType: String,
|
||||
matchers: Set<IdeaKotlinDependencyMatcher>
|
||||
matchers: Set<IdeaKotlinBinaryDependencyMatcher>
|
||||
): Set<IdeaKotlinResolvedBinaryDependency> {
|
||||
val resolvedBinaryDependencies = dependencies
|
||||
.mapNotNull { dependency ->
|
||||
@@ -57,7 +59,7 @@ fun IdeaKotlinFragment.assertResolvedBinaryDependencies(
|
||||
}
|
||||
|
||||
appendLine()
|
||||
appendLine("Unexpected dependency coordinates:")
|
||||
appendLine("${name}: Unexpected dependency coordinates:")
|
||||
unexpectedResolvedBinaryDependencies.forEach { unexpectedDependency ->
|
||||
appendLine("\"${unexpectedDependency.coordinates}\",")
|
||||
}
|
||||
@@ -65,14 +67,14 @@ fun IdeaKotlinFragment.assertResolvedBinaryDependencies(
|
||||
|
||||
if (missingDependencies.isNotEmpty()) {
|
||||
appendLine()
|
||||
appendLine("Missing dependencies:")
|
||||
appendLine("${name}: Missing dependencies:")
|
||||
missingDependencies.forEach { missingDependency ->
|
||||
appendLine(missingDependency.description)
|
||||
}
|
||||
}
|
||||
|
||||
appendLine()
|
||||
appendLine("Resolved Dependency Coordinates:")
|
||||
appendLine("${name}: Resolved Dependency Coordinates:")
|
||||
resolvedBinaryDependencies.mapNotNull { it.coordinates }.forEach { coordinates ->
|
||||
appendLine("\"$coordinates\",")
|
||||
}
|
||||
@@ -83,8 +85,61 @@ fun IdeaKotlinFragment.assertResolvedBinaryDependencies(
|
||||
@JvmName("assertResolvedBinaryDependenciesByAnyMatcher")
|
||||
fun IdeaKotlinFragment.assertResolvedBinaryDependencies(
|
||||
binaryType: String, matchers: Set<Any?>,
|
||||
) = assertResolvedBinaryDependencies(binaryType, matchers.flatMap { buildIdeaKotlinDependencyMatchers(it) }.toSet())
|
||||
) = assertResolvedBinaryDependencies(binaryType, matchers.flatMap { buildIdeaKotlinBinaryDependencyMatchers(it) }.toSet())
|
||||
|
||||
fun IdeaKotlinFragment.assertResolvedBinaryDependencies(
|
||||
binaryType: String, vararg matchers: Any?
|
||||
) = assertResolvedBinaryDependencies(binaryType, matchers.toSet())
|
||||
|
||||
fun IdeaKotlinFragment.assertSourceDependencies(matchers: Set<IdeaKotlinSourceDependencyMatcher>): Set<IdeaKotlinSourceDependency> {
|
||||
val sourceDependencies = dependencies.filterIsInstance<IdeaKotlinSourceDependency>().toSet()
|
||||
|
||||
val unexpectedDependencies = sourceDependencies
|
||||
.filter { dependency -> matchers.none { matcher -> matcher.matches(dependency) } }
|
||||
|
||||
val missingDependencies = matchers.filter { matcher ->
|
||||
sourceDependencies.none { dependency -> matcher.matches(dependency) }
|
||||
}
|
||||
|
||||
if (unexpectedDependencies.isEmpty() && missingDependencies.isEmpty()) {
|
||||
return sourceDependencies
|
||||
}
|
||||
|
||||
fail(
|
||||
buildString {
|
||||
if (unexpectedDependencies.isNotEmpty()) {
|
||||
appendLine("${name}: Unexpected source dependencies found:")
|
||||
unexpectedDependencies.forEach { unexpectedDependency ->
|
||||
appendLine(unexpectedDependency)
|
||||
}
|
||||
|
||||
appendLine()
|
||||
appendLine("${name}: Unexpected source dependency paths:")
|
||||
unexpectedDependencies.forEach { unexpectedDependency ->
|
||||
appendLine("\"${unexpectedDependency.path}\",")
|
||||
}
|
||||
}
|
||||
|
||||
if (missingDependencies.isNotEmpty()) {
|
||||
appendLine()
|
||||
appendLine("${name}: Missing fragment dependencies:")
|
||||
missingDependencies.forEach { missingDependency ->
|
||||
appendLine(missingDependency.description)
|
||||
}
|
||||
}
|
||||
|
||||
appendLine()
|
||||
appendLine("${name}: Resolved source dependency paths:")
|
||||
sourceDependencies.forEach { dependency ->
|
||||
appendLine("\"${dependency.path}\",")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@JvmName("assertSourceDependenciesByAnyMatcher")
|
||||
fun IdeaKotlinFragment.assertSourceDependencies(matchers: Set<Any?>): Set<IdeaKotlinSourceDependency> =
|
||||
assertSourceDependencies(matchers.flatMap { buildIdeaKotlinSourceDependencyMatchers(it) }.toSet())
|
||||
|
||||
fun IdeaKotlinFragment.assertSourceDependencies(vararg matchers: Any?) =
|
||||
assertSourceDependencies(matchers.toSet())
|
||||
|
||||
Reference in New Issue
Block a user