Merge branch 'master' into fix-java-encoding
diff --git a/build.gradle b/build.gradle
index 56d7ec8..ec6103c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -39,7 +39,11 @@
from javadoc.destinationDir
}
+ task provideBuildClasspath(type: ProvideBuildClasspathTask)
+
test {
+ dependsOn provideBuildClasspath
+
exclude "**/*\$*" // otherwise gradle runs static inner classes like TestRunnerSequenceTest$SimpleTest
testLogging {
events "failed"
diff --git a/buildSrc/src/main/groovy/ProvideBuildClasspathTask.groovy b/buildSrc/src/main/groovy/ProvideBuildClasspathTask.groovy
new file mode 100644
index 0000000..9ba6860
--- /dev/null
+++ b/buildSrc/src/main/groovy/ProvideBuildClasspathTask.groovy
@@ -0,0 +1,28 @@
+import org.gradle.api.DefaultTask
+import org.gradle.api.Project
+import org.gradle.api.tasks.TaskAction
+
+class ProvideBuildClasspathTask extends DefaultTask {
+ @TaskAction
+ public void writeProperties() throws Exception {
+ List<String> paths = new ArrayList<>()
+
+ project.rootProject.allprojects.each { Project otherProject ->
+ def match = otherProject.name =~ /robolectric-shadows\/(.*)/
+ if (match.matches()) {
+ def artifactName = "${otherProject.group}:${otherProject.mavenArtifactName()}:${otherProject.version}"
+ File classesDir = otherProject.sourceSets['main'].output.classesDir
+ File resourcesDir = otherProject.sourceSets['main'].output.resourcesDir
+ paths << "${artifactName.replaceAll(/:/, '\\\\:')}: ${classesDir}:${resourcesDir}"
+ }
+ }
+
+ File outDir = project.sourceSets['test'].output.resourcesDir
+ if (!outDir.directory) outDir.mkdirs()
+ File outFile = new File(outDir, 'robolectric-build-paths.properties')
+ outFile.withPrintWriter { out ->
+ out.println("# GENERATED by ${this} -- do not edit")
+ paths.each { path -> out.println path }
+ }
+ }
+}
diff --git a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
index 68cbaec..790306b 100644
--- a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
+++ b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
@@ -2,7 +2,6 @@
import android.app.Application;
import android.os.Build;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -23,10 +22,7 @@
import org.robolectric.internal.SdkConfig;
import org.robolectric.internal.SdkEnvironment;
import org.robolectric.internal.bytecode.*;
-import org.robolectric.internal.dependency.CachedDependencyResolver;
-import org.robolectric.internal.dependency.DependencyResolver;
-import org.robolectric.internal.dependency.LocalDependencyResolver;
-import org.robolectric.internal.dependency.MavenDependencyResolver;
+import org.robolectric.internal.dependency.*;
import org.robolectric.manifest.AndroidManifest;
import org.robolectric.res.OverlayResourceLoader;
import org.robolectric.res.PackageResourceLoader;
@@ -38,23 +34,13 @@
import org.robolectric.util.Pair;
import org.robolectric.util.ReflectionHelpers;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
+import java.io.*;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
+import java.net.URL;
import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
/**
* Installs a {@link org.robolectric.internal.bytecode.InstrumentingClassLoader} and
@@ -109,6 +95,22 @@
dependencyResolver = new MavenDependencyResolver();
}
}
+
+ URL buildPathPropertiesUrl = getClass().getClassLoader().getResource("robolectric-build-paths.properties");
+ if (buildPathPropertiesUrl != null) {
+ try {
+ Logger.info("Using Robolectric classes from %s", buildPathPropertiesUrl.getPath());
+
+ final Properties properties = new Properties();
+ InputStream stream = buildPathPropertiesUrl.openStream();
+ properties.load(stream);
+ stream.close();
+
+ dependencyResolver = new LocalBuildResolver(properties, dependencyResolver);
+ } catch (IOException e) {
+ throw new RuntimeException("couldn't read " + buildPathPropertiesUrl, e);
+ }
+ }
}
return dependencyResolver;
diff --git a/robolectric/src/main/java/org/robolectric/internal/dependency/DependencyJar.java b/robolectric/src/main/java/org/robolectric/internal/dependency/DependencyJar.java
index 4003b1d..368e4de 100644
--- a/robolectric/src/main/java/org/robolectric/internal/dependency/DependencyJar.java
+++ b/robolectric/src/main/java/org/robolectric/internal/dependency/DependencyJar.java
@@ -32,4 +32,14 @@
public String getClassifier() {
return classifier;
}
+
+ public String getShortName() {
+ return getGroupId() + ":" + getArtifactId() + ":" + getVersion()
+ + ((getClassifier() == null) ? "" : ":" + getClassifier());
+ }
+
+ @Override
+ public String toString() {
+ return "DependencyJar{" + getShortName() + '}';
+ }
}
diff --git a/robolectric/src/main/java/org/robolectric/internal/dependency/LocalBuildResolver.java b/robolectric/src/main/java/org/robolectric/internal/dependency/LocalBuildResolver.java
new file mode 100644
index 0000000..c68ae24
--- /dev/null
+++ b/robolectric/src/main/java/org/robolectric/internal/dependency/LocalBuildResolver.java
@@ -0,0 +1,57 @@
+package org.robolectric.internal.dependency;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+public class LocalBuildResolver implements DependencyResolver {
+ private final Properties properties;
+ private DependencyResolver delegate;
+
+ public LocalBuildResolver(Properties properties, DependencyResolver dependencyResolver) {
+ this.properties = properties;
+ delegate = dependencyResolver;
+ }
+
+ @Override
+ public URL[] getLocalArtifactUrls(DependencyJar... dependencies) {
+ List<URL> urls = new ArrayList<>();
+ for (DependencyJar dependency : dependencies) {
+ urls.addAll(getUrlsForDependency(dependency));
+ }
+ return urls.toArray(new URL[urls.size()]);
+ }
+
+ @Override
+ public URL getLocalArtifactUrl(DependencyJar dependency) {
+ List<URL> urls = getUrlsForDependency(dependency);
+ if (urls.size() != 1) {
+ throw new RuntimeException("should be exactly one URL for " + dependency + " but got " + urls);
+ } else {
+ return urls.get(0);
+ }
+ }
+
+ private List<URL> getUrlsForDependency(DependencyJar dependency) {
+ List<URL> urls = new ArrayList<>();
+ String depShortName = dependency.getShortName();
+ String path = properties.getProperty(depShortName);
+ if (path != null) {
+ for (String pathPart : path.split(":")) {
+ try {
+ URL url = new File(pathPart).toURI().toURL();
+ urls.add(url);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ } else {
+ urls.add(delegate.getLocalArtifactUrl(dependency));
+ }
+ return urls;
+ }
+
+}
diff --git a/robolectric/src/test/java/org/robolectric/internal/dependency/DependencyJarTest.java b/robolectric/src/test/java/org/robolectric/internal/dependency/DependencyJarTest.java
new file mode 100644
index 0000000..b7340ca
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/internal/dependency/DependencyJarTest.java
@@ -0,0 +1,15 @@
+package org.robolectric.internal.dependency;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DependencyJarTest {
+ @Test
+ public void testGetShortName() throws Exception {
+ assertThat(new DependencyJar("com.group", "artifact", "1.3", null).getShortName())
+ .isEqualTo("com.group:artifact:1.3");
+ assertThat(new DependencyJar("com.group", "artifact", "1.3", "dll").getShortName())
+ .isEqualTo("com.group:artifact:1.3:dll");
+ }
+}
\ No newline at end of file
diff --git a/robolectric/src/test/java/org/robolectric/internal/dependency/LocalBuildResolverTest.java b/robolectric/src/test/java/org/robolectric/internal/dependency/LocalBuildResolverTest.java
new file mode 100644
index 0000000..a70cf54
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/internal/dependency/LocalBuildResolverTest.java
@@ -0,0 +1,45 @@
+package org.robolectric.internal.dependency;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.URL;
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class LocalBuildResolverTest {
+
+ private LocalBuildResolver resolver;
+ private Properties properties;
+ private DependencyResolver mock;
+
+ @Before
+ public void setUp() throws Exception {
+ properties = new Properties();
+ mock = mock(DependencyResolver.class);
+ resolver = new LocalBuildResolver(properties, mock);
+ }
+
+ @Test
+ public void whenPathIsProvidedInProperties_shouldReturnFileUrls() throws Exception {
+ properties.setProperty("com.group:example:1.3", "/path/1:/path/2");
+ URL[] urls = resolver.getLocalArtifactUrls(new DependencyJar("com.group", "example", "1.3", null));
+ assertThat(urls).containsExactly(
+ new URL("file:///path/1"),
+ new URL("file:///path/2")
+ );
+ }
+
+ @Test
+ public void whenMissingFromProperties_shouldDelegate() throws Exception {
+ DependencyJar dependencyJar = new DependencyJar("com.group", "example", "1.3", null);
+ when(mock.getLocalArtifactUrl(dependencyJar)).thenReturn(new URL("file:///path/3"));
+ URL[] urls = resolver.getLocalArtifactUrls(dependencyJar);
+ assertThat(urls).containsExactly(
+ new URL("file:///path/3")
+ );
+ }
+}
\ No newline at end of file