How to run Scala test in Scala native application? - scala

I have hello world scala native app and wanted to run small scala test to this app I use the usual test command but it's throw an exception :
NativeMain.scala
object NativeMain {
val p = new Person("xxxx")
def main(args: Array[String]): Unit = {
println("Hello world")
}
}
class Person(var name: String)
}
NativeTest.scala
import org.scalatest.{FlatSpec, Matchers}
class NativeTest extends FlatSpec with Matchers {
"name" should "the name is set correctly in constructor" in {
assert(NativeMain.p.name == "xxxx")
}
}
I run test command in the sbt shell and got this error
[IJ]> test
[info] Compiling 1 Scala source to /home/****/Documents/ScalaNativeFresh/target/scala-2.11/classes...
[info] Compiling 1 Scala source to /home/****/Documents/ScalaNativeFresh/target/scala-2.11/test-classes...
[info] Compiling 1 Scala source to /home/****/Documents/ScalaNativeFresh/target/scala-2.11/test-classes...
[info] Linking (28516 ms)
[error] cannot link: #java.lang.Thread::getStackTrace_scala.scalanative.runtime.ObjectArray
[error] unable to link
[error] (nativetest:nativeLink) unable to link
[error] Total time: 117 s, completed Apr 2, 2019 3:04:24 PM
Any help or suggestions thank you :) ?

There is an open issue to add Add support for Scala Native #1112 and according to cheeseng:
3.1.0-SNAP6 and 3.2.0-SNAP10 are the only 2 versions (as of the time of writing) that supports scala-native
Try importing scalatest_native0.3_2.11 like so
libraryDependencies += "org.scalatest" % "scalatest_native0.3_2.11" % "3.2.0-SNAP10"
scalatest-native-example is a working example showing how to use scalatest with scala-native.

Related

Scala js `#JSGlobal` object reference error

I had this small snippet of code: -
import scala.scalajs.js
import scala.scalajs.js.annotation.JSGlobal
object Main2 extends App {
val js: Option[JS1] = for {
jsTest <- JSTest.js1.toOption
} yield jsTest
println(js)
}
#js.native
#JSGlobal
object JSTest extends js.Object {
def js1: js.UndefOr[JS1] = js.native
}
#js.native
trait JS1 extends js.Object {
def js1: js.UndefOr[JS2] = js.native
}
#js.native
trait JS2 extends js.Object {
def js2: js.UndefOr[Int] = js.native
}
When I try to run this I am getting this error: -
const value = JSTest.js1;
^
ReferenceError: JSTest is not defined
at $c_LMain2$.delayedEndpoint$Main2$1__V (D:\experiment\target\scala-2.13\file:\D:\experiment\src\main\scala\Main2.scala:8:15)
at $c_LMain2$delayedInit$body.apply__O (D:\experiment\target\scala-2.13\file:\D:\experiment\src\main\scala\Main2.scala:5:14)
at $f_s_App__main__AT__V (D:\experiment\target\scala-2.13\https:\raw.githubusercontent.com\scala\scala\v2.13.2\src\library\scala\Function0.scala:39:7)
at $s_LMain2__main__AT__V (D:\experiment\target\scala-2.13\file:\D:\experiment\src\main\scala\Main2.scala:5:8)
at D:\experiment\target\scala-2.13\experiment-fastopt.js:9360:1
at D:\experiment\target\scala-2.13\experiment-fastopt.js:9361:4
at Script.runInThisContext (vm.js:132:18)
at Object.runInThisContext (vm.js:315:38)
at [stdin]:8:25
at Script.runInThisContext (vm.js:132:18)
[error] org.scalajs.jsenv.ExternalJSRun$NonZeroExitException: exited with code 1
[error] at org.scalajs.jsenv.ExternalJSRun$$anon$1.run(ExternalJSRun.scala:186)
[error] stack trace is suppressed; run last Compile / run for the full output
[error] (Compile / run) org.scalajs.jsenv.ExternalJSRun$NonZeroExitException: exited with code 1
[error] Total time: 7 s, completed 20-Aug-2020, 5:47:54 pm
According to scala-js doc: - https://www.scala-js.org/doc/interoperability/global-scope.html
It should run but throwing this error can anybody let me know what the issue here?
build.sbt
name := "experiment"
version := "0.1"
scalaVersion := "2.13.3"
enablePlugins(ScalaJSPlugin)
scalaJSUseMainModuleInitializer := true
configuration:-
Scala -> 2.13.3, SBT -> 1.3.13, JVM -> Java 14, scala-js -> 1.1.1
This question was asked because of porting issue from scala 0.6.33 to scala 1.1.1 and The solution for this is answered on this: -
scala-js "#JSGlobalScope" error when migrating to scala-js 1.1.1

Scala Play + Slick: How to inject dependencies to Spec tests?

I'm using Scala Play 2.7.x (the project is available here Play-Silhouette-Seed) and would like to test my daos. I have put together this simple one first to check what's the "new pattern" for testing play + slick + guice in 2.7.x:
package models.daos
import java.util.UUID
import org.specs2.mock._
import org.specs2.mutable._
import utils.AwaitUtil
import javax.inject.Inject
import models.generated.Tables.LoginInfoRow
class LoginInfoDaoSpec #Inject() (loginInfoDao: LoginInfoDao) extends Specification with Mockito with AwaitUtil {
"Creating a new LoginInfo" should {
"save it in the empty database" in {
loginInfoDao.create(LoginInfoRow(0, UUID.randomUUID().toString, UUID.randomUUID().toString))
loginInfoDao.findAll.size should beEqualTo(1)
}
}
}
Unfortunately, the guice dependency LoginInfoDao is not being provided to my test and then I get the error:
[play-silhouette-seed] $ testOnly models.daos.LoginInfoDaoSpec
[info] Done compiling.
[error] Can't find a suitable constructor with 0 or 1 parameter for class models.daos.LoginInfoDao
[info] ScalaTest
[info] Run completed in 1 second, 966 milliseconds.
[info] Total number of tests run: 0
[info] Suites: completed 0, aborted 0
[info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0
[info] No tests were executed.
[error] Error: Total 1, Failed 0, Errors 1, Passed 0
How do I get guice loading the needed modules for my test-cases?
A module is defined as:
class SilhouetteModule extends AbstractModule with ScalaModule {
override def configure() {
// ...
bind[LoginInfoDao].to[LoginInfoDaoImpl]
// ...
}
}
and I have an application.test.conf available defined as:
include "application.conf"
slick.dbs {
default {
profile="slick.jdbc.MySQLProfile$"
db.driver="com.mysql.cj.jdbc.Driver"
db.url="jdbc:mysql://localhost:3306/mytestdb?useUnicode=true&searchpath=public&serverTimezone=CET"
db.user="dev"
db.password="12345"
}
}
You should use another database for testing, H2 is the common choice.
class Module extends AbstractModule with ScalaModule {
...
}
With that name you need to let play know there is a Module to load, if you call it Module, it automatically know what to load and should work just fine (if you only need 1 module in testing)
If that doesn't work let me know

Could not instantiate controllers.WebJarAssets during testing

Play is working fine when I am using sbt run. However, when I am trying to do such test:
#RunWith(classOf[JUnitRunner])
class MarketApiSpec extends Specification {
"Market API" should {
"load product list" in new WithApplication {
val completed = route(FakeRequest("GET", "/api/products")).get.map(x => Json.parse(x.body.toString()))
val jsonObject = Await.result(completed, Duration("1s"))
jsonObject.get("products").get(0).get("name").asText() must beEqualTo("Programmer");
}
}
}
By a sbt test I get such error exception:
[info] Market API should
[info] ! load product list
[error] RuntimeException: : java.lang.NoClassDefFoundError: Could not initialize class controllers.WebJarAssets$ (Action.scala:523)
[error] play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:523)
I googled a lot, however I didn't find the solution. I think its related to sbt somehow, but even giving a test scope doesn't help.

Play test-only doesn't ignore tests

I have a play application and I need to ignore my functional tests when I compile and build, then later run only the integration tests.
This is my test code:
ApplicationSpec.scala
#RunWith(classOf[JUnitRunner])
class ApplicationSpec extends Specification {
"Application" should {
"send 404 on a bad request" in new WithApplication {
route(FakeRequest(GET, "/boum")) must beNone
}
}
IntegrationSpec.scala
#RunWith(classOf[JUnitRunner])
class IntegrationSpec extends Specification {
"Application" should {
"work from within a browser" in {
running(TestServer(9000), FIREFOX) { browser =>
browser.goTo("http://localhost:9000/app")
browser.pageSource must contain("Your new application is ready.")
}
}
} section "integration"
}
The docs tells me I can use something like this from the command line:
play "test-only -- exclude integration"
The only problem is that this doesn't actually exclude any tests and my integration tests invoke firefox and start running. What am I doing wrong? How can I exclude the integration tests and then later run them by themselves?
sbt's Testing documentation describes several ways to define separate test configurations.
For instance, the Additional test configurations with shared sources example could be used in this situation:
In this approach, the sources are compiled together using the same classpath and are packaged together. However, different tests are run depending on the configuration.
In a default Play Framework 2.2.2 application created with play new, add a file named project/Build.scala with this content:
import sbt._
import Keys._
object B extends Build {
lazy val root =
Project("root", file("."))
.configs(FunTest)
.settings(inConfig(FunTest)(Defaults.testTasks) : _*)
.settings(
libraryDependencies += specs,
testOptions in Test := Seq(Tests.Filter(unitFilter)),
testOptions in FunTest := Seq(Tests.Filter(itFilter))
)
def itFilter(name: String): Boolean = (name endsWith "IntegrationSpec")
def unitFilter(name: String): Boolean = (name endsWith "Spec") && !itFilter(name)
lazy val FunTest = config("fun") extend(Test)
lazy val specs = "org.specs2" %% "specs2" % "2.0" % "test"
}
To run standard unit tests:
$ sbt test
Which produces:
[info] Loading project definition from /home/fernando/work/scratch/so23160453/project
[info] Set current project to so23160453 (in build file:/home/fernando/work/scratch/so23160453/)
[info] ApplicationSpec
[info] Application should
[info] + send 404 on a bad request
[info] + render the index page
[info] Total for specification ApplicationSpec
[info] Finished in 974 ms
[info] 2 examples, 0 failure, 0 error
[info] Passed: Total 2, Failed 0, Errors 0, Passed 2
[success] Total time: 3 s, completed Apr 22, 2014 12:42:37 PM
To run tests for the added configuration (here, "fun"), prefix it with the configuration name:
$ sbt fun:test
Which produces:
[info] Loading project definition from /home/fernando/work/scratch/so23160453/project
[info] Set current project to so23160453 (in build file:/home/fernando/work/scratch/so23160453/)
[info] IntegrationSpec
[info] Application should
[info] + work from within a browser
[info] Total for specification IntegrationSpec
[info] Finished in 0 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 6 s, completed Apr 22, 2014 12:43:17 PM
You can also test only a particular class, like this:
$ sbt "fun:testOnly IntegrationSpec"
See this example in GitHub.

Play Framework specs2 Fails to Fail

I have an interesting problem with testing using the WithApplication scope from Play 2.1.1.
Here is my code:
import play.api.test.{FakeApplication, WithApplication}
import org.specs2.mutable.Specification
class TestSpec extends Specification {
"Test" should {
"fail" in {
true === false
}
"fail as well" in new WithApplication() {
true === false
}
"fail with extreme prejudice" in new WithApplication(FakeApplication()) {
true === false
}
}
}
I would expect all 3 of these to fail but in this case only the first one failed.
[info] Total for specification TestSpec
[info] Finished in 21 ms
[info] 3 examples, 1 failure, 0 error
[info]
[error] Failed: : Total 4, Failed 1, Errors 0, Passed 3, Skipped 0
[error] Failed tests:
[error] TestSpec
Is there some trick I'm missing here?
I'm using Scala 2.10.2, sbt 0.12.2, Play 2.1.1 and runnning on Java 7 U40.
Thanks in advance.
You should try a latest version of Play or the latest version of specs2 (2.2.3) where this issue has been fixed.