Skip to content

Instantly share code, notes, and snippets.

@pfn
Forked from jberkel/RobolectricSuite.scala
Last active October 4, 2015 15:47
Show Gist options
  • Save pfn/2662806 to your computer and use it in GitHub Desktop.
Save pfn/2662806 to your computer and use it in GitHub Desktop.
RobolectricSuite
import org.scalatest.Suite
import org.scalatest.Reporter
import org.scalatest.Stopper
import org.scalatest.Filter
import org.scalatest.Tracker
import org.scalatest.Distributor
import com.xtremelabs.robolectric.Robolectric
import com.xtremelabs.robolectric.ApplicationResolver
import com.xtremelabs.robolectric.RobolectricConfig
import com.xtremelabs.robolectric.bytecode.RobolectricClassLoader
import com.xtremelabs.robolectric.bytecode.ShadowWrangler
import com.xtremelabs.robolectric.internal.RealObject
import com.xtremelabs.robolectric.res.ResourceLoader
import com.xtremelabs.robolectric.util.DatabaseConfig
import com.xtremelabs.robolectric.util.DatabaseConfig.DatabaseMap
import com.xtremelabs.robolectric.util.DatabaseConfig.UsingDatabaseMap
import com.xtremelabs.robolectric.shadows.ShadowApplication
import com.xtremelabs.robolectric.shadows.ShadowLog
import java.io.File
import java.io.FileOutputStream
import java.io.PrintStream
import android.net.Uri__FromAndroid
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("."))
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
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment