1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.build 18 19 import androidx.testutils.gradle.ProjectSetupRule 20 import java.io.File 21 import org.junit.Assert 22 import org.junit.Assert.assertEquals 23 import org.junit.Rule 24 import org.junit.Test 25 26 class ConstraintTest { 27 @get:Rule val projectSetup = ProjectSetupRule() 28 29 /** Test for matching constraint versions in Gradle metadata. */ 30 @Test mavenMetadataRequiresVersionnull31 fun mavenMetadataRequiresVersion() { 32 val baseMavenMetadata = getPublishedFile("androidx/core/core/maven-metadata.xml") 33 val baseVersion = getLatestVersion(baseMavenMetadata) 34 35 val baseGradleMetadata = 36 getPublishedFile("androidx/core/core/$baseVersion/core-$baseVersion.module") 37 val baseRequiresKtxVersion = 38 getConstraintVersion(baseGradleMetadata.readText(), "androidx.core", "core-ktx")!! 39 40 val ktxMavenMetadata = getPublishedFile("androidx/core/core-ktx/maven-metadata.xml") 41 val ktxVersion = getLatestVersion(ktxMavenMetadata) 42 43 val ktxGradleMetadata = 44 getPublishedFile("androidx/core/core-ktx/$ktxVersion/core-ktx-$ktxVersion.module") 45 val ktxRequiresBaseVersion = 46 getConstraintVersion(ktxGradleMetadata.readText(), "androidx.core", "core")!! 47 48 // The core and core-ktx libraries should share the same version. 49 assertEquals(baseVersion, ktxVersion) 50 51 // Their Gradle metadata files should reference each other as `required`-type constraints. 52 assertEquals(baseVersion, ktxRequiresBaseVersion) 53 assertEquals(ktxVersion, baseRequiresKtxVersion) 54 } 55 56 /** Unit test for the constraint version extraction function. */ 57 @Test getConstraintVersionTestnull58 fun getConstraintVersionTest() { 59 val metadata = 60 """ 61 "version": { 62 "requires": "1.0.0" 63 } 64 } 65 ], 66 variants: [ 67 { 68 "name": "releaseVariantReleaseApiPublication", 69 "dependencyConstraints": [ 70 { 71 "group": "org.jetbrains.kotlin", 72 "module": "kotlin-stdlib", 73 "version": { 74 "requires": "1.8.22" 75 } 76 } 77 ], 78 }, 79 { 80 "name": "releaseVariantReleaseRuntimePublication", 81 "dependencyConstraints": [ 82 { 83 "group": "androidx.preference", 84 "module": "preference-ktx", 85 "version": { 86 "requires": "1.3.0-alpha01" 87 } 88 } 89 ], 90 } 91 ] 92 "files": [ 93 { 94 "name": "preference-1.3.0-alpha01.aar", 95 "url": "preference-1.3.0-alpha01.aar", 96 """ 97 .trimIndent() 98 99 val requiresVersion = 100 getConstraintVersion(metadata, "androidx.preference", "preference-ktx") 101 assertEquals("1.3.0-alpha01", requiresVersion) 102 } 103 getConstraintVersionnull104 private fun getConstraintVersion(metadata: String, groupId: String, artifact: String): String? = 105 getDependencyConstraints(metadata).let { 106 Regex( 107 "\"group\": \"$groupId\",\\s+\"module\": " + 108 "\"$artifact\",\\s+\"version\": \\{\\s+\"requires\": \"(.+?)\"" 109 ) 110 .find(it) 111 ?.groups 112 ?.get(1) 113 ?.value 114 } 115 getDependencyConstraintsnull116 private fun getDependencyConstraints(moduleJson: String) = 117 Regex("(?s)\"dependencyConstraints\": \\[(.+?)]").findAll(moduleJson).joinToString("\n") { 118 it.groups.get(1)?.value.orEmpty() 119 } 120 121 // Yes, I know https://stackoverflow.com/a/1732454/258688, but it's just a test... getLatestVersionnull122 private fun getLatestVersion(metadataFile: File) = 123 metadataFile 124 .readLines() 125 .mapNotNull { Regex(".*<latest>(.*?)</latest>.*").find(it)?.groups?.get(1)?.value } 126 .first() 127 getPublishedFilenull128 private fun getPublishedFile(name: String) = 129 File(projectSetup.props.tipOfTreeMavenRepoPath).resolve(name).check { it.exists() } 130 checknull131 private fun <T> T.check(eval: (T) -> Boolean): T { 132 if (!eval(this)) { 133 Assert.fail("Failed assertion: $this") 134 } 135 return this 136 } 137 } 138