Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to robolectric 4 #11

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'org.codehaus.groovy:groovy-android-gradle-plugin:2.0.0'
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'org.codehaus.groovy:groovy-android-gradle-plugin:2.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
Expand Down
17 changes: 3 additions & 14 deletions electricspock-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ apply plugin: 'maven'
artifactId='electricspock-core'
group='hkhc.electricspock'

//targetCompatibility = '1.7'
//sourceCompatibility = '1.7'

sourceSets {
test {
// Class.getResource won't work in unit test without this line.
// It ensure the test resources are in the same directory as classes
output.resourcesDir = "build/classes/test"
}
}

dependencies {

Expand All @@ -40,12 +30,11 @@ dependencies {
testRuntimeOnly files("build/classes/groovy/test")
testRuntimeOnly files("build/classes/groovy/main")

api "org.robolectric:robolectric:3.8"
api 'org.codehaus.groovy:groovy-all:2.4.13'
api "org.spockframework:spock-core:1.1-groovy-2.4"
api 'org.robolectric:robolectric:4.3'
api 'org.codehaus.groovy:groovy-all:2.5.0'
api 'org.spockframework:spock-core:1.3-groovy-2.5'

implementation 'org.jetbrains:annotations-java5:15.0'
implementation 'org.robolectric:android-all:7.1.0_r7-robolectric-0'

testImplementation 'junit:junit:4.12'
testImplementation 'org.assertj:assertj-core:1.7.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
package hkhc.electricspock

import org.junit.runner.RunWith
import spock.lang.Specification;
import spock.lang.Specification

/**
* Created by herman on 28/12/2016.
* Test Runner declared here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.junit.runner.manipulation.Sorter;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.InitializationError;
import org.robolectric.internal.SdkEnvironment;
import org.robolectric.internal.AndroidSandbox;
import org.spockframework.runtime.Sputnik;
import org.spockframework.runtime.model.SpecInfo;

Expand All @@ -48,7 +48,7 @@

public class ElectricSputnik extends Runner implements Filterable, Sortable {

private SdkEnvironment sdkEnvironment;
private AndroidSandbox sdkEnvironment;

/* it is used to setup Robolectric infrastructure, and not used to run actual test cases */
private ContainedRobolectricTestRunner containedRunner;
Expand All @@ -65,15 +65,17 @@ public class ElectricSputnik extends Runner implements Filterable, Sortable {
new SecureRandom(); // this starts up the Poller SunPKCS11-Darwin thread early, outside of any Robolectric classloader
}

public ElectricSputnik(Class<? extends Specification> specClass) throws InitializationError {
public ElectricSputnik(Class<? extends Specification> specClass) throws InitializationError {

/* The project is so sensitive to the version of Robolectric, that we strictly check
its version before proceed
*/
(new RobolectricVersionChecker()).checkRobolectricVersion();

containedRunner = new ContainedRobolectricTestRunner(specClass);
containedRunner = new ContainedRobolectricTestRunner();
sdkEnvironment = containedRunner.getContainedSdkEnvironment();


specInfoClass = sdkEnvironment.bootstrappedClass(SpecInfo.class);

// Since we have bootstrappedClass we may properly initialize
Expand All @@ -84,18 +86,19 @@ public ElectricSputnik(Class<? extends Specification> specClass) throws Initial
}

/**
* Sputnik is the test runner for Spock specification. This method Load the spec class and
* Sputnik class with Robolectric sandbox, so that Robolectric can intercept the Android API
* code. That's how we bridge Spock framework and Robolectric together.
* @param specClass the Specification class to be run under Sputnik
* Sputnik is the test runner for Spock specification. This method Load the spec class and
* Sputnik class with Robolectric sandbox, so that Robolectric can intercept the Android API
* code. That's how we bridge Spock framework and Robolectric together.
*
* @param specClass the Specification class to be run under Sputnik
*/
private Runner createSputnik(Class<? extends Specification> specClass) {

Class bootstrappedTestClass = sdkEnvironment.bootstrappedClass(specClass);

try {

return (Runner)sdkEnvironment
return (Runner) sdkEnvironment
.bootstrappedClass(Sputnik.class)
.getConstructor(Class.class)
.newInstance(bootstrappedTestClass);
Expand All @@ -113,9 +116,9 @@ private void registerSpec() {

Constructor interceptorConstructor = getInterceptorConstructor();

for(Method method : sputnik.getClass().getDeclaredMethods()) {
for (Method method : sputnik.getClass().getDeclaredMethods()) {
Object specInfo = getSpec(method);
if (specInfo!=null) {
if (specInfo != null) {
try {
// ElectricSpockInterceptor register itself to SpecInfo on construction,
// no need to keep a ref here
Expand All @@ -135,6 +138,7 @@ private void registerSpec() {
/**
* Get the SpecInfo from Specification. However, the SpecInfo instance it return will be under
* Robolectric sandbox, so it cannot be casted directly to SpecInfo statically.
*
* @param method the getSpec method
* @return the SpecInfo object loaded under Robolectric sandbox
*/
Expand All @@ -144,24 +148,24 @@ private Object getSpec(Method method) {
method.setAccessible(true);
try {
Object specInfo = method.invoke(sputnik);
if (specInfo.getClass()!=specInfoClass) {
if (specInfo.getClass() != specInfoClass) {
throw new RuntimeException("Failed to obtain SpecInfo instance from getSpec method. Instance of '"
+specInfo.getClass().getName()+"' is obtained");
+ specInfo.getClass().getName() + "' is obtained");
}
return specInfo;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
else {
} else {
return null;
}
}

/**
* Get a sandboxed constructor of interceptor
*
* @return
*/
private Constructor getInterceptorConstructor() {
Expand All @@ -173,22 +177,20 @@ private Constructor getInterceptorConstructor() {
specInfoClass,
ContainedRobolectricTestRunner.class
);
}
catch (NoSuchMethodException e) {
} catch (NoSuchMethodException e) {
// it should not happen in production code as the class
// ElectricSpockInterceptor is known
throw new RuntimeException(e);
}

}


public Description getDescription() {

Description originalDesc = sputnik.getDescription();

Class<?> testClass = originalDesc.getTestClass();
if (testClass==null) throw new RuntimeException("Unexpected null testClass");
if (testClass == null) throw new RuntimeException("Unexpected null testClass");

String title = null;
Annotation[] annotations = testClass.getAnnotations();
Expand All @@ -200,9 +202,9 @@ public Description getDescription() {
}

Description overridedDesc = Description.createSuiteDescription(
title==null ? testClass.getName() : title
title == null ? testClass.getName() : title
);
for(Description d: originalDesc.getChildren()) {
for (Description d : originalDesc.getChildren()) {
overridedDesc.addChild(d);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ public class RobolectricVersionChecker {
private String versionKey = "robolectric.version";

// *** update this for version upgrade
private String[] acceptedVersions = new String[] {"3.3","3.4", "3.5", "3.6", "3.7", "3.8"};
private String[] acceptedVersions = new String[]{"4,0", "4.1", "4.2", "4.3"};

public RobolectricVersionChecker() {}
public RobolectricVersionChecker() {
}

public RobolectricVersionChecker(String versionFile) {
this.versionFile = versionFile;
Expand All @@ -51,51 +52,42 @@ public void setAcceptedVersions(String[] acceptedVersions) {
}

public String getCurrentRobolectricVersion() {

try {

Properties prop = new Properties();
prop.load(getClass().getClassLoader().getResourceAsStream(versionFile));
return prop.getProperty(versionKey);
}
catch (Throwable t) {
} catch (Throwable t) {
return "Unknown";
}


}

public boolean isVersion(String version, String prefix) {

if (version==null) return false;
if (version == null) return false;

return version.equals(prefix) ||
version.indexOf(prefix+".")==0 ||
version.indexOf(prefix+"-")==0;

version.indexOf(prefix + ".") == 0 ||
version.indexOf(prefix + "-") == 0;
}

// return true if any of prefixes is matached.
public boolean isVersion(String version, String[] prefixes) {
for(String p : prefixes) {
for (String p : prefixes) {
if (isVersion(version, p)) return true;
}
return false;
}

public void checkRobolectricVersion(String ver) {

if (!isVersion(ver, acceptedVersions))
throw new RuntimeException(
"This version of ElectricSpock supports Robolectric 3.3.x to 3.8.x only. "
+"Version "+ver+" is detected.");
"This version of ElectricSpock supports Robolectric 4.0.x to 4.4.x only. "
+ "Version " + ver + " is detected. You can downgrade to a previous version " +
"of Electricspock to support older versions of Robolectric");
}

public void checkRobolectricVersion() {

String ver = getCurrentRobolectricVersion();
checkRobolectricVersion(ver);

}

}
Loading