Can't import from slick.driver.H2Driver.simple._ in Scala - scala

I'm trying to use Slick in Scala, I've followed the docs and the examples, installed the sbt dependencies and I have this problem:
api-scala\src\main\scala\com\example\app\MyScalatraServlet.scala:7: value simple is not a member of object slick.driver.H2Driver
[error] import slick.driver.H2Driver.simple._
I've tried with import scala.slick.driver.H2Driver.simple._ too, and can't find the solution to this.
I'm using IntelliJ IDEA as IDE.
This is my code in MyScalatraServlet.scala:
package com.example.app
import com.example.app.models._
import org.scalatra._
import org.scalatra.scalate.ScalateSupport
import org.json4s.{DefaultFormats, Formats}
import org.scalatra.json._
import slick.driver.H2Driver.simple._
import slick.jdbc.JdbcBackend.Database.dynamicSession
class MyScalatraServlet(db: Database) extends ApiscalaStack with ScalateSupport with JacksonJsonSupport {
protected implicit lazy val jsonFormats: Formats = DefaultFormats
before() {
contentType = formats("json")
}
get("/") {
contentType="text/html"
layoutTemplate("/WEB-INF/templates/views/index.mustache")
}
get("/about/?") {
<p>About</p>
}
get("/flor/?") {
FlowerData.all
}
get("/user/:name?") {
<p>User: {params("name")}</p>
}
}
Any ideas?
Thanks!

Which slick version are you using? For slick 3 it's
import scala.slick.driver.H2Driver.api._

Related

Creating functional tests Scala Playframework 2.6 Macwire

I wrote some traits to use it as a base for my functional tests
This file is for creating a DB in memory (H2 + Evolutions)
BlogApiDBTest.scala
package functional.common
import play.api.db.Databases
import play.api.db.evolutions.Evolutions
trait BlogApiDBTest {
implicit val testDatabase = Databases.inMemory(
name = "blog_db",
urlOptions = Map(
"MODE" -> "MYSQL"
),
config = Map(
"logStatements" -> true
)
)
org.h2.engine.Mode.getInstance("MYSQL").convertInsertNullToZero = false
Evolutions.applyEvolutions(testDatabase)
}
Here I am overriding some injected components for testing purposes
BlogApiComponentsTest.scala
package functional.common
import common.BlogApiComponents
import org.scalatestplus.play.components.WithApplicationComponents
import play.api.{BuiltInComponents, Configuration}
trait BlogApiComponentsTest extends WithApplicationComponents with BlogApiDBTest {
override def components: BuiltInComponents = new BlogApiComponents(context) {
override lazy val configuration: Configuration = context.initialConfiguration
override lazy val blogDatabase = testDatabase
}
}
This is the base class for my functional tests
BlogApiOneServerPerTestWithComponents.scala
package functional.common
import org.scalatestplus.play.PlaySpec
import org.scalatestplus.play.components.{OneServerPerTestWithComponents}
trait BlogApiOneServerPerTestWithComponents extends PlaySpec with OneServerPerTestWithComponents with BlogApiComponentsTest {
}
Finally the test I am trying to execute
PostControllerSpec.scala
package functional.controllers
import functional.common.BlogApiOneServerPerTestWithComponents
import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures}
import play.api.mvc.{Results}
import play.api.test.{FakeRequest, Helpers}
import play.api.test.Helpers.{GET, route}
class PostControllerSpec extends BlogApiOneServerPerTestWithComponents
with Results
with ScalaFutures
with IntegrationPatience {
"Server query should" should {
"provide an Application" in {
val Some(result) = route(app, FakeRequest(GET, "/posts"))
Helpers.contentAsString(result) must be("success!")
}
}
}
Then I get
blog-api/test/functional/controllers/PostControllerSpec.scala:18:31: Cannot write an instance of play.api.mvc.AnyContentAsEmpty.type to HTTP response. Try to define a Writeable[play.api.mvc.AnyContentAsEmpty.type]
Here is the code
Adding the following import should make it work:
import play.api.test.Helpers._
Looking at the signature of route
def route[T](app: Application, req: Request[T])(implicit w: Writeable[T]): Option[Future[Result]]
we see it expects an implicit w: Writeable[T]. The above import will provide it via Writables

could not find implicit value for parameter env: com.mohiva.play.silhouette.api.Environment[utils.auth.DefaultEnv]

I'm using a Silhouette v4.0 library with play framework 2.5.
And have been trying to write test code using play specs2.
But, I get the following error with my test class as below.
Error Message
[error] could not find implicit value for parameter env: com.mohiva.play.silhouette.api.Environment[utils.auth.DefaultEnv]
.withAuthenticator[DefaultEnv](identity.loginInfo)
^
Here's the test class
package controllers
import com.google.inject.AbstractModule
import org.joda.time.DateTime
import org.specs2.specification.Scope
import org.specs2.matcher._
import org.specs2.mock._
import play.api.test._
import play.api.libs.json._
import play.api.libs.json.Json
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
import play.api.libs.concurrent.Execution.Implicits._
import play.api.libs.mailer.{ MailerClient, Email }
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.inject.bind
import com.mohiva.play.silhouette.test._
import com.mohiva.play.silhouette.api._
import com.mohiva.play.silhouette.api.repositories.AuthInfoRepository
import com.mohiva.play.silhouette.api.util._
import com.mohiva.play.silhouette.impl.providers._
import net.codingwell.scalaguice.ScalaModule
import utils.auth.DefaultEnv
class TestControllerSpec extends PlaySpecification with Mockito {
"case" in new Context {
new WithApplication(application) {
val request = FakeRequest(POST, "/api/test")
.withAuthenticator[DefaultEnv](identity.loginInfo) // <-
val result = route(app, request).get
status(result) must be equalTo OK
}
}
trait Context extends Scope {
val identity = User(
loginInfo = LoginInfo(..)
..
)
implicit val env = FakeEnvironment[DefaultEnv](Seq(identity.loginInfo -> identity))
class FakeModule extends AbstractModule with ScalaModule {
def configure() = {
bind[Environment[DefaultEnv]].toInstance(env)
}
}
lazy val application = new GuiceApplicationBuilder()
.overrides(new FakeModule)
.build
}
}
There are some other test classes similar to this class are properly able to compile and execute.
It's kind of implicit problem with scope..
Therefore, I tried to import all the same as another test class which's able to compile properly. But, still unable to compile.
Missing some import?
As the compiler states, you're missing an implicit value. Use the following, which is modeled after one of Silhouette's specs:
class TestControllerSpec extends PlaySpecification with Mockito {
"the POST request" should {
"return an OK response" in new Context {
new WithApplication(application) {
val identity = User(LoginInfo(...))
implicit val env = FakeEnvironment[DefaultEnv](Seq(identity.loginInfo -> identity))
val request = FakeRequest(POST, "/api/test")
.withAuthenticator(identity.loginInfo)
val result = route(app, request).get
status(result) must be equalTo OK
}
}
}
trait Context extends Scope {
...
}
}

Scala Marshalling/Unmarshalling

