Scala.js matchers with facades types - scala

I cannot get basic tests using matchers working with Scala.js with Three.js facade. Following code prints error "scala.scalajs.js.JavaScriptException: TypeError: Cannot read property 'isArray__Z' of null".
import org.denigma.threejs.Vector3
import org.scalatest.{FlatSpec, Matchers}
class TestVector extends FlatSpec with Matchers {
"Vector" should "work" in {
val v000 = new Vector3(0, 0, 0)
v000 should be (v000)
}
}
Complete project shared at GitHub.
I guess it must be something related to facaded native types, as tests with classes defined in Scala work fine.
I did not find any gotchas documented regarding Scala.js and matchers. Am I missing something obvious?
Complete stack trace of the error:
[info] - should work *** FAILED ***
[info] scala.scalajs.js.JavaScriptException: TypeError: Cannot read property 'isArray__Z' of null
[info] at scala.runtime.ScalaRunTime$.isArrayClass(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:19470:14)
[info] at scala.runtime.ScalaRunTime$.isArray(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:19461:32)
[info] at org.scalatest.Assertions$.areEqualComparingArraysStructurally(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:30299:29)
[info] at org.scalatest.words.BeWord$$anon$15.apply(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:26853:49)
[info] at org.scalatest.Matchers$ShouldMethodHelper$.shouldMatcher(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:8592:29)
[info] at org.scalatest.Matchers$AnyShouldWrapper.should(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:8523:115)
[info] at {anonymous}()(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:54138:20)
[info] at scala.scalajs.runtime.AnonFunction0.apply(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:29505:23)
[info] at org.scalatest.OutcomeOf$class.outcomeOf(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:2911:7)
[info] at org.scalatest.Transformer.apply(W:\Test\JSTest\target\scala-2.11\jstest-test-fastopt.js:37772:10)

Related

Property check should fail in Scalatest

I've created and am also using some external Scalacheck generators from Lists and appropriate types, using Gen.oneOf(List[T]) . I think it would be occasionally useful to return a placeholder for an empty value. Currently the lists are populated. How should I go about this? Do I try to append an empty type to the end of the list? If so how do I go about that? If not, how else can I get my generators to add an empty value. It seems straightforward, but I am having trouble figuring it out right now.
import org.scalatest.FlatSpec
import org.scalacheck.Gen
import org.scalacheck.Prop.exists
import org.scalatest.prop.PropertyChecks
class EventFieldGeneratorTest extends FlatSpec with PropertyChecks {
behavior of "Gen.option"
it should "occasionally return None" in {
val colors = Gen.oneOf("Blue", "Red", "Green", "Yellow")
val opt = Gen.option(colors)
val list = Gen.listOfN(20, opt)
val p1 = exists(list)(_ == None)
p1.check
}
}
Can anybody explain why my test is giving up?
Testing started at 10:31 AM ... ! Gave up after only 0 passed tests. 501 tests were discarded.
Process finished with exit code 0
How can I mark that as a failed result for ScalaTest? Is it a bad idea for me to use Flatspec?
Maybe I should be using something other than check...
Here's the documentation I used to sort it on. On the Scalatest page:
http://www.scalatest.org/user_guide/writing_scalacheck_style_properties
I don't think there's anything flawed with trying to use lists with optional values. There are just a few issues you're running in to that are giving you trouble.
It's confusing, but if you're using the Scalatest framework, you need to use the Scalatest infrastructure to use Scalacheck. So you'll need to use Scalatest matchers, and write Scalatest-flavored properties (using it's forAll), but you'll still use Scalacheck's generators directly.
For some reason the type inference between lists and Option type is giving you trouble. If you use the shouldBe matcher,
x shouldBe(None)
you'll get a relevant runtime error from Scalatest:
[info] - should occasionally return None *** FAILED ***
[info] TestFailedException was thrown during property evaluation.
[info] Message: List() was not equal to None
[info] Location: (GenTest.scala:13)
[info] Occurred when passed generated values (
[info] arg0 = List() // 5 shrinks
[info] )
[info] Run completed in 1 second, 621 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 0, failed 1, canceled 0, ignored 0, pending 0
You shouldn't be matching a list with an Option type. You need to be matching with the Scalatest "container" matcher should contain
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import org.scalacheck.Gen
import org.scalatest.prop.PropertyChecks
class EventFieldGeneratorTest extends FlatSpec with Matchers with PropertyChecks {
behavior of "Gen.option"
it should "occasionally return None" in {
val colors = Gen.oneOf("Blue","Red","Green","Yellow")
val opt = Gen.option(colors)
val list = Gen.listOfN(20,opt)
forAll(list) { (xs: List[Option[String]]) =>
xs should contain (None)
}
}
}
This gives you a successful property check:
[info] EventFieldGeneratorTest:
[info] Gen.option
[info] - should occasionally return None
[info] ScalaTest
[info] Run completed in 1 second, 9 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
More on Scalatest matchers
http://www.scalatest.org/user_guide/using_matchers

Testing Controller action in play framework 2.4 wih scalatest

