How do you use play scala specs2 matchers across multiple files - scala

I am using Play 2.2.1 with scala and trying to test with Specs2 matchers across multiple files. Everything works fine in one very large ApplicationSpec.scala file but I would like to move the code to separate files.
The following code is what I am using to test across multiple files but it is very intermittent.
ApplicationSpec.scala file
import org.specs2.mutable._
import org.specs2.mutable.Specification
import org.specs2.matcher.JsonMatchers
import org.specs2.runner._
import org.junit.runner._
#RunWith(classOf[JUnitRunner])
class ApplicationSpec extends PlaySpecification with JsonMatchers {
"Test using another file" should {
testing
"End of test" in {"End" must beEqualTo("End")}
}
This function is located inside the ApplicationSpec.scala file
def testing() {
"Multiple files" should {
"Testing testFile1" in {
testFile1.test1
testFile1.test2
"Test1 and Test2 should print before this line" in { 1 must beEqualTo(1)}
}
"Testing testFile2" in {
testFile2.test3
testFile2.test4
"Test3 and Test4 should print before this line" in { 1 must beEqualTo(1)}
}
}
}
testFile1.scala
object testFile1 extends ApplicationSpec {
def test1 {
"testFile1 - test1" in {1 must beEqualTo(1)}
}
def test2 {
"testFile1 - test2" in {1 must beEqualTo(1)}
}
}
testFile2.scala
object testFile2 extends ApplicationSpec {
def test3 {
"testFile2 - test3" in {1 must beEqualTo(1)}
}
def test4 {
"testFile2 - tes4" in {1 must beEqualTo(1)}
}
}
Test results Each time "play test" is run test1, test2, and test3, test4 may or may not print out. Sometimes all four tests show up or none of the tests are printed.
+ test WS logic
[info]
[info] Test using another file should
[info]
[info] Multiple files should
[info]
[info] Testing testFile1
[info] + Test1 and Test2 should print before this line
[info]
[info] Testing testFile2
[info] + testFile2 - test3
[info] + testFile2 - tes4
[info] + Test3 and Test4 should print before this line
[info] + End of test
[info]
[info] Total for specification testFile2
[info] Finished in 1 second, 713 ms
[info] 6 examples, 0 failure, 0 error
[info] testFile1
[info]
[info] Application should
[info] + test WS logic
[info]
[info] Test using another file should
[info]
[info] Multiple files should
[info]
[info] Testing testFile1
[info] + testFile1 - test1
[info] + testFile1 - test2
[info] + Test1 and Test2 should print before this line
[info]
[info] Testing testFile2
[info] + Test3 and Test4 should print before this line
[info] + End of test
[info]
[info] Total for specification testFile1
[info] Finished in 111 ms
[info] 6 examples, 0 failure, 0 error
[info] ApplicationSpec
[info]
[info] Application should
[info] + test WS logic
[info]
[info] Test using another file should
[info]
[info] Multiple files should
[info]
[info] Testing testFile1
[info] + Test1 and Test2 should print before this line
[info]
[info] Testing testFile2
[info] + Test3 and Test4 should print before this line
[info] + End of test
[info]
[info] Total for specification ApplicationSpec
[info] Finished in 99 ms
[info] 4 examples, 0 failure, 0 error

You can use traits to declare examples then import them to the main specification by mixing them in:
class TestSpec extends org.specs2.mutable.Specification with testFile1 with testFile2 {
"Test using another file" should {
testing
"End of test" in {"End" must beEqualTo("End")}
}
def testing {
"Multiple files" should {
"Testing testFile1" in {
tests1
"Test1 and Test2 should print before this line" in { 1 must beEqualTo(1)}
}
"Testing testFile2" in {
tests2
"Test3 and Test4 should print before this line" in { 1 must beEqualTo(1)}
}
}
}
trait testFile1 extends org.specs2.mutable.Specification {
def tests1 = {
"testFile1 - test1" in {1 must beEqualTo(1)}
"testFile1 - test2" in {1 must beEqualTo(1)}
}
}
trait testFile2 extends org.specs2.mutable.Specification {
def tests2 = {
"testFile2 - test3" in {1 must beEqualTo(1)}
"testFile2 - tes4" in {1 must beEqualTo(1)}
}
}

Related

initializate value only once before all tests runs

I want to initializate value only once before all tests runs
Now the value insertDbScheme create scheme in every test, if it possible to run it only once. Insert scheme from sbt task not suitable
I have two tests
test1:
class Test1 extends Specification with InsertDbScheme {
"test" in {
insertDbScheme
// some code
ok
}
}
test2:
class Test2 extends Specification with InsertDbScheme {
"test" in {
insertDbScheme
// some code
ok
}
}
and a base trait that insert scheme to database
trait InsertDbScheme {
lazy val insertDbScheme = {
println("insert scheme to database")
}
}
result of running tests
insert scheme to database
insert scheme to database
[info] Test1
[info]
[info] + test
[info]
[info]
[info] Total for specification Test1
[info] Finished in 152 ms
[info] 1 example, 0 failure, 0 error
[info]
[info] Test2
[info]
[info] + test
[info]
[info]
[info] Total for specification Test2
[info] Finished in 152 ms
[info] 1 example, 0 failure, 0 error
[info]
[info] ScalaCheck
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] Passed: Total 2, Failed 0, Errors 0, Passed 2
[success] Total time: 12 s, completed May 18, 2017 6:35:21 PM
You can use an object to make sure it's lazy val is only instantiated once:
trait InsertDbScheme {
import InsertDbScheme._
lazy val insertDbScheme = insertDbSchemeOnce
}
object InsertDbScheme {
lazy val insertDbSchemeOnce = {
println("insert scheme to database")
}
}
The easiest thing is to use a variable in a InsertDbScheme object:
trait InsertDbScheme {
def insertDbScheme = synchronized {
if (!InsertDbScheme.done) {
println("insert scheme to database")
InsertDbScheme.done = true
}
}
}
object InsertDbScheme {
var done = false
}

Running setup/teardown tasks during stb test task

I try to configure sbt to run a setup task at the beginning and a tear down task at the end of myProject/test command.
My build.sbt is here:
name := "ch-2"
version := "1.0"
libraryDependencies += "org.specs2" % "specs2_2.10" % "1.14" % "test"
lazy val common = (
Project("common", file("common")).
settings()
)
lazy val subPro = (
Project("sub", file("subA")).settings(
).dependsOn(common)
settings(libraryDependencies += "org.specs2" % "specs2_2.10" % "1.14" % "test" )
)
val startS = taskKey[Unit]("Start")
val stopS = taskKey[Unit]("Stop")
startS := { println("Running start")}
stopS := { println("Running stop")}
testOptions in Test in subPro += Tests.Setup { () => startS.value }
testOptions in Test in subPro += Tests.Cleanup { () => stopS.value }
The actual dummy test class is here:
import org.specs2.mutable.Specification
/**
* Created by jk on 26.3.2017.
*/
object FooSpec extends Specification {
"The TEST method" should {
"blaa blaa 1" in {
println("test 1 running...")
true
}
"blaa blaa 2" in {
println("test 2 running...")
true
}
}
}
When I run the tests for project sub, I get following output:
> sub/test
Running stop
Running start
[info] Updating {file:/home/jk/workspace/sbt-in-action/ch2/}sub...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /home/jk/workspace/sbt-in-action/ch2/subA/target/scala-2.10/test-classes...
test 1 running...
test 2 running...
[info] FooSpec
[info]
[info] The TEST method should
[info] + blaa blaa 1
[info] + blaa blaa 2
[info]
[info]
[info] Total for specification FooSpec
[info] Finished in 18 ms
[info] 2 examples, 0 failure, 0 error
[info]
[info] Passed: Total 2, Failed 0, Errors 0, Passed 2
[success] Total time: 3 s, completed Mar 26, 2017 7:09:34 PM
Why is stop task run even before compilation is finished and how to fix it so that it is run after all test cases are run (despite the result of the test cases)?
Also the start task should run after successfull compilation but before first test case. How to fix these?
How about doing it like this instead?
def startS(): Unit = { println("Running start")}
def stopS(): Unit = { println("Running stop")}
testOptions in Test in subPro += Tests.Setup { () => startS() }
testOptions in Test in subPro += Tests.Cleanup { () => stopS() }

Using Elastic4s to register a query with the percolator

I'm trying to register a percolator query with the elastic4s library. After much research I've found I need to use something like:
val myQuery = """ { "query" : { "match" : { "foo" : "bar" } } } """
esClient.execute( register id 12345 into "baz" query myQuery )
As if I'm doing this:
curl -XPUT 'localhost:9200/baz/.percolator/12345' -d '{
"query" : {
"match" : {
"foo" : "bar"
}
}
}'
But whenever I try running esClient.execute I end up getting a few parsing errors, but it works fine through the curl:
[info] org.elasticsearch.index.percolator.PercolatorException: failed to parse query [987654]
[info] at org.elasticsearch.index.percolator.PercolatorQueriesRegistry.parsePercolatorDocument(PercolatorQueriesRegistry.java:182)
[info] at org.elasticsearch.index.percolator.PercolatorQueriesRegistry$RealTimePercolatorOperationListener.preIndex(PercolatorQueriesRegistry.java:301)
[info] at org.elasticsearch.index.indexing.ShardIndexingService.preIndex(ShardIndexingService.java:146)
[info] at org.elasticsearch.index.shard.IndexShard.index(IndexShard.java:565)
[info] at org.elasticsearch.index.engine.Engine$Index.execute(Engine.java:836)
[info] at org.elasticsearch.action.support.replication.TransportReplicationAction.executeIndexRequestOnPrimary(TransportReplicationAction.java:1073)
[info] at org.elasticsearch.action.index.TransportIndexAction.shardOperationOnPrimary(TransportIndexAction.java:170)
[info] at org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryPhase.performOnPrimary(TransportReplicationAction.java:579)
[info] at org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryPhase$1.doRun(TransportReplicationAction.java:452)
[info] at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
[info] ...
[info] Cause: org.elasticsearch.index.query.QueryParsingException: Failed to parse query [{"query":{"match":{"foo":"bar"}}}]
[info] at org.elasticsearch.index.query.QueryStringQueryParser.parse(QueryStringQueryParser.java:243)
[info] at org.elasticsearch.index.query.QueryParseContext.parseInnerQuery(QueryParseContext.java:257)
[info] at org.elasticsearch.index.query.IndexQueryParserService.parseInnerQuery(IndexQueryParserService.java:244)
[info] at org.elasticsearch.index.percolator.PercolatorQueriesRegistry.parseQuery(PercolatorQueriesRegistry.java:208)
[info] at org.elasticsearch.index.percolator.PercolatorQueriesRegistry.parsePercolatorDocument(PercolatorQueriesRegistry.java:179)
[info] at org.elasticsearch.index.percolator.PercolatorQueriesRegistry$RealTimePercolatorOperationListener.preIndex(PercolatorQueriesRegistry.java:301)
[info] at org.elasticsearch.index.indexing.ShardIndexingService.preIndex(ShardIndexingService.java:146)
[info] at org.elasticsearch.index.shard.IndexShard.index(IndexShard.java:565)
[info] at org.elasticsearch.index.engine.Engine$Index.execute(Engine.java:836)
[info] at org.elasticsearch.action.support.replication.TransportReplicationAction.executeIndexRequestOnPrimary(TransportReplicationAction.java:1073)
[info] ...
[info] Cause: org.apache.lucene.queryparser.classic.ParseException: Cannot parse '{"query":{"match":{"foo":"bar"}}}': Encountered " "}" "} "" at line 1, column 30.
[info] Was expecting one of:
[info] "TO" ...
[info] <RANGE_QUOTED> ...
[info] <RANGE_GOOP> ...
[info] at org.apache.lucene.queryparser.classic.QueryParserBase.parse(QueryParserBase.java:123)
[info] at org.apache.lucene.queryparser.classic.MapperQueryParser.parse(MapperQueryParser.java:848)
[info] at org.elasticsearch.index.query.QueryStringQueryParser.parse(QueryStringQueryParser.java:227)
[info] at org.elasticsearch.index.query.QueryParseContext.parseInnerQuery(QueryParseContext.java:257)
[info] at org.elasticsearch.index.query.IndexQueryParserService.parseInnerQuery(IndexQueryParserService.java:244)
[info] at org.elasticsearch.index.percolator.PercolatorQueriesRegistry.parseQuery(PercolatorQueriesRegistry.java:208)
[info] at org.elasticsearch.index.percolator.PercolatorQueriesRegistry.parsePercolatorDocument(PercolatorQueriesRegistry.java:179)
[info] at org.elasticsearch.index.percolator.PercolatorQueriesRegistry$RealTimePercolatorOperationListener.preIndex(PercolatorQueriesRegistry.java:301)
[info] at org.elasticsearch.index.indexing.ShardIndexingService.preIndex(ShardIndexingService.java:146)
[info] at org.elasticsearch.index.shard.IndexShard.index(IndexShard.java:565)
[info] ...
[info] Cause: org.apache.lucene.queryparser.classic.ParseException: Encountered " "}" "} "" at line 1, column 30.
[info] Was expecting one of:
[info] "TO" ...
[info] <RANGE_QUOTED> ...
[info] <RANGE_GOOP> ...
[info] at org.apache.lucene.queryparser.classic.QueryParser.generateParseException(QueryParser.java:698)
[info] at org.apache.lucene.queryparser.classic.QueryParser.jj_consume_token(QueryParser.java:580)
[info] at org.apache.lucene.queryparser.classic.QueryParser.Term(QueryParser.java:394)
[info] at org.apache.lucene.queryparser.classic.QueryParser.Clause(QueryParser.java:247)
[info] at org.apache.lucene.queryparser.classic.QueryParser.Query(QueryParser.java:171)
[info] at org.apache.lucene.queryparser.classic.QueryParser.TopLevelQuery(QueryParser.java:160)
[info] at org.apache.lucene.queryparser.classic.QueryParserBase.parse(QueryParserBase.java:118)
[info] at org.apache.lucene.queryparser.classic.MapperQueryParser.parse(MapperQueryParser.java:848)
[info] at org.elasticsearch.index.query.QueryStringQueryParser.parse(QueryStringQueryParser.java:227)
[info] at org.elasticsearch.index.query.QueryParseContext.parseInnerQuery(QueryParseContext.java:257)
[info] ...
So I've got the feeling that I need to format the query differently, but it's not in the docs and I can't seem to find any examples out there. I've tried a few other formats like so:
val myQuery2 = """ "query" : { "match" : { "foo" : "bar" } } """
val myQuery3 = """ { "match" : { "foo" : "bar" } } """
val myQuery4 = """ "match" : { "foo" : "bar" } """
But nothing seems to be able to work, the only thing I've gotten to work was just having it like:
val myQuery5 = "query"
But with this I cannot specify what I actually want to match on. Anyone have any experience with this, or any ideas?
The query method accepts a string, but the string is a query string and not a json fragment as you have tried. If the query string format is not suitable, then you need to create the query using the elastic4s query dsl, eg
termQuery("field", "value")
or
matchQuery("field", "value")
etc. There are many query types, and they can be nested with a bool query.

