blob: 52153b4108397950190bf0913a448b740ef3e20a [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* 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.android.build.gradle.internal.variant2
import com.android.build.gradle.internal.api.dsl.extensions.BaseExtension2
import com.android.build.gradle.internal.api.dsl.model.BaseFlavorImpl
import com.android.build.gradle.internal.api.dsl.model.BuildTypeOrProductFlavorImpl
import com.android.build.gradle.internal.api.dsl.model.DefaultConfigImpl
import com.android.build.gradle.internal.api.dsl.model.FallbackStrategyImpl
import com.android.build.gradle.internal.api.dsl.model.ProductFlavorOrVariantImpl
import com.android.build.gradle.internal.api.dsl.model.VariantPropertiesImpl
import com.android.build.gradle.internal.fixtures.FakeConfigurationContainer
import com.android.build.gradle.internal.fixtures.FakeContainerFactory
import com.android.build.gradle.internal.fixtures.FakeDeprecationReporter
import com.android.build.gradle.internal.fixtures.FakeEvalIssueReporter
import com.android.build.gradle.internal.fixtures.FakeFilesProvider
import com.android.build.gradle.internal.fixtures.FakeObjectFactory
import com.android.build.gradle.internal.fixtures.FakeLogger
import com.android.build.gradle.internal.fixtures.FakeVariantFactory2
import com.android.builder.core.BuilderConstants
import com.android.builder.core.VariantType
import com.android.builder.core.VariantTypeImpl
import com.google.common.truth.Truth
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.artifacts.Configuration
import org.junit.Test
class DslModelDataImplTest {
private val issueReporter = FakeEvalIssueReporter()
private val deprecationReporter = FakeDeprecationReporter()
private val configurationContainer = FakeConfigurationContainer()
private val dslScope = DslScopeImpl(issueReporter, deprecationReporter, FakeObjectFactory())
@Test
fun `source sets for default config`() {
val modelData = createModelData(
createFactories(BaseExtension2::class.java, VariantTypeImpl.BASE_APK))
val defaultConfigData = modelData.defaultConfigData
Truth.assertThat(defaultConfigData).isNotNull()
var sourceSet = defaultConfigData.getSourceSet(VariantTypeImpl.BASE_APK)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo(BuilderConstants.MAIN)
sourceSet = defaultConfigData.getSourceSet(VariantTypeImpl.ANDROID_TEST)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo("androidTest")
sourceSet = defaultConfigData.getSourceSet(VariantTypeImpl.UNIT_TEST)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo("test")
// always assert we haven't hit any deprecation
Truth.assertThat(deprecationReporter.deprecationWarnings).isEmpty()
}
@Test
fun `configurations for default config`() {
val modelData = createModelData(
createFactories(BaseExtension2::class.java, VariantTypeImpl.BASE_APK))
val defaultConfigData = modelData.defaultConfigData
Truth.assertThat(defaultConfigData).isNotNull()
val compile = getNonNullConfig("compile")
val api = getNonNullConfig("api")
Truth.assertThat(api.extendsFrom).containsExactly(compile)
val impl = getNonNullConfig("implementation")
Truth.assertThat(impl.extendsFrom).containsExactly(api)
Truth.assertThat(getNonNullConfig("compileOnly")).isNotNull()
val apkOnly = getNonNullConfig("apk")
val runtimeOnly = getNonNullConfig("runtimeOnly")
Truth.assertThat(runtimeOnly.extendsFrom).containsExactly(apkOnly)
// test test configuration
val testCompile = getNonNullConfig("testCompile")
val testApi = getNonNullConfig("testApi")
Truth.assertThat(testApi.extendsFrom).containsExactly(testCompile)
val testImpl = getNonNullConfig("testImplementation")
Truth.assertThat(testImpl.extendsFrom).containsExactly(testApi, impl)
val testApkOnly = getNonNullConfig("testApk")
val testRuntimeOnly = getNonNullConfig("testRuntimeOnly")
Truth.assertThat(testRuntimeOnly.extendsFrom).containsExactly(runtimeOnly, testApkOnly)
// test androidTest configuration
val androidTestCompile = getNonNullConfig("androidTestCompile")
val androidTestApi = getNonNullConfig("androidTestApi")
Truth.assertThat(androidTestApi.extendsFrom).containsExactly(androidTestCompile)
val androidTestImpl = getNonNullConfig("androidTestImplementation")
Truth.assertThat(androidTestImpl.extendsFrom).containsExactly(androidTestApi, impl)
val androidTestApkOnly = getNonNullConfig("androidTestApk")
val androidTestRuntimeOnly = getNonNullConfig("androidTestRuntimeOnly")
Truth.assertThat(androidTestRuntimeOnly.extendsFrom).containsExactly(runtimeOnly, androidTestApkOnly)
// always assert we haven't hit any deprecation
Truth.assertThat(deprecationReporter.deprecationWarnings).isEmpty()
}
@Test
fun `configurations for default config with library`() {
val modelData = createModelData(
createFactories(BaseExtension2::class.java, VariantTypeImpl.LIBRARY))
val defaultConfigData = modelData.defaultConfigData
Truth.assertThat(defaultConfigData).isNotNull()
// test main configurations
val publishOnly = getNonNullConfig("publish")
val runtimeOnly = getNonNullConfig("runtimeOnly")
Truth.assertThat(runtimeOnly.extendsFrom).containsExactly(publishOnly)
// always assert we haven't hit any deprecation
Truth.assertThat(deprecationReporter.deprecationWarnings).isEmpty()
}
@Test
fun `source sets for default config when no tests`() {
val modelData = createModelData(
createFactories(
BaseExtension2::class.java,
VariantTypeImpl.BASE_APK,
hasAndroidTests = false,
hasUnitTests = false))
val defaultConfigData = modelData.defaultConfigData
Truth.assertThat(defaultConfigData).isNotNull()
var sourceSet = defaultConfigData.getSourceSet(VariantTypeImpl.BASE_APK)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo(BuilderConstants.MAIN)
sourceSet = defaultConfigData.getSourceSet(VariantTypeImpl.ANDROID_TEST)
Truth.assertThat(sourceSet).isNull()
sourceSet = defaultConfigData.getSourceSet(VariantTypeImpl.UNIT_TEST)
Truth.assertThat(sourceSet).isNull()
// tests to make sure we don't have test source sets or configs.
checkNullConfiguration("testCompile")
checkNullConfiguration("androidTestCompile")
// always assert we haven't hit any deprecation
Truth.assertThat(deprecationReporter.deprecationWarnings).isEmpty()
}
@Test
fun `source sets for added flavors`() {
val modelData = createModelData(
createFactories(BaseExtension2::class.java, VariantTypeImpl.BASE_APK))
val flavorName = "free"
modelData.productFlavors.create(flavorName)
modelData.afterEvaluateCompute()
val data = modelData.flavorData[flavorName]
Truth.assertThat(data).isNotNull()
var sourceSet = data?.getSourceSet(VariantTypeImpl.BASE_APK)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo(flavorName)
sourceSet = data?.getSourceSet(VariantTypeImpl.ANDROID_TEST)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo("androidTestFree")
sourceSet = data?.getSourceSet(VariantTypeImpl.UNIT_TEST)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo("testFree")
// always assert we haven't hit any deprecation
Truth.assertThat(deprecationReporter.deprecationWarnings).isEmpty()
}
@Test
fun `configurations for added flavors`() {
val modelData = createModelData(
createFactories(BaseExtension2::class.java, VariantTypeImpl.BASE_APK))
val flavorName = "free"
modelData.productFlavors.create(flavorName)
modelData.afterEvaluateCompute()
val compile = getNonNullConfig("freeCompile")
val api = getNonNullConfig("freeApi")
Truth.assertThat(api.extendsFrom).containsExactly(compile)
val impl = getNonNullConfig("freeImplementation")
Truth.assertThat(impl.extendsFrom).containsExactly(api)
Truth.assertThat(getNonNullConfig("freeCompileOnly")).isNotNull()
val apkOnly = getNonNullConfig("freeApk")
val runtimeOnly = getNonNullConfig("freeRuntimeOnly")
Truth.assertThat(runtimeOnly.extendsFrom).containsExactly(apkOnly)
// test test configuration
val testCompile = getNonNullConfig("testFreeCompile")
val testApi = getNonNullConfig("testFreeApi")
Truth.assertThat(testApi.extendsFrom).containsExactly(testCompile)
val testImpl = getNonNullConfig("testFreeImplementation")
Truth.assertThat(testImpl.extendsFrom).containsExactly(testApi, impl)
val testApkOnly = getNonNullConfig("testFreeApk")
val testRuntimeOnly = getNonNullConfig("testFreeRuntimeOnly")
Truth.assertThat(testRuntimeOnly.extendsFrom).containsExactly(runtimeOnly, testApkOnly)
// test androidTest configuration
val androidTestCompile = getNonNullConfig("androidTestFreeCompile")
val androidTestApi = getNonNullConfig("androidTestFreeApi")
Truth.assertThat(androidTestApi.extendsFrom).containsExactly(androidTestCompile)
val androidTestImpl = getNonNullConfig("androidTestFreeImplementation")
Truth.assertThat(androidTestImpl.extendsFrom).containsExactly(androidTestApi, impl)
val androidTestApkOnly = getNonNullConfig("androidTestFreeApk")
val androidTestRuntimeOnly = getNonNullConfig("androidTestFreeRuntimeOnly")
Truth.assertThat(androidTestRuntimeOnly.extendsFrom).containsExactly(runtimeOnly, androidTestApkOnly)
// always assert we haven't hit any deprecation
Truth.assertThat(deprecationReporter.deprecationWarnings).isEmpty()
}
@Test
fun `source sets for added build type`() {
val modelData = createModelData(
createFactories(BaseExtension2::class.java, VariantTypeImpl.BASE_APK))
val flavorName = "staging"
modelData.buildTypes.create(flavorName)
modelData.afterEvaluateCompute()
val data = modelData.buildTypeData[flavorName]
Truth.assertThat(data).isNotNull()
var sourceSet = data?.getSourceSet(VariantTypeImpl.BASE_APK)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo(flavorName)
sourceSet = data?.getSourceSet(VariantTypeImpl.ANDROID_TEST)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo("androidTestStaging")
sourceSet = data?.getSourceSet(VariantTypeImpl.UNIT_TEST)
Truth.assertThat(sourceSet).isNotNull()
Truth.assertThat(sourceSet?.name).isEqualTo("testStaging")
// always assert we haven't hit any deprecation
Truth.assertThat(deprecationReporter.deprecationWarnings).isEmpty()
}
@Test
fun `configurations for added build type`() {
val modelData = createModelData(
createFactories(BaseExtension2::class.java, VariantTypeImpl.BASE_APK))
val flavorName = "staging"
modelData.buildTypes.create(flavorName)
modelData.afterEvaluateCompute()
val compile = getNonNullConfig("stagingCompile")
val api = getNonNullConfig("stagingApi")
Truth.assertThat(api.extendsFrom).containsExactly(compile)
val impl = getNonNullConfig("stagingImplementation")
Truth.assertThat(impl.extendsFrom).containsExactly(api)
Truth.assertThat(getNonNullConfig("stagingCompileOnly")).isNotNull()
val apkOnly = getNonNullConfig("stagingApk")
val runtimeOnly = getNonNullConfig("stagingRuntimeOnly")
Truth.assertThat(runtimeOnly.extendsFrom).containsExactly(apkOnly)
// test test configuration
val testCompile = getNonNullConfig("testStagingCompile")
val testApi = getNonNullConfig("testStagingApi")
Truth.assertThat(testApi.extendsFrom).containsExactly(testCompile)
val testImpl = getNonNullConfig("testStagingImplementation")
Truth.assertThat(testImpl.extendsFrom).containsExactly(testApi, impl)
val testApkOnly = getNonNullConfig("testStagingApk")
val testRuntimeOnly = getNonNullConfig("testStagingRuntimeOnly")
Truth.assertThat(testRuntimeOnly.extendsFrom).containsExactly(runtimeOnly, testApkOnly)
// test androidTest configuration
val androidTestCompile = getNonNullConfig("androidTestStagingCompile")
val androidTestApi = getNonNullConfig("androidTestStagingApi")
Truth.assertThat(androidTestApi.extendsFrom).containsExactly(androidTestCompile)
val androidTestImpl = getNonNullConfig("androidTestStagingImplementation")
Truth.assertThat(androidTestImpl.extendsFrom).containsExactly(androidTestApi, impl)
val androidTestApkOnly = getNonNullConfig("androidTestStagingApk")
val androidTestRuntimeOnly = getNonNullConfig("androidTestStagingRuntimeOnly")
Truth.assertThat(androidTestRuntimeOnly.extendsFrom).containsExactly(runtimeOnly, androidTestApkOnly)
// always assert we haven't hit any deprecation
Truth.assertThat(deprecationReporter.deprecationWarnings).isEmpty()
}
@Test
fun `name collisions between flavor, build type and default values`() {
val modelData = createModelData(
createFactories(BaseExtension2::class.java, VariantTypeImpl.BASE_APK))
// first validate collision against forbidden names
val flavors = modelData.productFlavors
validateCollision(
flavors, "main","ProductFlavor names cannot be 'main'")
validateCollision(
flavors, "lint","ProductFlavor names cannot be 'lint'")
validateCollision(
flavors,
VariantType.ANDROID_TEST_PREFIX,
"ProductFlavor names cannot start with 'androidTest'")
validateCollision(
flavors,
VariantType.ANDROID_TEST_PREFIX + "Foo",
"ProductFlavor names cannot start with 'androidTest'")
validateCollision(
flavors,
VariantType.UNIT_TEST_PREFIX,
"ProductFlavor names cannot start with 'test'")
validateCollision(
flavors,
VariantType.UNIT_TEST_PREFIX + "Foo",
"ProductFlavor names cannot start with 'test'")
// same with build types
val buildTypes = modelData.buildTypes
validateCollision(
buildTypes, "main","BuildType names cannot be 'main'")
validateCollision(
buildTypes, "lint","BuildType names cannot be 'lint'")
validateCollision(
buildTypes,
VariantType.ANDROID_TEST_PREFIX,
"BuildType names cannot start with 'androidTest'")
validateCollision(
buildTypes,
VariantType.ANDROID_TEST_PREFIX + "Foo",
"BuildType names cannot start with 'androidTest'")
validateCollision(
buildTypes,
VariantType.UNIT_TEST_PREFIX,
"BuildType names cannot start with 'test'")
validateCollision(
buildTypes,
VariantType.UNIT_TEST_PREFIX + "Foo",
"BuildType names cannot start with 'test'")
// create a flavor and then a build type of the same name
flavors.create("foo")
validateCollision(
buildTypes,
"foo",
"BuildType names cannot collide with ProductFlavor names: foo")
// and the other way around
buildTypes.create("bar")
validateCollision(
flavors,
"bar",
"ProductFlavor names cannot collide with BuildType names: bar")
}
// ----
private fun getNonNullConfig(name: String): Configuration {
val config = configurationContainer.findByName(name)
Truth.assertThat(config).named(name).isNotNull()
return config!!
}
private fun checkNullConfiguration(name: String) {
val config = configurationContainer.findByName(name)
Truth.assertThat(config).named(name).isNull()
}
private fun <T> validateCollision(
container: NamedDomainObjectContainer<T>,
itemName: String,
expectedMessage: String) {
container.create(itemName)
Truth.assertThat(issueReporter.messages).containsExactly(expectedMessage)
issueReporter.messages.clear()
}
private fun <E: BaseExtension2> createModelData(
factories: List<VariantFactory2<E>>): DslModelDataImpl<E> {
val baseFlavor = BaseFlavorImpl(dslScope)
val defaultConfig = DefaultConfigImpl(
VariantPropertiesImpl(dslScope),
BuildTypeOrProductFlavorImpl(dslScope) { baseFlavor.postProcessing },
ProductFlavorOrVariantImpl(dslScope),
baseFlavor,
dslScope)
return DslModelDataImpl(
defaultConfig,
factories,
configurationContainer,
FakeFilesProvider(),
FakeContainerFactory(),
dslScope,
FakeLogger())
}
private fun <T: BaseExtension2> createFactories(
itemClass: Class<T>,
mainVariantType: VariantType,
hasAndroidTests: Boolean = true,
hasUnitTests: Boolean = true
): List<VariantFactory2<T>> {
val list = mutableListOf<VariantFactory2<T>>()
val testList = mutableListOf<VariantType>()
if (hasAndroidTests) {
testList.add(VariantTypeImpl.ANDROID_TEST)
}
if (hasUnitTests) {
testList.add(VariantTypeImpl.UNIT_TEST)
}
list.add(FakeVariantFactory2<BaseExtension2>(mainVariantType, testList, null))
if (hasAndroidTests) {
list.add(
FakeVariantFactory2<BaseExtension2>(
VariantTypeImpl.ANDROID_TEST, listOf(), mainVariantType))
}
if (hasUnitTests) {
list.add(
FakeVariantFactory2<BaseExtension2>(
VariantTypeImpl.UNIT_TEST, listOf(), mainVariantType))
}
return list
}
}