Last active
January 8, 2016 21:47
-
-
Save EdgeCaseBerg/136c3d5946cdcc21e770 to your computer and use it in GitHub Desktop.
How to automatically test if you're providing appropriate matches if you need to parse string to some case objects without reflection in your code. Pretty fun stuff I think
This file contains hidden or 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
| package com.github.edgecaseberg.test { | |
| import scala.reflect.runtime.universe | |
| import scala.reflect.runtime.universe.typeOf | |
| import scala.util.Random | |
| import org.scalatest._ | |
| trait ParsingTest extends FlatSpec with Matchers { | |
| val random = new Random() | |
| def randomCase(s: String): String = { | |
| s.toList.map { c => | |
| if (random.nextBoolean()) { | |
| c.toString.toUpperCase | |
| } else { | |
| c.toString.toLowerCase | |
| } | |
| }.mkString.toString | |
| } | |
| val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader) | |
| def getSubclassesOf(t: universe.Type) = t.typeSymbol.asClass.knownDirectSubclasses | |
| def getObjectForCompanion(fullName: String) = { | |
| val module = runtimeMirror.staticModule(fullName) | |
| runtimeMirror.reflectModule(module) | |
| } | |
| } | |
| } | |
| package com.github.edgecaseberg { | |
| import scala.reflect.runtime.universe.typeOf | |
| import org.scalatest._ | |
| sealed abstract class MyAutomatic | |
| case object V0 extends MyAutomatic | |
| case object V1 extends MyAutomatic | |
| object MyAutomatic { | |
| val defaultVal = V0 | |
| /** Defaults to currentVersion if no match is found */ | |
| def fromString(s: String) = s.toLowerCase.trim match { | |
| case "v1" => V1 | |
| case "v0" => V0 | |
| case _ => defaultVal | |
| } | |
| } | |
| class MyAutomaticTest extends ParsingTest { | |
| "MyAutomatic" should "parse unknown text to a default value" in { | |
| assertResult(MyAutomatic.currentVersion) { | |
| MyAutomatic.fromString("hfhaskldjfhasldfjaskdjfhasdljkfskdjfals") | |
| } | |
| } | |
| val subClasses = getSubclassesOf[MyAutomatic] | |
| for (symbol <- subClasses) { | |
| val obj = getObjectForCompanion(symbol.fullName) | |
| it should s"convert ${symbol.name} to the correct enum" in { | |
| assertResult(obj.instance) { | |
| MyAutomatic.fromString(symbol.name.toString) | |
| } | |
| } | |
| it should s"convert ${symbol.name} regardless of case to the correct enum" in { | |
| val randomCases: List[String] = (1 to 10).map(i => randomCase(symbol.name.toString)).toList | |
| randomCases.map { r => | |
| assertResult(obj.instance) { | |
| MyAutomatic.fromString(r) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment