blob: d4b07bf12f54992e45df325c6c6fd6572de76a50 [file] [log] [blame]
/*
* Copyright (C) 2019 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.integration.library
import com.android.build.gradle.integration.common.fixture.GradleTestProject
import com.android.build.gradle.integration.common.fixture.app.HelloWorldApp
import com.android.build.gradle.integration.common.fixture.app.TestSourceFile
import com.android.build.gradle.internal.scope.InternalArtifactType
import com.android.build.gradle.integration.common.utils.getBuildType
import com.android.build.gradle.integration.common.utils.getProductFlavor
import com.android.builder.model.AndroidProject
import com.android.builder.model.ClassField
import com.google.common.base.Charsets
import com.google.common.collect.Maps
import com.google.common.io.Files
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.BeforeClass
import org.junit.ClassRule
import org.junit.Test
import java.io.File
import java.io.IOException
/**
* Test for BuildConfig field declared in build type, flavors, and variant and how they override
* each other.
*
* Forked from [com.android.build.gradle.integration.application.BuildConfigTest].
*/
class LibraryBuildConfigTest {
companion object {
@JvmStatic
@get:ClassRule
val project: GradleTestProject =
GradleTestProject.builder().fromTestApp(HelloWorldApp.noBuildFile().also {
it.addFile(
TestSourceFile(
"build.gradle",
"""
apply plugin: 'com.android.library'
android {
compileSdkVersion ${GradleTestProject.DEFAULT_COMPILE_SDK_VERSION}
defaultConfig {
buildConfigField "int", "VALUE_DEFAULT", "1"
buildConfigField "int", "VALUE_DEBUG", "1"
buildConfigField "int", "VALUE_FLAVOR", "1"
buildConfigField "int", "VALUE_VARIANT", "1"
}
buildTypes {
debug {
buildConfigField "int", "VALUE_DEBUG", "100"
buildConfigField "int", "VALUE_VARIANT", "100"
}
}
flavorDimensions 'foo'
productFlavors {
flavor1 {
buildConfigField "int", "VALUE_DEBUG", "10"
buildConfigField "int", "VALUE_FLAVOR", "10"
buildConfigField "int", "VALUE_VARIANT", "10"
}
flavor2 {
buildConfigField "int", "VALUE_DEBUG", "20"
buildConfigField "int", "VALUE_FLAVOR", "20"
buildConfigField "int", "VALUE_VARIANT", "20"
}
}
libraryVariants.all { variant ->
if (variant.buildType.name == "debug") {
variant.buildConfigField "int", "VALUE_VARIANT", "1000"
}
}
}
""".trimIndent()
)
)
}).create()
private lateinit var model: AndroidProject
@JvmStatic
@BeforeClass
fun setUp() {
model = project.executeAndReturnModel(
"clean",
"generateFlavor1DebugBuildConfig",
"generateFlavor1ReleaseBuildConfig",
"generateFlavor2DebugBuildConfig",
"generateFlavor2ReleaseBuildConfig"
).onlyModel
}
}
@Test
@Throws(IOException::class)
fun testFlavor1Debug() {
val expected = """
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.example.helloworld;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String LIBRARY_PACKAGE_NAME = "com.example.helloworld";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "flavor1";
// Field from build type: debug
public static final int VALUE_DEBUG = 100;
// Field from default config.
public static final int VALUE_DEFAULT = 1;
// Field from product flavor: flavor1
public static final int VALUE_FLAVOR = 10;
// Field from the variant API
public static final int VALUE_VARIANT = 1000;
}
""".trimIndent()
doCheckBuildConfig(expected, "flavor1/debug")
}
@Test
fun modelDefaultConfig() {
val map = Maps.newHashMap<String, String>()
map["VALUE_DEFAULT"] = "1"
map["VALUE_FLAVOR"] = "1"
map["VALUE_DEBUG"] = "1"
map["VALUE_VARIANT"] = "1"
checkMaps(map, model.defaultConfig.productFlavor.buildConfigFields, "defaultConfig")
}
@Test
fun modelFlavor1() {
val map = Maps.newHashMap<String, String>()
map["VALUE_FLAVOR"] = "10"
map["VALUE_DEBUG"] = "10"
map["VALUE_VARIANT"] = "10"
checkFlavor(model, "flavor1", map)
}
@Test
@Throws(IOException::class)
fun buildFlavor2Debug() {
val expected = ("""
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.example.helloworld;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String LIBRARY_PACKAGE_NAME = "com.example.helloworld";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "flavor2";
// Field from build type: debug
public static final int VALUE_DEBUG = 100;
// Field from default config.
public static final int VALUE_DEFAULT = 1;
// Field from product flavor: flavor2
public static final int VALUE_FLAVOR = 20;
// Field from the variant API
public static final int VALUE_VARIANT = 1000;
}
""").trimIndent()
doCheckBuildConfig(expected, "flavor2/debug")
}
@Test
fun modelFlavor2() {
val map = Maps.newHashMap<String, String>()
map["VALUE_FLAVOR"] = "20"
map["VALUE_DEBUG"] = "20"
map["VALUE_VARIANT"] = "20"
checkFlavor(model, "flavor2", map)
}
@Test
fun buildFlavor1Release() {
val expected = """
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.example.helloworld;
public final class BuildConfig {
public static final boolean DEBUG = false;
public static final String LIBRARY_PACKAGE_NAME = "com.example.helloworld";
public static final String BUILD_TYPE = "release";
public static final String FLAVOR = "flavor1";
// Field from product flavor: flavor1
public static final int VALUE_DEBUG = 10;
// Field from default config.
public static final int VALUE_DEFAULT = 1;
// Field from product flavor: flavor1
public static final int VALUE_FLAVOR = 10;
// Field from product flavor: flavor1
public static final int VALUE_VARIANT = 10;
}
""".trimIndent()
doCheckBuildConfig(expected, "flavor1/release")
}
@Test
fun modelDebug() {
val map = Maps.newHashMap<String, String>()
map["VALUE_DEBUG"] = "100"
map["VALUE_VARIANT"] = "100"
checkBuildType(model, "debug", map)
}
@Test
@Throws(IOException::class)
fun buildFlavor2Release() {
val expected = """
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.example.helloworld;
public final class BuildConfig {
public static final boolean DEBUG = false;
public static final String LIBRARY_PACKAGE_NAME = "com.example.helloworld";
public static final String BUILD_TYPE = "release";
public static final String FLAVOR = "flavor2";
// Field from product flavor: flavor2
public static final int VALUE_DEBUG = 20;
// Field from default config.
public static final int VALUE_DEFAULT = 1;
// Field from product flavor: flavor2
public static final int VALUE_FLAVOR = 20;
// Field from product flavor: flavor2
public static final int VALUE_VARIANT = 20;
}
""".trimIndent()
doCheckBuildConfig(expected, "flavor2/release")
}
@Test
fun modelRelease() {
checkBuildType(model, "release", emptyMap())
}
private fun doCheckBuildConfig(expected: String, variantDir: String) {
if (project.getIntermediateFile(
InternalArtifactType.COMPILE_BUILD_CONFIG_JAR.getFolderName()).exists()) {
return
}
val outputFile = File(
project.projectDir,
"build/generated/source/buildConfig/"
+ variantDir
+ "/com/example/helloworld/BuildConfig.java"
)
Assert.assertTrue("Missing file: $outputFile", outputFile.isFile)
assertEquals(
expected,
Files.asByteSource(outputFile).asCharSource(Charsets.UTF_8).read()
)
}
private fun checkFlavor(
androidProject: AndroidProject,
flavorName: String,
valueMap: Map<String, String>?
) {
val productFlavor = androidProject.getProductFlavor(flavorName).productFlavor
assertNotNull("$flavorName variant null-check", productFlavor)
checkMaps(valueMap, productFlavor.buildConfigFields, flavorName)
}
private fun checkBuildType(
androidProject: AndroidProject,
buildTypeName: String,
valueMap: Map<String, String>?
) {
val buildType = androidProject.getBuildType(buildTypeName).buildType
assertNotNull("$buildTypeName flavor null-check", buildType)
checkMaps(valueMap, buildType.buildConfigFields, buildTypeName)
}
private fun checkMaps(
valueMap: Map<String, String>?,
value: Map<String, ClassField>?,
name: String
) {
assertNotNull(value)
// check the map against the expected one.
assertEquals(valueMap!!.keys, value!!.keys)
for (key in valueMap.keys) {
val field = value[key]
assertNotNull("$name: expected field $key", field)
assertEquals(
"$name: check Value of $key", valueMap[key], field!!.value
)
}
}
}