How to get meaningful message for failing Specs2 test on all elements of a collection? - specs2

I have a list of files exampleProblems, to each of which I want to apply a method and check that it doesn't throw an exception. The problem is that I don't get a good failure message from Specs2. I need to find out which element caused the problem. I already tried adding an aka, but with no success.
Here is the code:
def is: Fragments =
"parse all example uai files" ! (exampleProblems must contain((p: String) => {
Problem.parseUAIProblem(ClassLoader.getSystemResourceAsStream(p)).aka(p) must throwAn[Exception].not
}).forall)
And here is the message I'm getting:
java.lang.Exception: There is 1 failure Got the exception
java.lang.IllegalArgumentException: requirement failed: variables are
not ordered increasingly
at
vultura.fastfactors.UAIParserTest$$anonfun$is$1$$anonfun$apply$1.apply(UAIParserTest.scala:24)
at
vultura.fastfactors.UAIParserTest$$anonfun$is$1$$anonfun$apply$1.apply(UAIParserTest.scala:24)

This means that the throwA[E] matcher should be improved to display the expectable description when using aka. I'll fix this but as a work-around you can write:
class TestSpec extends Specification { def is =
"parse all example uai files" ! {
Seq("a", "b") must contain { (p: String) =>
s"$p is ok" ==> { { sys.error("bang"); p} must not (throwAn[Exception]) }
}.forall
}
}
This displays:
[info] x parse all example uai files
[error] There is 1 failure
[error] a is not ok because Got the exception java.lang.RuntimeException: bang

Related

Akka group runForeach

I have an akka source that I want to group and run on batch. I am facing a problem and I am not really sure what is going wrong.
I have a source that looks something like this
val source = Source(facts.toList)
source
.grouped(config.batchSize)
.runForeach(batch => {
//Do something
})
But I am getting
[error] found : scala.concurrent.Future[akka.Done]
[error] required: scala.concurrent.Future[Unit]
[error] .runForeach(batch => {
[error]
^
Why isn't it not able to run the source?
You're not showing the larger context in which your code snippet resides, but I'm guessing your code is the last expression inside a method that is expecting a return value of Future[Unit]. The compiler is complaining because Source#runForeach returns a Future[Done] instead of a Future[Unit].
A quick fix could be to change your method's return type to Future[Done].

Scala: Int doesn't take parameters on a recursive call

I get a weird compilation error in the small Scala exercise I am working on.
I have this method that is supposed to keep on asking user input until a correct answer is provided. Alas I am stumbled at the first case in my pattern matching:
override def guess(guess: Int):Unit = {
val guessIndex = binary(array, guess)
guessIndex match {
case -1 => {
val nextAttempt = StdIn.readLine(s"Please be attentive $guess is outside the search range"
+" (0 to $upperBound). Try again: \n");
val a = validateType[Int](nextAttempt)
guess(a)
}
}
}
The IDE underlines guess(a) with the error "Int doesn't take parameters". Running sbt compile from the console confirms this error:
> compile
[info] Compiling 2 Scala sources to /home/vgorcinschi/Documents/eclipseProjects/Algorithms/Chapter 1 Fundamentals/algorithms1_4_34/target/scala-2.12/classes...
[error] /home/vgorcinschi/Documents/eclipseProjects/Algorithms/Chapter 1 Fundamentals/algorithms1_4_34/src/main/scala/ca/vgorcinschi/algorithms1_4_34/hotandcold/HotAndColdImpl.scala:23: Int does not take parameters
[error] guess(a)
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 0 s, completed 6-May-2017 6:47:58 PM
There are few different Stackoverflow tickets for the same error message, but they're for different scenarios. In mine here it looks like a method who takes an Int parameter is being rejected. If you could please give me a hint this would help me a lot.
Rename the guess parameter (or the method name, so it's something different) - the parameter is the first guess in scope, so the compiler thinks you're trying to call it as a function.

java generics in scala sometimes fail with cast exception

So this is a pretty specific problem, but might be related to issues other may have experience, though I could not find a good solution.
in our specific case, we are using Elasticsearch. the problematic piece of code is this:
val hit: org.elasticsearch.search.SearchHit = {...}
val innerSystemField: Option[Long] =
Try(hit.field("system.innerField").getValue) match {
case Success(x) => Some(x.asInstanceOf[Long])
case Failure(e) => {
logger.error("exception during innerField retrieval", e)
None
}
}
so, it doesn't really matters we are using Elasticsearch, what matter, is the library API. so, here's the SearchHit interface's field method which returns an instance of SearchHitField. and here's the SearchHitField interface's getValue method. the method is declared as:
<V> V getValue();
and this is where the problem lies. the mapping which we defined Elasticsearch with, guarantee that the returned value will always be a Long. but every once in a while we get a Failure containing a java.lang.ClassCastException: java.lang.Long cannot be cast to scala.runtime.Nothing$. The thing is, that if I explicitly write the type, it won't compile:
[error] /home/me/projects/my-project/src/main/scala/com/org/project/MyElasticsearchCode.scala:123: polymorphic expression cannot be instantiated to expected type;
[error] found : [V]()V
[error] required: Long
[error] Try[Long](hit.field("system.innerField").getValue) match {
[error] ^
[error] one error found
[error] (project/compile:compileIncremental) Compilation failed
[error] Total time: 4 s, completed Jul 27, 2015 4:16:41 PM
So how do I get around this problem?
I find the message of the ClassCastException a bit confusing. Maybe you could try this:
val innerSystemField: Option[Long] =
Try[Any](hit.field("system.innerField").getValue) match {
case Success(x: java.lang.Long) => Some(x.asInstanceOf[Long])
case Failure(e) => {
logger.error("exception during innerField retrieval", e)
None
}
}

ScalaTest hides setup failures in FreeSpec

when I run the following test it throws an exception directly in the description clause, befor e it reaches the in clause:
"when the message send actor receives a reference to an address" - {
val unusedInThisTestActor = mock[ActorRef]
val serviceFacade = testActor
val keys = Array("password")
val values = Array("cheese")
val addressRef = TestActorRef[ServiceEndpoint]
val messageSender = system.actorOf(new Props(() => new MessageSendActor(unusedInThisTestActor, serviceFacade, unusedInThisTestActor)))
messageSender ! ReferenceToAddress(addressRef, ("command", keys, values))
"it tells the service facade to send the command to the address reference" in {
expectMsg(SendCommandToService(addressRef,("command", keys, values)))
}
}
ScalaTest then ignores this test, rather than saying it failed which leaves everyone thinking the code is working fine. The only way to notice something went wrong is to look carefully at the output:
[ERROR] [06/16/2013 10:31:05.722] [main] [akka://testactorsystems/user/$$a] error while processing Create(622541251)
d7565b2b-b0a4-4af6-83c7-ed67f7bf0302akka.actor.ActorInitializationException: exception during creation
at akka.actor.ActorInitializationException$.apply(Actor.scala:170)
And use this to work out which tests aren't being run.
This is not very helpful, and I would prefer scala test to mark this as a failure somehow. Is that possible?

Play for Scala and Anorm: cannot create a simple parser

There should be something simple here, though I'm completely missing it, since I'm noob in Scala and Play. Here's the code:
case class ExceptionInfo(ExceptionType: String, Message: String, StackTrace: Seq[String])
object ExceptionInfo
{
val excInfoParser = {
get[String]("ExceptionInfo.ExceptionType") ~
get[String]("Message") ~
get[String]("ExceptionInfo.StackTrace") map {
case ExceptionType ~ Message ~ StackTrace => ExceptionInfo(ExceptionType, Message, StackTrace.split("\r\n"))
}
}
}
This doesn't compile, with following output:
Description Resource Path Location Type
not found: value ExceptionType Application.scala /testme/app/controllers line 40 Scala Problem
not found: value Message Application.scala /testme/app/controllers line 40 Scala Problem
not found: value StackTrace Application.scala /testme/app/controllers line 40 Scala Problem
not found: value ExceptionType Application.scala /testme/app/controllers line 40 Scala Problem
Thanks in advance!
Should work when you name the variables in lowercase:
case exceptionType ~ message ~ stackTrace => ExceptionInfo(exceptionType, message, stackTrace.split("\r\n"))
The lowercase is what distinguishes variables to be bound to (what you're looking for) from constants to be matched against. See here and here for more.