Skip to content

Instantly share code, notes, and snippets.

@scottaj
Last active December 16, 2015 19:19
Show Gist options
  • Save scottaj/5484758 to your computer and use it in GitHub Desktop.
Save scottaj/5484758 to your computer and use it in GitHub Desktop.
Errors getting scalatest to work with robolectric 1.2.
import sbt._
import Keys._
import AndroidKeys._
object General {
val settings = Defaults.defaultSettings ++ Seq (
name := "BlahBlah",
version := "0.1",
versionCode := 0,
scalaVersion := "2.10.1",
platformName in Android := "android-10"
)
val proguardSettings = Seq (
useProguard in Android := true,
// Config to stop Akka from dying
proguardOptimizations in Android += "-keep class com.typesafe.**",
proguardOptimizations in Android += "-keep class akka.**",
proguardOptimizations in Android += "-keep class scala.collection.immutable.StringLike {*;}",
proguardOptimizations in Android += "-keepclasseswithmembers class * {public <init>(java.lang.String, akka.actor.ActorSystem$Settings, akka.event.EventStream, akka.actor.Scheduler, akka.actor.DynamicAccess);}",
proguardOptimizations in Android += "-keepclasseswithmembers class * {public <init>(akka.actor.ExtendedActorSystem);}",
proguardOptimizations in Android += "-keep class scala.collection.SeqLike {public protected *;}",
// Standard Android options
proguardOptimizations in Android += "-keep public class * extends android.app.Application",
proguardOptimizations in Android += "-keep public class * extends android.app.Service",
proguardOptimizations in Android += "-keep public class * extends android.content.BroadcastReceiver",
proguardOptimizations in Android += "-keep public class * extends android.content.ContentProvider",
proguardOptimizations in Android += "-keep public class * extends android.view.View {public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...);}",
proguardOptimizations in Android += "-keepclasseswithmembers class * {public <init>(android.content.Context, android.util.AttributeSet);}",
proguardOptimizations in Android += "-keepclasseswithmembers class * {public <init>(android.content.Context, android.util.AttributeSet, int);}",
proguardOptimizations in Android += "-keepclassmembers class * extends android.content.Context {public void *(android.view.View); public void *(android.view.MenuItem);} ",
proguardOptimizations in Android += "-keepclassmembers class * implements android.os.Parcelable {static android.os.Parcelable$Creator CREATOR;}",
proguardOptimizations in Android += "-keepclassmembers class **.R$* {public static <fields>;}"
)
lazy val fullAndroidSettings =
General.settings ++
AndroidProject.androidSettings ++
TypedResources.settings ++
proguardSettings ++
AndroidManifestGenerator.settings ++
AndroidMarketPublish.settings ++ Seq (
keyalias in Android := "change-me",
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.1.0",
libraryDependencies += "org.scaloid" % "scaloid" % "1.0_8_2.10",
libraryDependencies += "com.pivotallabs" % "robolectric" % "1.2" % "test",
libraryDependencies += "org.scalatest" %% "scalatest" % "1.9.1" % "test"
)
}
object AndroidBuild extends Build {
lazy val main = Project (
"BlahBlah",
file("."),
settings = General.fullAndroidSettings
)
}
import android.net.Uri__FromAndroid
import com.xtremelabs.robolectric._
import com.xtremelabs.robolectric.bytecode._
import com.xtremelabs.robolectric.internal.RealObject
import com.xtremelabs.robolectric.res._
import com.xtremelabs.robolectric.shadows._
import com.xtremelabs.robolectric.util.{DatabaseConfig, SQLiteMap}
import com.xtremelabs.robolectric.util.DatabaseConfig._
import java.io.{File, FileOutputStream, PrintStream}
import org.scalatest._
trait RobolectricSuite extends Suite {
lazy val instrumentedClass = RobolectricSuite.classLoader.bootstrap(this.getClass)
lazy val instrumentedInstance = instrumentedClass.newInstance().asInstanceOf[RobolectricSuite]
lazy val robolectricConfig = new RobolectricConfig(new File("src/main"))
lazy val defaultDatabaseMap: DatabaseMap = new com.xtremelabs.robolectric.util.SQLiteMap()
lazy val resourceLoader = {
new ResourceLoader(robolectricConfig.getRealSdkVersion,
Class.forName(robolectricConfig.getRClassName),
robolectricConfig.getResourceDirectory,
robolectricConfig.getAssetsDirectory)
}
override def run(testName: Option[String],
reporter: Reporter,
stopper: Stopper,
filter: Filter,
configMap: Map[String, Any],
distributor: Option[Distributor],
tracker: Tracker) {
if (!isInstrumented) {
instrumentedInstance.beforeTest()
instrumentedInstance.run(testName, reporter, stopper, filter, configMap, distributor, tracker)
instrumentedInstance.afterTest()
} else {
super.run(testName, reporter, stopper, filter, configMap, distributor, tracker)
}
}
def isInstrumented = getClass.getClassLoader.getClass.getName.contains(classOf[RobolectricClassLoader].getName)
protected def beforeTest() {
setupApplicationState()
}
protected def afterTest() {}
protected def resetStaticState() {}
protected def bindShadowClasses() {}
protected def setupApplicationState() {
robolectricConfig.validate()
setupLogging()
Robolectric.bindDefaultShadowClasses()
bindShadowClasses()
Robolectric.resetStaticState()
resetStaticState()
DatabaseConfig.setDatabaseMap(setupDatabaseMap(getClass, defaultDatabaseMap))
Robolectric.application = ShadowApplication.bind(new ApplicationResolver(robolectricConfig).resolveApplication(), resourceLoader)
}
protected def setupLogging() {
val logging = System.getProperty("robolectric.logging")
if (logging != null && ShadowLog.stream == null) {
ShadowLog.stream = logging match {
case "stdout" => System.out
case "stderr" => System.err
case _ => {
val file = new PrintStream(new FileOutputStream(logging))
Runtime.getRuntime.addShutdownHook(new Thread() {
override def run() {
try {
file.close();
} catch { case e:Exception => }
}
})
file
}
}
}
}
protected def setupDatabaseMap(testClass: Class[_], map: DatabaseMap):DatabaseMap = {
if (testClass.isAnnotationPresent(classOf[UsingDatabaseMap])) {
val usingMap = testClass.getAnnotation(classOf[UsingDatabaseMap])
if (usingMap.value() != null) {
Robolectric.newInstanceOf(usingMap.value())
} else if (map == null) {
throw new RuntimeException("UsingDatabaseMap annotation value must provide a class implementing DatabaseMap")
} else {
map
}
} else {
map
}
}
}
object RobolectricSuite {
lazy val classHandler = ShadowWrangler.getInstance
lazy val classLoader = {
val loader = new RobolectricClassLoader(classHandler)
loader.delegateLoadingOf("org.scalatest.")
loader.delegateLoadingOf("org.mockito.")
loader.delegateLoadingOf("scala.")
List(
classOf[Uri__FromAndroid],
classOf[RobolectricSuite],
classOf[RealObject],
classOf[ShadowWrangler],
classOf[RobolectricConfig],
classOf[DatabaseMap],
classOf[android.R]
).foreach {
classToDelegate => loader.delegateLoadingOf(classToDelegate.getName)
}
loader
}
}
─$ sbt test 1 ↵
[info] Loading global plugins from /Users/al/.sbt/plugins
[info] Loading project definition from /Users/al/Projects/AO/reapso/android/project
[info] Set current project to Reapso (in build file:/Users/al/Projects/AO/reapso/android/)
[info] Wrote /Users/al/Projects/AO/reapso/android/target/scala-2.10/src_managed/main/scala/com/reapso/mobile/TR.scala
[info] Compiling 1 Scala source to /Users/al/Projects/AO/reapso/android/target/scala-2.10/test-classes...
[warn] Class android.animation.Animator not found - continuing with a stub.
[error] error while loading Robolectric, class file '/Users/al/.ivy2/cache/com.pivotallabs/robolectric/jars/robolectric-1.2.jar(com/xtremelabs/robolectric/Robolectric.class)' is broken
[error] (class java.lang.NullPointerException/)
[warn] one warning found
[error] one error found
[error] (test:compile) Compilation failed
[error] Total time: 3 s, completed Apr 29, 2013 5:03:01 PM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment