I'm stepping through my first Scala project, and looking at parser combinators in particular. I'm having trouble getting a simple unit test scenario to work, and trying to understand what I'm missing.
I'm stuck on pattern matching a ParseResult into the case classes of Success, Failure and Error. I can't get Scala to resolve the case classes. There's a few examples around of this, but they all seem to be using them inside something that extends of of the parser classes. For example the tests on github are inside the same package. The example here is inside a class extending a parser.
The test i'm trying to write looks like:
package test.parsertests
import parser.InputParser // my sut
import scala.util.parsing.combinator._
import org.scalatest.FunSuite
class SetSuite extends FunSuite {
val sut = new InputParser()
test("Parsing a valid command") {
val result = sut.applyParser(sut.commandParser, "SOME VALID INPUT")
result match {
case Success(x, _) => println("Result: " + x.toString) // <-- not found: value Success
case Failure(msg, _) => println("Failure: " + msg) // similar
case Error(msg, _) => println("Error: " + msg) // similar
}
}
}
and the method I'm calling is designed to let me exersize each of my parsers on my SUT:
package parser
import scala.util.parsing.combinator._
import scala.util.parsing.combinator.syntactical._
class InputParser extends StandardTokenParsers {
def commandParser: Parser[Command] =
("Command " ~> coord ~ coord ~ direction) ^^ { case x ~ y ~ d => new Command(x, y, d) }
def applyParser[T](p: Parser[T], c: String): ParseResult[T] = {
val tokens = new lexical.Scanner(c)
phrase(p)(tokens)
}
The fundamental issue is getting the case classes resolved in my test scope. Based on the source for the Parsers class, how can I get them defined? Can I resolve this with some additional import statements, or are they only accessible via inheritance? I've tried all the combinations that should resolve this issue, but I'm obviously missing something here.
Right hand column FTW! I stumbled on an answer in this related question. The problem was identifying the case classes as nested classes of Parsers.
Related
The following code snippet is a short scala macro bundle definition from a thoughtworks project:
private[SelfType] final class Macros(val c: whitebox.Context) {
import c.universe._
def apply[A: WeakTypeTag]: Tree = {
val a = weakTypeOf[A]
val selfTypes: List[Type] = {
val selfTypeBuilder = List.newBuilder[Type]
def buildSelfTypes(t: Type): Unit = {
val dealiased = t.dealias
dealiased match {
case RefinedType(superTypes, refinedScope) =>
superTypes.foreach(buildSelfTypes)
case typeRef: TypeRef =>
val symbol = dealiased.typeSymbol
if (symbol.isClass) {
selfTypeBuilder += symbol.asClass.selfType.asSeenFrom(dealiased, symbol)
}
case _ =>
}
}
buildSelfTypes(a)
selfTypeBuilder.result()
}
val out = selfTypes match {
case Nil =>
definitions.AnyTpe
case _ =>
internal.refinedType(selfTypes, c.internal.enclosingOwner)
}
q"_root_.com.thoughtworks.feature.SelfType.make[$a, $out]"
}
}
(courtesy of https://github.com/ThoughtWorksInc/feature.scala/blob/4d19cc19016d85f26925895f43f618e1b7552d09/SelfType/src/main/scala/com/thoughtworks/feature/SelfType.scala)
The last line as a quasiquote seems to contain a lot of boilerplate text:
q"_root_.com.thoughtworks.feature.SelfType.make[$a, $out]"
Assuming that this macro bundle is defined inside a trait as part of a family polymorphism design pattern: there is no deterministic q"_root_.com.thoughtworks.feature.SelfType.make[$a, $out]", it has to be derived from an object variable vvv of the macro bundle when it is being compiled. How do I use this variable to make the quasiquote shorter and more adaptive?
There may be multiple methods to achieve this (e.g. for each implementation, define a Liftable for SelfType object). But that's even more boilerplate. I'm looking for the shortest solution. Ideally, something like this:
val sym = Term(vvv)
q"$sym.make[$a, $out]"
If you have a static reference (e.g. the type/companion is imported), you can do:
q"${symbolOf[SelfType.type]}.make[$a, $out]"
You can also use symbolOf[A].companion if you have A: WeakTypeTag but no info about its companion. That might not work if the compiler doesn't consider the object A a companion to class A
Found my first solution:
val name = SelfTypes.getClass.getCanonicalName.stripSuffix("$")
val tree = c.parse(name)
q"$tree.make[$a, $out]"
Not sure if it is the most efficient or idiomatic solution, I'll let the question hanging there for a while
I'm trying to incorporate ScalaTest into my Java project; replacing all JUnit tests with ScalaTests. At one point, I want to check if Guice's Injector injects the correct type. In Java, I have a test like this:
public class InjectorBehaviour {
#Test
public void shouldInjectCorrectTypes() {
Injector injector = Guice.createInjector(new ModuleImpl());
House house = injector.getInstance(House.class);
assertTrue(house.door() instanceof WoodenDoor);
assertTrue(house.window() instanceof BambooWindow);
assertTrue(house.roof() instanceof SlateRoof);
}
}
But I have a problem doing the same with ScalaTest:
class InjectorSpec extends Spec {
describe("An injector") {
it("should inject the correct types") {
val injector = Guice.createInjector(new ModuleImpl)
val house = injector.getInstance(classOf[House])
assert(house.door instanceof WoodenDoor)
assert(house.window instanceof BambooWindow)
assert(house.roof instanceof SlateRoof)
}
}
}
It complains that the value instanceof is not a member of Door/Window/Roof. Can't I use instanceof that way in Scala?
Scala is not Java. Scala just does not have the operator instanceof instead it has a parametric method called isInstanceOf[Type].
You might also enjoy watching a ScalaTest Crash Course.
With Scalatest 2.2.x (maybe even earlier) you can use:
anInstance mustBe a[SomeClass]
If you want to be less JUnit-esque and if you want to use ScalaTest's matchers, you can write your own property matcher that matches for type (bar type erasure).
I found this thread to be quite useful: http://groups.google.com/group/scalatest-users/browse_thread/thread/52b75133a5c70786/1440504527566dea?#1440504527566dea
You can then write assertions like:
house.door should be (anInstanceOf[WoodenDoor])
instead of
assert(house.door instanceof WoodenDoor)
The current answers about isInstanceOf[Type] and junit advice are good but I want to add one thing (for people who got to this page in a non-junit-related capacity). In many cases scala pattern matching will suit your needs. I would recommend it in those cases because it gives you the typecasting for free and leaves less room for error.
Example:
OuterType foo = blah
foo match {
case subFoo : SubType => {
subFoo.thingSubTypeDoes // no need to cast, use match variable
}
case subFoo => {
// fallthrough code
}
}
Consolidating Guillaume's ScalaTest discussion reference (and another discussion linked to by James Moore) into two methods, updated for ScalaTest 2.x and Scala 2.10 (to use ClassTag rather than manifest):
import org.scalatest.matchers._
import scala.reflect._
def ofType[T:ClassTag] = BeMatcher { obj: Any =>
val cls = classTag[T].runtimeClass
MatchResult(
obj.getClass == cls,
obj.toString + " was not an instance of " + cls.toString,
obj.toString + " was an instance of " + cls.toString
)
}
def anInstanceOf[T:ClassTag] = BeMatcher { obj: Any =>
val cls = classTag[T].runtimeClass
MatchResult(
cls.isAssignableFrom(obj.getClass),
obj.getClass.toString + " was not assignable from " + cls.toString,
obj.getClass.toString + " was assignable from " + cls.toString
)
}
I use 2.11.8 to do the assertion with collections. The newer syntax is as follows:
val scores: Map[String, Int] = Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8)
scores shouldBe a[Map[_, _]]
I have the following code
sealed trait DomainValidation {
def errorMessage: String
}
type ValidationResult[A] = ValidatedNel[DomainValidation, A]
val ai:ValidationResult[String] = "big".validNel
val bi:ValidationResult[String] = "leboski".validNel
val l = List(ai,bi)
I want to convert l to ValidationResult[List[String]]. I came across sequence functionality but I am unable to use cats sequence as some implicit has to be there which knows how to handle ValidationResult[A]. But I am unable figure out what exactly is needed. I wrote the following
object helper {
implicit class hello[A](l: List[ValidationResult[A]]) {
def mysequence: ValidationResult[List[A]] = {
val m = l.collect { case Invalid(a) => Invalid(a) }
if (m.isEmpty) l.map { case Valid(a) => a }.validNel
else /* merge the NonEmpty Lists */
}
}
}
I am able to do l.mysequence. But how do I use cats sequence.
PS: I am a scala beginner. Having a hard time learning :). Forgive for any incorrect mentions.
The following should work as expected on Scala 2.12:
import cats.data.ValidatedNel, cats.syntax.validated._
// Your code:
sealed trait DomainValidation {
def errorMessage: String
}
type ValidationResult[A] = ValidatedNel[DomainValidation, A]
val ai:ValidationResult[String] = "big".validNel
val bi:ValidationResult[String] = "leboski".validNel
val l = List(ai,bi)
And then:
scala> import cats.instances.list._, cats.syntax.traverse._
import cats.instances.list._
import cats.syntax.traverse._
scala> l.sequence
res0: ValidationResult[List[String]] = Valid(List(big, leboski))
You don't show your code or explain what's not working, so it's hard to diagnose your issue, but it's likely to be one of the following problems:
You're on Scala 2.11, where .sequence requires you to enable -Ypartial-unification in your compiler options. If you're using sbt, you can do this by adding scalacOptions += "-Ypartial-unification" to your build.sbt (assuming you're on 2.11.9+).
You've omitted one of the necessary imports. You need at least the Traverse instance for List and the syntax for Traverse. The example code above includes the two imports you need, or you can just import cats.implicits._ and make your life a little easier.
If it's not one of these two things, you'll probably need to include more detail in your question for us to be able to help.
I am working on a project that uses Slick 1.0 and the cake pattern to connect to a postgresql database.
As it is right now, everything seems to work fine, but I have a lot more tables to add and I realize that there are a number of common columns that all the tables contain. I would like to be able to make a trait that contains the common fields, but I cannot figure out how to get this to work. (I am fairly new at scala, but I think that I have the basics down pretty well.)
Here is an example that will hopefully illustrate what I want to do:
One.scala:
package models.db.slick
import java.util.UUID
import play.api.db.slick.Profile
case class One(common1:UUID, common2:String, unique1:String)
trait OneComponent{this: Profile =>
import profile.simple._
object Ones extends Table[One]("One") with CommonColumns{
def unique1 = column[String]("unique1")
def * = common1 ~ common2 ~ unique1 <> (One.apply _, One.unapply _)
}
}
ColumnColumns.scala:
package models.db.slick
import java.util.UUID
import play.api.db.slick.Profile
trait CommonColumns{
def common1 = column[UUID]("common1")
def common2 = column[String]("common2")
}
This does not compile because the ColumnColumns trait doesn't know column[T]. I tried specifying a self type of Table, but I can't figure out how to get to the Table object which is itself in a the scala.slick.driver.BasicTableComponent trait. I also tried to specify a self type that implements a column function like:
trait CommonColumns{ this => {def column[C](n: String, options:
scala.slick.lifted.ColumnOption[C]* )
(implicit tm:scala.slick.lifted.TypeMapper[C]
): scala.slick.lifted.Column[C]}
...
}
but that doesn't work. I most likely have the syntax wrong on that one, but I can't find a good example of how to do this.
What do you think? Is there a good way to get this done?
I figured it out!
At least I think I did. If anyone notices something wrong with this, please let me know.
OK, so here is how I did it:
I changed the CommonColumns trait to be:
trait CommonColumnsComponent{ this:Profile =>
import profile.simple._
trait CommonColumns{ this:Table[_] =>
def common1 = column[UUID]("common1")
def common2 = column[String]("common2")
}
}
and then I changed OneComponent to:
trait OneComponent extends CommonColumnsComponent{this: Profile =>
import profile.simple._
object Ones extends Table[One]("One") with CommonColumns{
def unique1 = column[String]("unique1")
def * = common1 ~ common2 ~ unique1 <> (One.apply _, One.unapply _)
}
}
and it worked.
Based on available documentation this task seems straightforward, however I've been hitting my head in the wall for a couple of days on this and still can't make it work for a simple inter-module dependency...
Here's a reduced example:
trait Bla {
def m: String
}
class BlaImpl(implicit val bindingModule: BindingModule) extends Bla with Injectable {
val s = inject[String]('bla)
def m = "got " + s
}
object Program extends App with Injectable {
implicit val bindingModule =
new NewBindingModule({ implicit module ⇒ module.bind[Bla] toSingle { new BlaImpl } }) ~
new NewBindingModule(_.bind[String] idBy 'bla toSingle "bla!")
val bla = inject[Bla]
assert(bla.m == "got bla!")
}
Running this code fails with the following error, When trying to build the BlaImpl instance:
org.scala_tools.subcut.inject.BindingException: No binding for key BindingKey(java.lang.String,Some(bla))
Debugging shows that the binding module handed to BlaImpl's constructor doesn't contain the 'bla String in its bindings, and that Program.bindingModule.bindings has all bindings (including the needed String).
I've seen other question similar but it dows refer only to composition but not to dependencies crossing module borders.
What am I doing wrong?
Unfortunately it will not work. Even if you merge 2 modules together
with subcut, this does not mean that they will see each-others dependencies.
If you want to archive desired results, then you need to pass BindingModule explicitly to the BlaImpl constructor. Something like this:
val anotherModule = new NewBindingModule(_.bind[String] idBy 'bla toSingle "bla!")
implicit val bindingModule =
new NewBindingModule({ implicit module => module.bind[Bla] toSingle { new BlaImpl()(anotherModule) } })
Module merge will not do the trick in this case. I actually discussed this problem of subcut in this answer. I even created a example code that compares subcut and Scaldi and demonstrates how they both solve this problem (or don't solve it, in case of subcut):
https://gist.github.com/OlegIlyenko/5623423
If I would rewrite your example with Scaldi, then it would be something like this:
import scaldi.{Injector, Injectable, Module, DynamicModule}
trait Bla {
def m: String
}
class BlaImpl(implicit inj: Injector) extends Bla with Injectable {
val s = inject[String]('bla)
def m = "got " + s
}
object Program extends App with Injectable {
implicit val appModule =
new Module { bind [Bla] to new BlaImpl } ::
DynamicModule(_.binding identifiedBy 'bla to "bla!")
val bla = inject [Bla]
assert(bla.m == "got bla!")
}
As you can see, in Scaldi modules can see each-others dependencies if they are composed with :: or ++.