Created
December 22, 2017 22:39
-
-
Save tifletcher/cf31570e9bccf5f4677c8695e93cfd80 to your computer and use it in GitHub Desktop.
Using locally defined traits for per-test state setup with scalatest. Much NIH.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.scalatest.FunSpec | |
class ScopedSpec extends FunSpec { | |
trait SpecScope { | |
val x = 1 | |
} | |
implicit val scopeConstructor = ScopeFactory(new SpecScope {}) | |
// or, without the aid of the ScopeFactory.apply: | |
// implicit object SpecScopeFactory extends ScopeFactory[SpecScope] { | |
// override def apply: SpecScope = new SpecScope {} | |
// } | |
describe("scope helper") { | |
it("must be able to create new default scopes") { | |
using[SpecScope]() { scope => | |
assert(scope.x == 1) | |
} | |
} | |
it("must be able to use explicitly overridden scopes") { | |
val s2 = new SpecScope { | |
override val x = 2 | |
} | |
using(s2) { scope => | |
assert(scope.x == 2) | |
} | |
} | |
it("can have scopes imported for a different feel")(using[SpecScope]() { scope => | |
import scope._ | |
assert(x == 1) | |
}) | |
} | |
// machinery. these go in a helper namespace somewhere | |
trait ScopeFactory[T] { | |
def apply: T | |
} | |
// optional. allows implicit creation as implicit val foo = ScopeFactory(new ScopeFactory{}) | |
object ScopeFactory { | |
def apply[T](constructor: => T): ScopeFactory[T] = new ScopeFactory[T] { | |
def apply = constructor | |
} | |
} | |
def using[T: ScopeFactory](scope: Option[T] = None)(block: T => Unit): Unit = scope match { | |
case Some(s) => block(s) | |
case _ => | |
val scope = implicitly[ScopeFactory[T]].apply | |
block(scope) | |
} | |
def using[T: ScopeFactory](scope: T)(block: T => Unit): Unit = using[T](Some(scope))(block) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment