LeakCanaryLeakDeobfuscationPluginTest.kt
TLDR
This file contains the unit tests for the LeakCanaryLeakDeobfuscationPlugin
class in the leakcanary.deobfuscation
package.
Methods
No methods are defined in this file.
Classes
LeakCanaryLeakDeobfuscationPluginTest
This class contains unit tests for the LeakCanaryLeakDeobfuscationPlugin
class. The tests verify that the plugin correctly copies the mapping file into the APK assets directory, doesn't copy the mapping file if it hasn't been configured, and throws an exception if there is no variant with enabled minification.
package com.squareup.leakcanary.deobfuscation
import org.assertj.core.api.Assertions.assertThat
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome.SUCCESS
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import java.io.File
import java.util.zip.ZipFile
class LeakCanaryLeakDeobfuscationPluginTest {
@get:Rule
val tempFolder = TemporaryFolder()
private lateinit var buildFile: File
@Before
fun setup() {
buildFile = tempFolder.newFile("build.gradle")
val localPropertiesFile = File("../local.properties")
if (localPropertiesFile.exists()) {
localPropertiesFile.copyTo(File(tempFolder.root, "local.properties"), overwrite = true)
} else {
System.getenv("ANDROID_HOME")?.let { androidHome ->
tempFolder.newFile("local.properties").apply {
writeText("sdk.dir=$androidHome")
}
}
}
File("src/test/test-project").copyRecursively(tempFolder.root)
val proguardRules = tempFolder.newFile("proguard-rules.pro")
proguardRules.writeText(
"""
-keep class com.leakcanary.test.** {*;}
""".trimIndent()
)
}
@Test
fun `leakcanary deobfuscation plugin runs and copies mapping file into the apk assets dir`() {
buildFile.writeText(
"""
plugins {
id 'com.android.application'
id 'com.squareup.leakcanary.deobfuscation'
}
allprojects {
repositories {
google()
jcenter()
}
}
android {
namespace 'com.leakcanary.test'
compileSdk 29
defaultConfig {
minSdk 29
}
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
leakCanary {
filterObfuscatedVariants { variant ->
variant.name == "debug"
}
}
""".trimIndent()
)
val result = GradleRunner.create()
.withProjectDir(tempFolder.root)
.withArguments("clean", "assembleDebug")
.withPluginClasspath()
.build()
// task has been run
assertThat(
result.task(":leakCanaryCopyObfuscationMappingForDebug")?.outcome == SUCCESS
).isTrue()
// apk has been built
val apkFile = File(tempFolder.root, "build/outputs/apk/debug")
.listFiles()
?.firstOrNull { it.extension == "apk" }
assertThat(apkFile != null).isTrue()
// mapping file has been generated by proguard/r8
val mappingFile = File(tempFolder.root, "build/outputs/mapping/debug/mapping.txt")
assertThat(mappingFile.exists()).isTrue()
// apk contains obfuscation mapping file in assets dir
val obfuscationMappingEntry = ZipFile(apkFile).use { zipFile ->
zipFile.entries().toList().firstOrNull { entry ->
entry.name.contains("assets/leakCanaryObfuscationMapping.txt")
}
}
assertThat(obfuscationMappingEntry != null).isTrue()
}
@Test
fun `leakcanary deobfuscation plugin doesn't copy mapping file if it hasn't been configured`() {
buildFile.writeText(
"""
plugins {
id 'com.squareup.leakcanary.deobfuscation'
id 'com.android.application'
}
allprojects {
repositories {
google()
jcenter()
}
}
android {
namespace 'com.leakcanary.test'
compileSdk 29
defaultConfig {
minSdk 29
}
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
""".trimIndent()
)
GradleRunner.create()
.withProjectDir(tempFolder.root)
.withArguments("clean", "assembleDebug")
.withPluginClasspath()
.build()
// apk has been built
val apkFile = File(tempFolder.root, "build/outputs/apk/debug")
.listFiles()
?.firstOrNull { it.extension == "apk" }
assertThat(apkFile != null).isTrue()
// apk doesn't contain obfuscation mapping file in assets dir
val obfuscationMappingEntry = ZipFile(apkFile).use { zipFile ->
zipFile.entries().toList().firstOrNull { entry ->
entry.name.contains("assets/leakCanaryObfuscationMapping.txt")
}
}
assertThat(obfuscationMappingEntry == null).isTrue()
}
@Test
fun `should throw if there is no variant with enabled minification`() {
buildFile.writeText(
"""
plugins {
id 'com.android.application'
id 'com.squareup.leakcanary.deobfuscation'
}
allprojects {
repositories {
google()
jcenter()
}
}
android {
namespace 'com.leakcanary.test'
compileSdk 29
defaultConfig {
minSdk 29
}
buildTypes {
debug {}
}
}
leakCanary {
filterObfuscatedVariants { variant ->
variant.name == "debug"
}
}
""".trimIndent()
)
val result = GradleRunner.create()
.withProjectDir(tempFolder.root)
.withArguments("clean", "assembleDebug")
.withPluginClasspath()
.buildAndFail()
assertThat(
result.output.contains(
"LeakCanary deobfuscation plugin couldn't find any variant with minification enabled."
)
).isTrue()
}
}