I'm trying to write a custom Marshaller for a very simple object, but it seems the scala runtime is not able to find it.
Following the spray template, I've defined the route as follows:
package com.example
import akka.actor.Actor
import spray.routing._
import spray.http._
import MediaTypes._
import com.example.dto.RecipeEntry
import com.example.dto.RecipeEntryJson._
trait RecipeManager extends HttpService {
val myRoute =
path("recipe") {
post {
decompressRequest() {
entity(as[RecipeEntry]) { recipe =>
complete(s"picture is $recipe.image")
}
}
}
}
}
and I've tried to define the Marshaller[RecipeEntry] as such:
package com.example.dto
import spray.json.DefaultJsonProtocol
import spray.httpx.SprayJsonSupport._
import spray.httpx.unmarshalling._
import spray.httpx.marshalling._
import spray.http._
case class RecipeEntry(originSite: String, image: String)
object RecipeEntryJson extends DefaultJsonProtocol {
implicit val jsonMarshaller: Marshaller[RecipeEntry] = jsonFormat2(RecipeEntry.apply)
}
but I keep getting the following error:
RecipeManager.scala:18: could not find implicit value for parameter um: spray.httpx.unmarshalling.FromRequestUnmarshaller[com.example.dto.RecipeEntry]
[error] entity(as[RecipeEntry]) { recipe =>
In fact, I'm running into the same problem as this link, however adding import com.example.dto.RecipeEntryJson._ did not help
I must be missing some small detail (probably quite a few, as I'm very new to scala and spray), but I've tried a number of things but to no avail. Any help is very much appreciated.

spray-json cannot marshal Map[String,String]

I have the following route setup, but when my map is returned in the first complete block I get an error:
could not find implicit value for evidence parameter of type spray.httpx.marshalling.Marshaller[scala.collection.immutable.Map[String,String]]
import spray.routing.HttpService
import akka.actor.Actor
import spray.http.HttpRequest
import spray.routing.RequestContext
import spray.json.DefaultJsonProtocol._
class UserServiceActor extends Actor with RestUserService {
def actorRefFactory = context
def receive = runRoute(linkRoute)
}
trait RestUserService extends HttpService {
val userService = new LinkUserService
def linkRoute =
pathPrefix("user" / Segment) {
userId =>
path("link") {
parameters('service ! "YT") {
complete {
Map("status"-> "OK", "auth_url" -> "http://mydomain.com/auth")
}
}
}
}
}
According to this test I should be able to convert a Map to json when DefaultJsonProtocol._ is imported but even that's failing:
val map:Map[String, String] = Map("hi"->"bye")
map.toJson
Cannot find JsonWriter or JsonFormat type class for scala.collection.mutable.Map[String,String]
Not sure what's wrong :(
Someone on the spray mailing list pointed out that the Map being created was a mutable one, spray-json won't marshal that. I changed it to be scala.collection.immutable.Map and also added the following imports:
import spray.httpx.SprayJsonSupport._
import spray.json.DefaultJsonProtocol._
And now everything works great.

Can Guice inject Scala objects

In Scala, can I use Guice to inject Scala objects?
For example, can I inject into s in the following object?
object GuiceSpec {
#Inject
val s: String = null
def get() = s
}
Some research on Google revealed that you can accomplish this as follows (the code that follows is a ScalaTest unit test):
import org.junit.runner.RunWith
import org.scalatest.WordSpec
import org.scalatest.matchers.MustMatchers
import org.scalatest.junit.JUnitRunner
import com.google.inject.Inject
import com.google.inject.Module
import com.google.inject.Binder
import com.google.inject.Guice
import uk.me.lings.scalaguice.ScalaModule
#RunWith(classOf[JUnitRunner])
class GuiceSpec extends WordSpec with MustMatchers {
"Guice" must {
"inject into Scala objects" in {
val injector = Guice.createInjector(new ScalaModule() {
def configure() {
bind[String].toInstance("foo")
bind[GuiceSpec.type].toInstance(GuiceSpec)
}
})
injector.getInstance(classOf[String]) must equal("foo")
GuiceSpec.get must equal("foo")
}
}
}
object GuiceSpec {
#Inject
var s: String = null
def get() = s
}
This assumes you are using scala-guice and ScalaTest.
The above answer is correct, but if you don't want to use ScalaGuice Extensions, you can do the following:
val injector = Guice.createInjector(new ScalaModule() {
def configure() {
bind[String].toInstance("foo")
}
#Provides
def guiceSpecProvider: GuiceSpec.type = GuiceSpec
})