diff options
Diffstat (limited to 'library/test/robotest/src/com/android/setupwizardlib/robolectric')
2 files changed, 155 insertions, 0 deletions
diff --git a/library/test/robotest/src/com/android/setupwizardlib/robolectric/PatchedGradleManifestFactory.java b/library/test/robotest/src/com/android/setupwizardlib/robolectric/PatchedGradleManifestFactory.java new file mode 100644 index 0000000..64c63e7 --- /dev/null +++ b/library/test/robotest/src/com/android/setupwizardlib/robolectric/PatchedGradleManifestFactory.java @@ -0,0 +1,126 @@ +/* + * 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.setupwizardlib.robolectric; + +import org.robolectric.annotation.Config; +import org.robolectric.internal.GradleManifestFactory; +import org.robolectric.internal.ManifestIdentifier; +import org.robolectric.res.FileFsFile; +import org.robolectric.util.Logger; +import org.robolectric.util.ReflectionHelpers; + +import java.io.File; +import java.net.URL; + +/** + * Modified GradleManifestFactory to patch an issue where some build variants have merged + * resources under res/merged/variant/type while others have it under bundles/variant/type/res. + * + * The change is that in the .exists() checks below we check for specific folders for the build + * variant rather than checking existence at the parent directory. + */ +class PatchedGradleManifestFactory extends GradleManifestFactory { + + @Override + public ManifestIdentifier identify(Config config) { + if (config.constants() == Void.class) { + Logger.error("Field 'constants' not specified in @Config annotation"); + Logger.error("This is required when using Robolectric with Gradle!"); + throw new RuntimeException("No 'constants' field in @Config annotation!"); + } + + final String buildOutputDir = getBuildOutputDir(config); + final String type = getType(config); + final String flavor = getFlavor(config); + final String abiSplit = getAbiSplit(config); + final String packageName = config.packageName().isEmpty() + ? config.constants().getPackage().getName() + : config.packageName(); + + final FileFsFile res; + final FileFsFile assets; + final FileFsFile manifest; + + if (FileFsFile.from(buildOutputDir, "data-binding-layout-out", flavor, type).exists()) { + // Android gradle plugin 1.5.0+ puts the merged layouts in data-binding-layout-out. + // https://github.com/robolectric/robolectric/issues/2143 + res = FileFsFile.from(buildOutputDir, "data-binding-layout-out", flavor, type); + } else if (FileFsFile.from(buildOutputDir, "res", "merged", flavor, type).exists()) { + // res/merged added in Android Gradle plugin 1.3-beta1 + res = FileFsFile.from(buildOutputDir, "res", "merged", flavor, type); + } else if (FileFsFile.from(buildOutputDir, "res", flavor, type).exists()) { + res = FileFsFile.from(buildOutputDir, "res", flavor, type); + } else { + res = FileFsFile.from(buildOutputDir, "bundles", flavor, type, "res"); + } + + if (FileFsFile.from(buildOutputDir, "assets", flavor, type).exists()) { + assets = FileFsFile.from(buildOutputDir, "assets", flavor, type); + } else { + assets = FileFsFile.from(buildOutputDir, "bundles", flavor, type, "assets"); + } + + String manifestName = config.manifest(); + URL manifestUrl = getClass().getClassLoader().getResource(manifestName); + if (manifestUrl != null && manifestUrl.getProtocol().equals("file")) { + manifest = FileFsFile.from(manifestUrl.getPath()); + } else if (FileFsFile.from(buildOutputDir, "manifests", "full", flavor, abiSplit, type, + manifestName).exists()) { + manifest = FileFsFile.from( + buildOutputDir, "manifests", "full", flavor, abiSplit, type, manifestName); + } else if (FileFsFile.from(buildOutputDir, "manifests", "aapt", flavor, abiSplit, type, + manifestName).exists()) { + // Android gradle plugin 2.2.0+ can put library manifest files inside of "aapt" + // instead of "full" + manifest = FileFsFile.from(buildOutputDir, "manifests", "aapt", flavor, abiSplit, + type, manifestName); + } else { + manifest = FileFsFile.from(buildOutputDir, "bundles", flavor, abiSplit, type, + manifestName); + } + + return new ManifestIdentifier(manifest, res, assets, packageName, null); + } + + private static String getBuildOutputDir(Config config) { + return config.buildDir() + File.separator + "intermediates"; + } + + private static String getType(Config config) { + try { + return ReflectionHelpers.getStaticField(config.constants(), "BUILD_TYPE"); + } catch (Throwable e) { + return null; + } + } + + private static String getFlavor(Config config) { + try { + return ReflectionHelpers.getStaticField(config.constants(), "FLAVOR"); + } catch (Throwable e) { + return null; + } + } + + private static String getAbiSplit(Config config) { + try { + return config.abiSplit(); + } catch (Throwable e) { + return null; + } + } +} diff --git a/library/test/robotest/src/com/android/setupwizardlib/robolectric/SuwLibRobolectricTestRunner.java b/library/test/robotest/src/com/android/setupwizardlib/robolectric/SuwLibRobolectricTestRunner.java index 61baa23..509201a 100644 --- a/library/test/robotest/src/com/android/setupwizardlib/robolectric/SuwLibRobolectricTestRunner.java +++ b/library/test/robotest/src/com/android/setupwizardlib/robolectric/SuwLibRobolectricTestRunner.java @@ -20,13 +20,42 @@ import org.junit.runner.notification.RunNotifier; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.internal.ManifestFactory; public class SuwLibRobolectricTestRunner extends RobolectricTestRunner { + private String mModuleRootPath; + public SuwLibRobolectricTestRunner(Class<?> testClass) throws InitializationError { super(testClass); } + // Hack to determine the module root path in the build folder (e.g. out/gradle/setup-wizard-lib) + private void updateModuleRootPath(Config config) { + String moduleRoot = config.constants().getResource("").toString() + .replace("file:", "").replace("jar:", ""); + mModuleRootPath = + moduleRoot.substring(0, moduleRoot.lastIndexOf("/build")) + "/setup-wizard-lib"; + } + + /** + * Return the default config used to run Robolectric tests. + */ + @Override + protected Config buildGlobalConfig() { + Config parent = super.buildGlobalConfig(); + updateModuleRootPath(parent); + return new Config.Builder(parent) + .setBuildDir(mModuleRootPath + "/build") + .build(); + } + + @Override + protected ManifestFactory getManifestFactory(Config config) { + return new PatchedGradleManifestFactory(); + } + @Override protected void runChild(FrameworkMethod method, RunNotifier notifier) { System.out.println("===== Running " + method + " ====="); |