I am trying to test my controller action in Play Framework with ScalaTest .
I have read play documentation and trying to run the given sample to get started
my controller Application.scala
class Application extends Controller {
def index1() = Action{
Ok("ok")
}
test class
import scala.concurrent.Future
import org.scalatestplus.play._
import play.api.mvc._
import play.api.test._
import play.api.test.Helpers._
import akka.stream.Materializer
import play.api.libs.json.Json
class ExampleController extends PlaySpec with Results {
"testing the index page" should {
"the test should be valid" in {
val controller = new controllers.Application()
val result: Future[Result] = controller.index1().apply(FakeRequest())
val bodyText: String = contentAsString(result)
bodyText mustBe "ok"
}
}
}
and i am getting following exception while running the test
ExampleController:
[info] testing the index page
[info] Exception encountered when attempting to run a suite with class name: ExampleController *** ABORTED ***
[info] java.lang.AbstractMethodError:
[info] at play.api.mvc.Results$class.$init$(Results.scala:605)
[info] at controllers.Application.<init>(Application.scala:51)
[info] at ExampleController$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(ExampleController.scala:38)
[info] at ExampleController$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(ExampleController.scala:37)
[info] at ExampleController$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(ExampleController.scala:37)
[info] at org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22)
[info] at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
[info] at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info] at org.scalatest.Transformer.apply(Transformer.scala:22)
[info] at org.scalatest.Transformer.apply(Transformer.scala:20)
[info] ...
[error] Uncaught exception when running ExampleController: java.lang.AbstractMethodError
[trace] Stack trace suppressed: run last arteciate/test:test for the full output.
[info] DeferredAbortedSuite:
[info] Exception encountered when attempting to run a suite with class name: org.scalatest.DeferredAbortedSuite *** ABORTED ***
[info] java.lang.NoSuchMethodError: play.api.libs.functional.syntax.package$.functionalCanBuildApplicative(Lplay/api/libs/functional/Applicative;)Lplay/api/libs/functional/FunctionalCanBuild;
[info] at models.institution.Gallery$.<init>(Gallery.scala:18)
[info] at models.institution.Gallery$.<clinit>(Gallery.scala)
[info] at TestModels.validationtest.<init>(validationtest.scala:251)
[info] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
Please guide me where i am committing mistake

Functional Tests in Play 2.4.6 when using compile time DI

I'm using Play 2.4.6 with compile time dependency injection and ScalaTest. The controller's constructor has few parameters, and in an ApplicationLoader I create it.
Here is the code:
class BootstrapLoader extends ApplicationLoader {
def load(context: Context) = {
new AppComponents(context).application
}
}
class AppComponents(context: Context) extends BuiltInComponentsFromContext(context) with NingWSComponents {
lazy val router = new Routes(httpErrorHandler, authenticationController, applicationController, assets)
lazy val applicationController = new controllers.Application()
lazy val authenticationController = new controllers.Authentication()(configuration, wsApi.client)
lazy val assets = new controllers.Assets(httpErrorHandler)
}
class Authentication(implicit configuration: Configuration, val ws: WSClient) extends Controller {
def login = Action { implicit request =>
Unauthorized(s"${redirectUrl}")
}
}
class AuthenticationSpec extends PlaySpec with OneAppPerSuite {
implicit val configuration: Configuration = app.configuration
implicit val wsClient: WSClient = WS.client(app)
"when user not logged-in" should {
"return Status code Unauthorized(401) with redirect url" in {
1 mustEqual 2
}
}
}
When I'm running the test I'm getting the following error:
[info] Exception encountered when attempting to run a suite with class name: controllers.AuthenticationSpec *** ABORTED ***
[info] com.google.inject.ProvisionException: Unable to provision, see the following errors:
[info]
[info] 1) Could not find a suitable constructor in controllers.Authentication. Classes must have either one (and only one) constructor annotated with #Inject or a zero-argument constructor that is not private.
[info] at controllers.Authentication.class(Authentication.scala:19)
[info] while locating controllers.Authentication
[info] for parameter 1 at router.Routes.<init>(Routes.scala:35)
[info] while locating router.Routes
[info] while locating play.api.test.FakeRouterProvider
[info] while locating play.api.routing.Router
[info]
[info] 1 error
[info] at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025)
[info] at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)
[info] at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:321)
[info] at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:316)
[info] at play.api.Application$class.routes(Application.scala:112)
[info] at play.api.test.FakeApplication.routes(Fakes.scala:197)
[info] at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:90)
[info] at play.api.Play$$anonfun$start$1.apply(Play.scala:87)
[info] at play.api.Play$$anonfun$start$1.apply(Play.scala:87)
[info] at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
FakeApplication use GuiceApplicationBuilder, which of course does not work.
What should I do to run such tests?
Thanks
override implicit lazy val app = new BootstrapLoader().load(
ApplicationLoader.createContext(
new Environment(
new File("."), ApplicationLoader.getClass.getClassLoader, Mode.Test)))
It works in Play 2.5.1
You are getting an error because the tests are not even able to start a application. That is happening because you are using Dependency Injection in your controllers (as the error message suggests) and you need to declare them as classes, instead of as objects. As you can see at the docs:
package controllers
import play.api.mvc._
class Application extends Controller {
def index = Action {
Ok("It works!")
}
}
If your controller has some dependency to be injected, you should use the #Inject annotation in your controller constructor (again, please see the docs). Per instance:
package controllers
import play.api.mvc._
import play.api.libs.ws._
import javax.inject._
class Application #Inject() (ws: WSClient) extends Controller {
// ...
}
You can also read the Compile Time Dependency Injection docs if you are using it instead of runtime DI.
If you use specs2 you can do it. see http://loicdescotte.github.io/posts/play24-compile-time-di/
But you loose the nice api.
Scalatest / scalatest-plus has done something funky with the DI (guice) :(
I'm facing the same problem as you. I don't have a satisfying solution, the following is a mere workaround:
I ended up putting
implicit def client:WSClient = NingWSClient()
in my WithApplicationLoader class
I also found https://github.com/leanovate/play-mockws which allows you to mock ws calls. But that's not what we want here.
my guess would be that the OneAppPerSuite trait isn't using your custom application loader. you may need to override the application construction that comes from that trait and make it use your custom loader.
looks like there is an example using scalatest here: http://mariussoutier.com/blog/2015/12/06/playframework-2-4-dependency-injection-di/

PowerMock in Scala: java.lang.NullPointerException when getPackage

This code just getPackage and getName of a class (not use any mock techniques yet), but it failed.
Anyone see this problem before?
Code:
import mai.MyScala1
import org.junit.Test
import org.junit.runner.RunWith
import org.powermock.modules.junit4.PowerMockRunner
import org.scalatest.junit.JUnitSuite
#RunWith(classOf[PowerMockRunner])
class MyTest extends JUnitSuite {
#Test def test1() {
classOf[MyScala1].getPackage // this one returns null
classOf[MyScala1].getPackage.getName // raise java.lang.NullPointerException
}
}
Error logs:
[info] - test1 *** FAILED ***
[info] java.lang.NullPointerException:
[info] at org.apache.tmp.MyTest.test1(MyTest.scala:15)
[info] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[info] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[info] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[info] at java.lang.reflect.Method.invoke(Method.java:497)
[info] at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
[info] at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
[info] at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
[info] at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
[info] at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
[info] ...
I think I found the answer, but I don't understand why it works?
Answer: Inside sbt, we should first "set fork := true", then everything will work fine.
The problem might be related to process vs thread problem.

