javascript - How would you test a Scala.js library for equivalence of JVM and JS implementations? -


i'm using scala.js, , have written trait implemented both jvm , js. i'm using third-party jvm , js libraries implement in 2 sides, should provide functionally equivalent results in jvm , browser. but, need write test verify that!

if testing 2 vanilla scala implementations, i'd know how it. i'd write generators of trait's inputs, , drive each function those, comparing results of each. (i can assume either function results booleans, integers, longs, strings, collections of same, or tostring()'d.)

is out there doing kind of testing?

how 1 implementation in javascript? phantom? (can pass generated js file it, rather simple js-as-strings?) else?

you can use scala's reflective toolbox in macro execute test code @ compilation time (on jvm). can use result , generate code compares value.

so want write macro, given following code:

functest.test { (1.0).tostring } 

can generate this:

assert("1.0" == (1.0).tostring) 

this sounds harder in is. let's start macro skeleton functest:

import scala.language.experimental.macros import scala.reflect.macros.blackbox.context  object functest {   def test[t](x: => t): unit = macro functestimpl.impl[t] }  class functestimpl(val c: context) {   import c.universe._    def impl[t : weaktypetag](x: tree): tree = ??? } 

inside impl, want run code in x , generate assertion (or whatever suits test framework use):

import scala.reflect.runtime.{universe => ru} import scala.tools.reflect.toolbox  def impl[t : weaktypetag](x: tree): tree = {   // make tool box (runtime compiler , evaluater)   val mirror = ru.runtimemirror(getclass.getclassloader)   val toolbox = mirror.mktoolbox()    // import trees compile time runtime universe   val importer = ru.mkimporter(c.universe)   val tree = toolbox.untypecheck(importer.importtree(x))    // evaluate expression , make literal tree   val result = toolbox.eval(tree)   val resulttree = reifyliteral(result)    // emit assertion   q"assert($x == $resulttree)" } 

the problem have, reifyliteral. supposed take arbitrary value , create literal out of it. hard / impossible in general. however, easy basic values (primitives, strings, etc.):

/** creates literal tree out of value (if possible) */ private def reifyliteral(x: any): tree = x match {   case x: int => q"$x"   case x: string => q"$x"    // example seq   case x: seq[_] =>     val elems = x.map(reifyliteral)     q"seq(..$elems)"    case _ =>     c.abort(c.enclosingposition, s"cannot reify $x of type ${x.getclass}") } 

that's it. can write:

functest.test { /* code */ } 

to automatically generate tests computational libraries.

caveat toolbox not right classpath injected @ moment. if use external library (which assume do), need tweak well. let me know if need there.


Comments

Popular posts from this blog

javascript - Karma not able to start PhantomJS on Windows - Error: spawn UNKNOWN -

c# - Display ASPX Popup control in RowDeleteing Event (ASPX Gridview) -

Nuget pack csproj using nuspec -