Testing of click event fails

I am following the official tutorial of scala.js, and in the testing part there is some code like this:
package tutorial.webapp
import utest._
import org.scalajs.jquery.{JQuery, jQuery}
object TutorialTest extends TestSuite {
// Initialize App
TutorialApp.setupUI
def tests = TestSuite {
'HelloWorld {
val ps = jQuery("p:contains('Hello World')")
log("Number of hello-world paragraphs", ps.length)
assert(ps.length == 1)
}
'ButtonClick {
def messageCount =
jQuery("p:contains('Bang!')").length
val button = jQuery("button:contains('Click me!')")
log("Number of bang paragraphs", messageCount)
log("Number of button", button.length)
assert(button.length == 1)
assert(messageCount == 0)
for (c <- 1 to 5) {
log("Number of bang paragraphs", messageCount)
log("Number of button", button.length)
button.click()
assert(messageCount == c)
}
}
def log[A](header: String, msg: A): Unit = {
println(
"""
|
|
|=========================================
|%s : %s
|=========================================
|
|
""".format(header, msg.toString).stripMargin)
}
}
The event-based tests in the for loop fail in sbt test:
> test
[info] Compiling 1 Scala source to /Users/kaiyin/personal_config_bin_files/workspace/scalajsLearn/target/scala-2.11/test-classes...
=========================================
Number of hello-world paragraphs : 1
=========================================
=========================================
Number of bang paragraphs : 0
=========================================
=========================================
Number of button : 1
=========================================
=========================================
Number of bang paragraphs : 0
=========================================
=========================================
Number of button : 1
=========================================
[info] 1/3 tutorial.webapp.TutorialTest.HelloWorld Success
[info] 2/3 tutorial.webapp.TutorialTest.ButtonClick
[info] utest.AssertionError: assert(messageCount == c)
[info] c: Int = 1
[info] 3/3 tutorial.webapp.TutorialTest Success
[info] -----------------------------------Results-----------------------------------
[info] tutorial.webapp.TutorialTest Success
[info] HelloWorld Success
[info] ButtonClick Failure('utest.AssertionError: assert(messageCount == c)
[info] c: Int = 1')
[info] Failures:
[info] 2/3 tutorial.webapp.TutorialTest.ButtonClick
[info] utest.AssertionError: assert(messageCount == c)
[info] c: Int = 1
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala:39:42)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala:33:17)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/javalanglib/src/main/scala/java/lang/Throwables.scala:24:50)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/javalanglib/src/main/scala/java/lang/Throwables.scala:12:19)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Errors.scala:20:45)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/asserts/package.scala:19:5)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/asserts/package.scala:38:56)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:15:38)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/asserts/Asserts.scala:74:22)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:15:38)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/collection/IndexedSeqOptimized.scala:33:24)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/js/WrappedArray.scala:20:13)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/asserts/Asserts.scala:72:16)
[info] (file:/Users/kaiyin/personal_config_bin_files/workspace/scalajsLearn/src/test/scala/tutorial/webapp/TutorialTest.scala:32:15)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/scalalib/overrides-2.11/scala/collection/immutable/Range.scala:160:8)
[info] (file:/Users/kaiyin/personal_config_bin_files/workspace/scalajsLearn/src/test/scala/tutorial/webapp/TutorialTest.scala:28:14)
[info] (file:/Users/kaiyin/personal_config_bin_files/workspace/scalajsLearn/src/test/scala/tutorial/webapp/TutorialTest.scala:12:25)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:166:31)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:164:27)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:61:78)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:10:30)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/util/Try.scala:192:16)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:61:48)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:61:48)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/Option.scala:158:5)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:61:93)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:61:93)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/util/Try.scala:237:43)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/util/Try.scala:237:43)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:10:30)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/util/Try.scala:192:16)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/util/Try.scala:237:41)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/Future.scala:235:25)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/Future.scala:235:20)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:15:38)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:32:19)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/ExecutionContext.scala:16:21)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:40:25)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:280:61)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:270:28)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/Future.scala:235:16)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:153:9)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:61:37)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:59:11)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Future.scala:24:20)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Future.scala:23:15)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/ExecutionContext.scala:16:21)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Future.scala:31:29)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/Future.scala:492:114)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:107:14)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:82:100)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:81:54)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/Option.scala:158:5)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:81:47)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:83:24)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:15:38)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/Future.scala:251:31)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/Future.scala:249:16)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:15:38)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:32:19)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/ExecutionContext.scala:16:21)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:40:25)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:280:61)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:270:28)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/Future.scala:249:16)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Promise.scala:153:9)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:82:100)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:81:54)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/Option.scala:158:5)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:81:47)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:88:38)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:59:11)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Future.scala:24:20)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Future.scala:23:15)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/ExecutionContext.scala:16:21)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/impl/Future.scala:31:29)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/concurrent/Future.scala:492:114)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:107:14)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/framework/Model.scala:133:22)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/package.scala:135:6)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/runner/BaseRunner.scala:70:21)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/runner/BaseRunner.scala:95:35)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:30:68)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/runner/Task.scala:48:19)
[info] (file:/Users/haoyi/Dropbox%20(Personal)/Workspace/utest-new/utest/js/../shared/src/main/scala/utest/runner/Task.scala:31:17)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala:104:36)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala:104:36)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:10:30)
[info] (https://raw.githubusercontent.com/scala/scala/v2.11.7/src/library/scala/util/Try.scala:192:16)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala:104:23)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala:36:18)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala:31:7)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.5/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala:10:30)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala:69:7)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/Slave.scala:30:28)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/BridgeBase.scala:34:20)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/BridgeBase.scala:19:14)
[info] (https://raw.githubusercontent.com/scala-js/scala-js/v0.6.0/test-interface/src/main/scala/org/scalajs/testinterface/internal/BridgeBase.scala:19:14)
[info] Tests: 3
[info] Passed: 2
[info] Failed: 1
[error] Failed tests:
[error] tutorial.webapp.TutorialTest
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 2 s, completed 27 oct. 2015 21:00:35
The entire project is here: https://github.com/kindlychung/scalajstutorial
The click behavior is defined here:
package tutorial.webapp
/**
* Created by IDEA on 27/10/15.
*/
import scala.scalajs.js.JSApp
import org.scalajs.dom
import dom.document
import scala.scalajs.js.annotation.JSExport
import org.scalajs.jquery.jQuery
object TutorialApp extends JSApp {
def main(): Unit = {
setupUI
setupBehavior
}
def appendPar(targetNode: dom.Node, text: String): Unit = {
val parNode = document.createElement("p")
val textNode = document.createTextNode(text)
parNode.appendChild(textNode)
targetNode.appendChild(parNode)
}
def addClickedMessage(msg: String): Unit = {
jQuery("body").append("<p>%s</p>".format(msg))
}
def setupUI: Unit = {
jQuery("body").append("<p>Hello World!</p>")
jQuery("body").append("""<button id="click-me-button" type="button">Click me!</button>""")
}
def setupBehavior: Unit = {
jQuery("#click-me-button").click(() => addClickedMessage("Bang!"))
}
}
Your button indeed does nothing. Your test does not call setupBehavior, which registers the click event on the button. Therefore, calling click() doesn't do anything. No message is added, and the test correctly reports that there is no message.
Make sure to call setupBehavior to fix your issue.

scala.util.Try does not wrap Exception when used with Future and Play WS

My understanding is that scala.util.Try wraps exceptions thrown any code inside the Try { ... } block.
Here is a simple example that wraps a NullPointerException.
object TryDemo extends App {
import scala.util.{Failure, Success, Try}
def doSomething(i: Int): String = {
if (i > 50) {
println("going to throw NullPointerException at index " + i)
throw new NullPointerException("- Exception at index " + i)
}
else
"some-result"
}
val t: Try[String] = Try {
var x = 0
while (x < 100) {
doSomething(x)
x += 1
}
"result-" + x
}
val result: Option[String] = t match {
case Success(s) => println("success " + s); Some(s)
case Failure(f) => println("failure " + f.getMessage()); None
}
}
This gives the following output as excepted.
going to throw NullPointerException at index 51
failure - Exception at index 51
However, when I try to do the following (with an invalid URL to ensure that it fails every time)
import play.api.libs.ws._
val wsURL = "http://invalidurl:9000/something"
val wsres: Try[Future[Response]] = Try {
WS.url(wsURL).withRequestTimeout(200).withQueryString(("param", value)).get
}
Exceptions are thrown instead of getting an error that is wrapped inside a Try.
Can anyone please explain why it works in the first case and not in the second ?
[info] java.net.ConnectException: http://invalidurl:9000/something
[info] at com.ning.http.client.providers.netty.NettyConnectListener.operationComplete(NettyConnectListener.java:103)
[info] at org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultChannelFuture.java:427)
[info] at org.jboss.netty.channel.DefaultChannelFuture.addListener(DefaultChannelFuture.java:145)
[info] at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.doConnect(NettyAsyncHttpProvider.java:1068)
[info] at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.execute(NettyAsyncHttpProvider.java:890)
[info] at com.ning.http.client.AsyncHttpClient.executeRequest(AsyncHttpClient.java:520)
[info] at play.api.libs.ws.WS$WSRequest.execute(WS.scala:177)
[info] at play.api.libs.ws.WS$WSRequestHolder.get(WS.scala:386)
[info] at controllers.geojson.GeoJsonTransfomer$$anonfun$9.apply(GeoJsonTransformer.scala:155)
[info] at controllers.geojson.GeoJsonTransfomer$$anonfun$9.apply(GeoJsonTransformer.scala:155)
[info] ...
[info] Cause: java.nio.channels.UnresolvedAddressException:
[info] at sun.nio.ch.Net.checkAddress(Net.java:127)
[info] at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:640)
[info] at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.connect(NioClientSocketPipelineSink.java:108)
[info] at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.eventSunk(NioClientSocketPipelineSink.java:70)
[info] at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:54)
[info] at org.jboss.netty.handler.codec.http.HttpClientCodec.handleDownstream(HttpClientCodec.java:97)
[info] at org.jboss.netty.handler.stream.ChunkedWriteHandler.handleDownstream(ChunkedWriteHandler.java:109)
[info] at org.jboss.netty.channel.Channels.connect(Channels.java:634)
[info] at org.jboss.netty.channel.AbstractChannel.connect(AbstractChannel.java:207)
[info] at org.jboss.netty.bootstrap.ClientBootstrap.connect(ClientBootstrap.java:229)