I've got error for generating pickler/unpickler for a type with type-parameter

I'm trying to use scala-pickling for my project; but I've got a problem with it. let assume that I've got this code:
import scala.pickling._
import scala.pickling.Defaults._
import scala.pickling.json._
sealed trait State
case class Married(name:String) extends State
case object Single extends State
trait Person[T<:State] {
def name:String
def surname:String
def age:Int
def state:T
}
case class Male[T<:State](
val name:String,
val surname:String,
val age:Int,
val state:T) extends Person[T]
case class Female[T<:State](
val name:String,
val surname:String,
val age:Int,
val state:T) extends Person[T]
def hideType[T<:State]:Person[T] = Male("Hussein", "?", 145, Single).asInstanceOf[Person[T]]
When I'm try to hideType.pickle , I get a compile-time error:
error: Cannot generate a pickler for Person[T]. Recompile with -Xlog-implicits for details
What's the problem for generating a pickler/unpickler in this case?
more info:
scala 2.11.6
scala-pickling 0.10.0
EDIT 1:
result of compile with "-Xlog-implicits":
[info] Loading global plugins from /home/someone/i/etc/sbt/0.13/plugins
[info] Loading project definition from /home/someone/tmp/pickling/project
[info] Set current project to pickling (in build file:/home/someone/tmp/pickling/)
[info] Compiling 1 Scala source to /home/someone/tmp/pickling/target/scala-2.11/classes...
[info] /home/someone/tmp/pickling/src/main/scala/com/example/Hello.scala:35: genPickler is not a valid implicit value for scala.pickling.Pickler[com.example.Person[T]] because:
[info] hasMatchingSymbol reported error: stepping aside: repeating itself
[info] hideType.pickle
[info] ^
[info] /home/someone/tmp/pickling/src/main/scala/com/example/Hello.scala:35: genPickler is not a valid implicit value for scala.pickling.Pickler[com.example.Person[T]] because:
[info] hasMatchingSymbol reported error: polymorphic expression cannot be instantiated to expected type;
[info] found : [T]scala.pickling.Pickler[T]
[info] required: scala.pickling.Pickler[com.example.Person[?]]
[info] hideType.pickle
[info] ^
[error] /home/someone/tmp/pickling/src/main/scala/com/example/Hello.scala:35: Cannot generate a pickler for com.example.Person[T]. Recompile with -Xlog-implicits for details
[error] hideType.pickle
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 2 s, completed May 26, 2015 4:31:45 AM
I am not sure what is the intention but you got a generic variable.
Try
hideType[State].pickle
or
hideType[Married].pickle