Spray route inside IDEA complains about false error - scala

I'm using spray and I have the following code:
import spray.json.DefaultJsonProtocol
import spray.routing.Directives
import spray.httpx.SprayJsonSupport.sprayJsonMarshaller
import spray.httpx.SprayJsonSupport.sprayJsonUnmarshaller
case class SomeResult(id: String, color: String)
trait Protocols extends DefaultJsonProtocol {
implicit val someResultFormat = jsonFormat2(SomeResult)
}
trait Api extends Directives with Protocols {
val route =
path("order" / IntNumber) { id =>
get {
complete {
val result: List[SomeResult] = List(SomeResult("foo", "green"+id), SomeResult("bar", "red"+id))
result
} // ERROR HERE
}
}
}
This compiles and runs fine, however, inside IntelliJ IDEA editor it complains about an error. Namely, it says that Expression of type List[SomeResult] doesn't conform to expected type ToResponseMarshallable. How can I avoid the IDE complaining about such things? is there any fix for this? is it a well-known error? I already invalidated cache files and restarted but the error persist.
FWIW, I'm using:
Scala 2.11.1
Spray 1.3.1
IDEA 14.0.3
Scala plugin 1.3.2
JDK 1.7.0_71

Related

Dead Code encountered with x fatal warnings on

I have a piece of code:
case class ColumnChange private(field: String, old: Option[JsValue], `new`: Option[JsValue])
#typeclass
trait CreateColumnChanges[-New] {
def fieldChanges(newValue: New): Vector[ColumnChange]
}
trait LowLevelFieldChangesImplicits {
import com.github.ghik.silencer.silent
#silent
implicit object NothingColumnChanges extends CreateColumnChanges[Nothing] {
override def columnChanges(newValue: Nothing): Vector[ColumnChange] = Vector.empty
}
}
I have enabled "-Xfatal-warnings" in my build.sbt.
When I am compiling my project its throwing this error:
dead code following this construct
[error] implicit object NothingCreateFieldChanges extends CreateFieldChanges[Nothing] {
I tried changing type to CreateColumnChanges[Any], but somehow many tests are failing, which over-complicates my problem, maybe because -New is in contravariant position. I tried putting this scalacOptions "-Ywarn-dead-code" in build file too, but its not having any effect and again I am getting the same exception. I am compiling with scala 2.12.10.Also #silent annotation is not having effect on it. How can I change my code to avoid this error.
Finally this worked,
I changed type from Nothing to Unit

Returning a JSON array in Akka Http

I have an Akka HTTP server with routing defined like this:
case class FooResults(results: Seq[Tuple2[String, Tuple2[Double, Double]]])
object MainApp extends App with JsonSupport {
...
lazy val routes: Route =
pathPrefix("foo") {
pathEnd {
get {
entity(as[String]) { str =>
val results =
(fooActor ? Foo(str)).mapTo[FooResults]
complete(results)
}
}
}
}
...
And in the class I have injected the implicit json support:
trait JsonSupport extends SprayJsonSupport {
import DefaultJsonProtocol._
implicit val userFormat = jsonFormat1(FooResults)
}
Somehow sbt still reports with
Type mismatch - FooResults with ToResponseMashallable
Anyone had similar problems? Thanks!
I figured out myself. It was because there're two SprayJsonSupport classes in my project:
import spray.httpx.SprayJsonSupport
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
Now obviously the latter is the correct one. Guess along the way since both Scala and Akka are evolving (fast), sometimes it becomes confusing with the namespaces and classes.

Scalatest with eclipse shows errors while using Matchers

I have an eclipse scala project which uses maven. Eclipse plugins for ScalaIDE and Scalatest are installed. I have tests like:
import org.scalatest._
class ExampleSpec extends FlatSpec with Matchers {
feature("Feature A Test") {
scenario("Foo scenario 1") {
val a = FooClass().getResult()
a.count shouldBe 1 // IDE shows error: value shouldBe is not a member of Long
a(0).getString(0) shouldBe "FOO" // IDE shows error: value shouldBe is not a member of String
}
}
}
The maven compilation and the tests run fine, but in eclipse when I open this file, I see an error in eclipse wherever I am using a Matcher as mentioned in the comments above. Eg.
value shouldBe is not a member of Long
What am I missing? A scala test file shows hundreds of problems.
After adding the following dummy code:
case class Bar() {
def count = Array(Bar())
def getString(x: Int) = Array("aqq")
def apply[T](x: Int) = this
}
case class FooClass() {
def getResult() = Bar()
}
and changing FlatSpec to FeatureSpec as this is the syntax you are using in your ExampleSpec, the code compiles without any issues.
If it's still not the case for you I can suggest creating simple build.sbt and generating project with Eclipse sbt plugin.
I know this is old, but I had the same issue with eclipse (late 2018), and I was able to fix this by making sure the test was NOT in the default package. That is, add "package org.scalatest.examples.flatspec" to the beginning of your test, as an example, and move the test into that package.

Why Scala Enumeration does not work in Apache Zeppelin but it works in maven

Enumeration works as expected when I use it in a maven project(with the same Scala version).
object t {
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
def main(args: Array[String]) = f(DashStyle.Solid)
}
But when it runs in Apache Zeppelin(Zeppelin 0.6, Spark 1.6, Scala 2.10, Java 1.8)
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
f(DashStyle.Solid)
It reports the following error even it says found and required type is exactly the same
<console>:130: error: type mismatch;
found : DashStyle.Value
required: DashStyle.Value
f(DashStyle.Solid)
Why and how should I use it?
I figured out the trick to solve this issue.
In Apache Zeppelin (or Scala REPL). In order to use Enumeration or sealed&object, it should be wrapped in object but not directly define on the root scope.
The reason why it works in maven is that I already put it into an object.
Define enumeration in an object in a Zeppelin paragraph
object t {
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
}
Then use it in a Zeppelin paragraph
import t._
f(DashStyle.Solid)

How can I fix the missing implicit value for parameter ta: TildeArrow in a test spec

I'm working on a simple test spec using spray and I can't get it to compile correctly, don't know if I'm doing anything wrong. My version of scala is 2.9.3 and spray 1.0.1 (Updating either of them is not a suitable option). Here's my test spec's code:
import org.specs2.mutable.Specification
import spray.testkit.Specs2RouteTest
import spray.http._
import akka.util.Duration
import java.util.concurrent.TimeUnit
import service.MyProxy
abstract class MyTestSpec extends Specification with Specs2RouteTest with MyProxy{
val duration = Duration(30, TimeUnit.SECONDS)
implicit val routeTestTimeout = RouteTestTimeout(duration)
"MyProxy" should {
"return a json for GET requests to the /api/getclass/classCode path for a regular request" in {
Get("/api/getclass/123/") ~> myRoutes~> check {
responseAs[String] must contain("classCode")
contentType === ContentTypes.`application/json`
}
}
} // end should...
} //end class
I'm getting this error when I run the test.
[error] C:\Users\Desktop\Project\MyTestSpec.scala:23: could not find implicit value for parameter ta: MyProxySpec.this.TildeArrow[spray.routing.RequestContext,Unit]
[error] Get("/api/getclass/123/") ~> myRoutes~> check {
[error] ^
[error] one error found
[error] (test:compile) Compilation failed
I've tried different solutions seen on another questions and nothing seems to work so far.
Spray.io: Can't compile test spec
how to make scalatest work with spraytestkit and HttpServiceActor
Basic Spray-Testkit usage to test a route does not work
https://groups.google.com/forum/#!topic/spray-user/H5hkXuDGWYQ
https://groups.google.com/forum/#!topic/spray-user/zFUJSVBPM5c
NOTE: Just for the record, I'm not using scalatest or scalacheck on this. Is purely a [spray] route test.And MyProxy extends Actor
I just struggled with this problem. To figure it out, I waded through the Akka HTTP codebase, which is a jungle of implicits.
My problem seemed to be that without the right secondary implicit in place, the correct TildeArrow instance wasn't being found. If you look at the code, the TildeArrow instance, which is required in the error message, is defined as an implicit def injectIntoRoute in the companion object and it requires a whole host of other implicits.
I suggest writing out your code without any of the implicit sugar. This should better help the compiler give you a proper error message:
"MyProxy" should {
"return a json for GET requests to the /api/getclass/classCode path for a regular request" in {
val request = Get("/api/getclass/123/")
val requestWithRoutes = request.~>(myRoutes)(TildeArrow.injectIntoRoute)
requestWithRoutes.~>(check {
responseAs[String] must contain("classCode")
contentType === ContentTypes.`application/json`
})
}
}
I think the reason is that since there's no concrete instance of the implicit available, the compiler is trying to satisfy the implicit resolution with the abstract class TildeArrow, and the completely unspecified abstract type, ta.Out, doesn't have a ~> defined.
In my specific case, I was missing an implicit ExecutionContextExecutor, whatever that means.
UPDATE
Actually, I looked into it further and the problem was that I had an implicit def ec: ExecutionContextExecutor declared in my route trait, but trait RouteTest defines its name as executor, and so when I defined my own to fulfill the missing implicit, I ended up with two of the same implicit.
It's a cute API, but the implicit magic is way out of control, IMO, especially given how cryptic the error messages tend to be.
The ScalatestRouteTest already provides an implicit ActorySystem. Remove the "implicit" modifier from your actorRefFactory method and the test should get executed.
Spray.io: Can't compile test spec
for akka http:
in my case which refer to akka-http-microservice
the implicit modifier of executionContext and also need to be removed
and should reorder the trait like this : class ServiceSpec extends FlatSpec with Matchers with Service with ScalatestRouteTest
In my case, the not found implicit error appeared when in my TestCase I also imported import monix.execution.Scheduler.Implicits.global (which is probably having some sort of ExecutionContext).
I fixed it adding the monix scheduler import just in the method where I needed it, not on the top imports.
I can reproduce the precise same error message with Scala 2.10 if myRoutes is not actually a route but a Directive[HNil].
I am therefore guessing that in your unshown service.MyProxy class your route does not complete.
ie
trait MyProxy extends HttpService {
val myRoutes = path("foo")
}
Gives this error
trait MyProxy extends HttpService {
val myRoutes = path("foo") {
complete(StatusCodes.Accepted)
}
}
Does not.
To expand a bit on previous answers given, there are some implicits which shouldn't be declared by any other Trait or class that is extends by your Test Class :
the ActorSystem
the ExecutionContext
the DefaultHostInfo (package akka.http.scaladsl.testkit)
the ActorMaterializer
if any of these is declared elsewhere than in ScalatestRouteTest, you'll have the following error thrown :
could not find implicit value for parameter ...TildeArrow[RequestContext, SomethingHereOther]
your build.sbt should have dependencies for akka-stream test along with akka test.
then it should get the whatever dependencies.
refer to this doc:-
scala route test doc