Last active
November 2, 2015 21:25
-
-
Save lordcodes/55801438a960ebbc2b2e to your computer and use it in GitHub Desktop.
Gradle code to fix issue in Robolectric when running tests on a library project. Based on an answer here (https://github.com/robolectric/robolectric/issues/1796), but altered to store the libraries in the build directory and to pull the package name from your build variants
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static groovy.io.FileType.FILES | |
// This task discovers the manifest files for the .aars that we depend on and | |
// adds them to project.ext.manifestFiles for use in later tasks. | |
task discoverManifestFiles(dependsOn: 'prepareDebugDependencies') << { | |
def aars = new File(project.buildDir.absolutePath + "/intermediates/exploded-aar") | |
def manifestFiles = new ArrayList<File>() | |
// Iterate through the exploded-aars directory, finding the manifests | |
aars.eachFileRecurse(FILES) { | |
if (it.name.endsWith('AndroidManifest.xml') && !it.absolutePath.contains('aapt')) { | |
manifestFiles.add(it) | |
} | |
} | |
project.ext.manifestFiles = manifestFiles; | |
} | |
// After gradle's done compiling the code, it'll run this to add some more tasks for us. | |
afterEvaluate { project -> | |
// Debug and release get their own tasks | |
android.libraryVariants.each { variant -> | |
def myPackageNamespace = variant.applicationId | |
def myPackagePath = myPackageNamespace.replaceAll("\\.", "/") | |
def processedPackages = new ArrayList<String>() | |
// Task one of two that we're adding: it depends on discovering manifest files | |
// and on processing resources for this build variant. It copies the merged R.java file | |
// from our project's namespace (which contains the resource IDs included in our | |
// dependencies) and drops it into each of our dependencies' namespaces. This is to work | |
// around limitations in robolectric. | |
def copyRJavaTaskName = "copy${variant.name.capitalize()}RJavaForRobolectric" | |
task(copyRJavaTaskName, | |
dependsOn: ["process${variant.name.capitalize()}Resources", "discoverManifestFiles"]) << { | |
// For each manifest file we discovered earlier, open it up an pull out the package | |
project.ext.manifestFiles.each { | |
def parsedManifestRoot = (new XmlParser()).parse(it.absolutePath) | |
def targetPackageNamespace = parsedManifestRoot.@package | |
// If it was already added, skip it | |
if(!processedPackages.contains(targetPackageNamespace)){ | |
processedPackages.add(targetPackageNamespace) | |
} else { | |
println "WARNING: Found two versions of $targetPackageNamespace; this could mess" + | |
" with your assets and resources" | |
// For some reason there are two versions of this dependency | |
// so skip additional iterations | |
return | |
} | |
def targetPackageNamespacePath = targetPackageNamespace.replaceAll("\\.", "/") | |
// Copy R.java from our outputs into the namespace of each dependency | |
// (and change the package line in the file, correspondingly) | |
copy { | |
from "build/generated/source/r/${variant.name}/$myPackagePath" | |
include 'R.java' | |
into "build/generated/source/r/${variant.name}/$targetPackageNamespacePath" | |
filter { line -> line.contains("package ${myPackageNamespace};") ? "package ${targetPackageNamespace};" : line } | |
} | |
} | |
} | |
// Insert this new task into the task tree: compiling unit tests depends on it. | |
tasks.getByName("compile${variant.name.capitalize()}UnitTestJavaWithJavac") dependsOn copyRJavaTaskName | |
// Second task we're adding: copy lib assets into the place where robolectric expects them. | |
// It depends on processing this variant's resources and on discovering manifest files. | |
def copyAssetsTaskName = "copy${variant.name.capitalize()}AssetsForRobolectric" | |
task(copyAssetsTaskName, | |
dependsOn: ["process${variant.name.capitalize()}Resources", "discoverManifestFiles"]) << { | |
// For each manifest file we discovered, find that project's assets folder and copy it | |
// to the same merged destination dir | |
project.ext.manifestFiles.each { | |
def manifestDirectory = it.parent | |
def src = "${manifestDirectory}/assets" | |
def dest = "build/intermediates/bundles/${variant.name}/assets" | |
copy { | |
from src | |
include '**/*' | |
into dest | |
} | |
} | |
} | |
// Insert this new task into the task tree: executing unit tests depends on it. | |
tasks.getByName("test${variant.name.capitalize()}UnitTest") dependsOn copyAssetsTaskName | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment