forked from scala-js/scala-js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integrate unit testing framework with sbt test discovery.
- Tests can now be run using the test facilities built in sbt. To use it you need to add a dependency on a Scala.js test framework (for example Scala.js jasmine test framework) and add a marker interface (`scala.scalajs.test.Test`) to your test classes (or extend JasmineTest when using the Scala.js jasmine test framework). - The default Scala.js test framework and Scala.js test bridge class can be changed using sbt settings. - A reference implementation of the test framework using jasmine is provided. - Added experimental support for `env.js` in the run and test environment. Just add `env.js` webjar as a dependency to your project. - Run command now searches for objects that have a `main` method (normal sbt behavior).
- Loading branch information
Showing
58 changed files
with
1,560 additions
and
559 deletions.
There are no files selected for viewing
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
Empty file.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import scala.scalajs.js.Dynamic.global | ||
|
||
object ElementCreator { | ||
val jQ = global.jQuery | ||
|
||
def create() = jQ("body").append(jQ("<h1>Test</h1>")) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import scala.scalajs.js | ||
import scala.scalajs.js.Dynamic.global | ||
import scala.scalajs.test.JasmineTest | ||
|
||
object ElementCreatorTest extends JasmineTest { | ||
|
||
// ElementCreator expects jquery to be present | ||
global.importScripts("jquery.js") | ||
|
||
describe("ElementCreator") { | ||
|
||
it("should be able to create an element in the body") { | ||
// create the element | ||
ElementCreator.create() | ||
|
||
// jquery would make this easier, but I wanted to | ||
// only use pure html in the test itself | ||
val body = global.document.getElementsByTagName("body") | ||
.asInstanceOf[js.Array[js.Dynamic]].head | ||
|
||
// the Scala.js DOM API would make this easier | ||
expect(body.firstChild.tagName.toString == "H1").toBeTruthy | ||
expect(body.firstChild.innerHTML.toString == "Test").toBeTruthy | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
jasmine-test-framework/src/main/scala/org/scalajs/jasmine/Jasmine.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.scalajs.jasmine | ||
|
||
import scala.scalajs.js | ||
|
||
object Jasmine extends js.GlobalScope { | ||
def describe(name: String, suite: js.Function0[_]): Unit = ??? | ||
def it(title: String, test: js.Function0[_]): Unit = ??? | ||
def xdescribe(name: String, suite: js.Function0[_]): Unit = ??? | ||
def xit(title: String, test: js.Function0[_]): Unit = ??? | ||
def beforeEach(block: js.Function0[_]): Unit = ??? | ||
def afterEach(block: js.Function0[_]): Unit = ??? | ||
def expect(exp: js.Any): JasmineExpectation = ??? | ||
} |
9 changes: 1 addition & 8 deletions
9
...ala/scalajs/test/JasmineExpectation.scala → .../scalajs/jasmine/JasmineExpectation.scala
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
13 changes: 13 additions & 0 deletions
13
jasmine-test-framework/src/main/scala/org/scalajs/jasmine/Results.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.scalajs.jasmine | ||
|
||
import scala.scalajs.js | ||
|
||
trait Result extends js.Object { | ||
def `type`: js.String = ??? | ||
val trace: js.Dynamic = ??? | ||
} | ||
|
||
trait ExpectationResult extends Result { | ||
def passed(): js.Boolean = ??? | ||
val message: js.String = ??? | ||
} |
9 changes: 9 additions & 0 deletions
9
jasmine-test-framework/src/main/scala/org/scalajs/jasmine/Spec.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.scalajs.jasmine | ||
|
||
import scala.scalajs.js | ||
|
||
trait Spec extends js.Object { | ||
def results(): SpecResults = ??? | ||
val description: js.String = ??? | ||
val suite: Suite = ??? | ||
} |
8 changes: 8 additions & 0 deletions
8
jasmine-test-framework/src/main/scala/org/scalajs/jasmine/SpecResults.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.scalajs.jasmine | ||
|
||
import scala.scalajs.js | ||
|
||
trait SpecResults extends js.Object { | ||
def passed(): js.Boolean = ??? | ||
def getItems(): js.Array[Result] = ??? | ||
} |
8 changes: 8 additions & 0 deletions
8
jasmine-test-framework/src/main/scala/org/scalajs/jasmine/Suite.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.scalajs.jasmine | ||
|
||
import scala.scalajs.js | ||
|
||
trait Suite extends js.Object { | ||
def results(): SuiteResults = ??? | ||
val description: js.String = ??? | ||
} |
9 changes: 9 additions & 0 deletions
9
jasmine-test-framework/src/main/scala/org/scalajs/jasmine/SuiteResults.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.scalajs.jasmine | ||
|
||
import scala.scalajs.js | ||
|
||
trait SuiteResults extends js.Object { | ||
val passedCount: js.Number = ??? | ||
val failedCount: js.Number = ??? | ||
val totalCount: js.Number = ??? | ||
} |
8 changes: 6 additions & 2 deletions
8
...cala/scala/scalajs/test/ScalaJSTest.scala → ...cala/scala/scalajs/test/JasmineTest.scala
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
168 changes: 168 additions & 0 deletions
168
jasmine-test-framework/src/main/scala/scala/scalajs/test/JasmineTestFramework.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
/* __ *\ | ||
** ________ ___ / / ___ __ ____ Scala.js Test Framework ** | ||
** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** | ||
** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** | ||
** /____/\___/_/ |_/____/_/ | |__/ /____/ ** | ||
** |/____/ ** | ||
\* */ | ||
|
||
|
||
package scala.scalajs.test | ||
|
||
import scala.scalajs.js | ||
import scala.scalajs.js.Dynamic.global | ||
import scala.scalajs.js.JavaScriptException | ||
|
||
import org.scalajs.jasmine.ExpectationResult | ||
import org.scalajs.jasmine.Result | ||
import org.scalajs.jasmine.Spec | ||
import org.scalajs.jasmine.Suite | ||
|
||
object JasmineTestFramework extends TestFramework { | ||
|
||
/* Stub-out timer methods used by Jasmine and not provided by Rhino. */ | ||
if (!global.setTimeout) { | ||
global.setTimeout = scalaJSStub("setTimeout") | ||
global.clearTimeout = scalaJSStub("clearTimeout") | ||
global.setInterval = scalaJSStub("setInterval") | ||
global.clearInterval = scalaJSStub("clearInterval") | ||
} | ||
|
||
def scalaJSStub(name: String): js.Function = { () => | ||
global.console.log("Stub for " + name + " called") | ||
} | ||
|
||
// make sure jasmine is loaded | ||
global.importScripts("jasmine.js") | ||
|
||
def runTests(testOutput: TestOutput)(tests: => Unit): Unit = { | ||
val jasmine = global.jasmine | ||
val reporter = new JasmineTestFramework(testOutput) | ||
|
||
try { | ||
tests | ||
|
||
val jasmineEnv = jasmine.getEnv() | ||
jasmineEnv.addReporter(reporter.asInstanceOf[js.Any]) | ||
jasmineEnv.updateInterval = 0 | ||
jasmineEnv.execute() | ||
} catch { | ||
case JavaScriptException(exception) => | ||
val stack = exception.asInstanceOf[js.Dynamic].stack | ||
testOutput.error("Problem executing code in tests: " + exception, | ||
reporter.getScriptStack(stack)) | ||
} | ||
} | ||
} | ||
|
||
class JasmineTestFramework(testOutput: TestOutput) { | ||
private var currentSuite: Suite = _ | ||
|
||
def reportRunnerStarting(): Unit = { | ||
testOutput.log.info("") | ||
} | ||
|
||
def reportSpecStarting(spec: Spec): Unit = { | ||
if (currentSuite != spec.suite) { | ||
currentSuite = spec.suite | ||
info(currentSuite.description) | ||
} | ||
} | ||
|
||
def reportSpecResults(spec: Spec): Unit = { | ||
val results = spec.results() | ||
val description = spec.description | ||
|
||
if (results.passed) { | ||
testOutput.succeeded(s" $success $description") | ||
} else { | ||
error(s" $failure $description") | ||
|
||
results.getItems foreach displayResult | ||
} | ||
} | ||
|
||
def reportSuiteResults(suite: Suite): Unit = { | ||
var results = suite.results() | ||
|
||
info("") | ||
val title = "Total for suite " + suite.description | ||
val message = | ||
s"${results.totalCount} specs, ${results.failedCount} failure" | ||
|
||
if (results.passedCount != results.totalCount) { | ||
error(title) | ||
errorWithInfoColor(message) | ||
} else { | ||
info(title) | ||
infoWithInfoColor(message) | ||
} | ||
info("") | ||
} | ||
|
||
def reportRunnerResults(): Unit = { | ||
// no need to report | ||
} | ||
|
||
private def info(str: String) = | ||
testOutput.log.info(str) | ||
|
||
private def infoWithInfoColor(str: String) = | ||
info(withColor(testOutput.infoColor, str)) | ||
|
||
private def errorWithInfoColor(str: String) = | ||
error(withColor(testOutput.infoColor, str)) | ||
|
||
private def error(msg: js.Any) = | ||
testOutput.log.error(msg.toString) | ||
|
||
private def withColor(color: String, message: String) = | ||
testOutput.color(message, color) | ||
|
||
private def sanitizeMessage(message: String) = { | ||
val FilePattern = """^(.+?) [^ ]+\.js \(line \d+\)\.*?$""".r | ||
val EvalPattern = """^(.+?) in eval.+\(eval\).+?\(line \d+\).*?$""".r | ||
|
||
message match { | ||
case FilePattern(originalMessage) => originalMessage | ||
case EvalPattern(originalMessage) => originalMessage | ||
case message => message | ||
} | ||
} | ||
|
||
private def failure = withColor(testOutput.errorColor, "x") | ||
private def success = withColor(testOutput.successColor, "+") | ||
|
||
private def displayResult(result: Result) = { | ||
(result.`type`: String) match { | ||
case "log" => | ||
info(s" ${result.toString}") | ||
case "expect" => | ||
val r = result.asInstanceOf[ExpectationResult] | ||
if (!r.passed()) { | ||
val message = sanitizeMessage(r.message) | ||
val stack = getScriptStack(r.trace.stack) | ||
|
||
if (stack.isEmpty) testOutput.failure(s" $message") | ||
else testOutput.error(s" $message", stack) | ||
} | ||
} | ||
} | ||
|
||
private def getScriptStack(stack: js.Any): Array[ScriptStackElement] = { | ||
if (stack.isInstanceOf[js.String]) { | ||
val StackTracePattern = """^(.+?) ([^ ]+\.js):(\d+).*?$""".r | ||
val stackString: String = stack.asInstanceOf[js.String] | ||
|
||
stackString | ||
.split("\n") | ||
.map { | ||
case StackTracePattern(originalMessage, fileName, lineNumber) => | ||
ScriptStackElement(fileName, "", lineNumber.toInt) | ||
case unknown => | ||
throw JavaScriptException("Unknown stack element: " + unknown) | ||
} | ||
.takeWhile(e => !(e.fileName contains "jasmine.js")) | ||
} else Array.empty | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
library/src/main/scala/scala/scalajs/test/EventProxy.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* __ *\ | ||
** ________ ___ / / ___ __ ____ Scala.js API ** | ||
** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** | ||
** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** | ||
** /____/\___/_/ |_/____/_/ | |__/ /____/ ** | ||
** |/____/ ** | ||
\* */ | ||
|
||
|
||
package scala.scalajs.test | ||
|
||
import scala.scalajs.js | ||
|
||
trait EventProxy extends js.Object { | ||
def error(message: js.String, stack: js.Array[js.Dictionary]): Unit = ??? | ||
def failure(message: js.String, stack: js.Array[js.Dictionary]): Unit = ??? | ||
def succeeded(message: js.String): Unit = ??? | ||
def skipped(message: js.String): Unit = ??? | ||
def pending(message: js.String): Unit = ??? | ||
def ignored(message: js.String): Unit = ??? | ||
def canceled(message: js.String): Unit = ??? | ||
|
||
def error(message: js.String): Unit = ??? | ||
def info(message: js.String): Unit = ??? | ||
} |
20 changes: 11 additions & 9 deletions
20
...st/scala/scala/scalajs/test/Jasmine.scala → ...ala/scalajs/test/ScriptStackElement.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,22 @@ | ||
/* __ *\ | ||
** ________ ___ / / ___ __ ____ Scala.js Test Suite ** | ||
** ________ ___ / / ___ __ ____ Scala.js API ** | ||
** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** | ||
** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** | ||
** /____/\___/_/ |_/____/_/ | |__/ /____/ ** | ||
** |/____/ ** | ||
\* */ | ||
|
||
|
||
package scala.scalajs.test | ||
|
||
import scala.scalajs.js | ||
|
||
object Jasmine extends js.GlobalScope { | ||
def describe(name: String, suite: js.Function0[_]): Unit = ??? | ||
def it(title: String, test: js.Function0[_]): Unit = ??? | ||
def xdescribe(name: String, suite: js.Function0[_]): Unit = ??? | ||
def xit(title: String, test: js.Function0[_]): Unit = ??? | ||
def beforeEach(block: js.Function0[_]): Unit = ??? | ||
def afterEach(block: js.Function0[_]): Unit = ??? | ||
def expect(exp: js.Any): JasmineExpectation = ??? | ||
class ScriptStackElement( | ||
val fileName: String, | ||
val functionName: String, | ||
val lineNumber: Int) | ||
|
||
object ScriptStackElement { | ||
def apply(fileName: String, functionName: String, lineNumber: Int) = | ||
new ScriptStackElement(fileName, functionName, lineNumber) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* __ *\ | ||
** ________ ___ / / ___ __ ____ Scala.js API ** | ||
** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL ** | ||
** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ ** | ||
** /____/\___/_/ |_/____/_/ | |__/ /____/ ** | ||
** |/____/ ** | ||
\* */ | ||
|
||
|
||
package scala.scalajs.test | ||
|
||
/** Marker trait for Scala.js tests */ | ||
trait Test |
Oops, something went wrong.