我正在尝试检查案例类列表是否包含一个特定的实例,但是当我尝试这样做时,我收到以下错误:
[info] Compiling 1 Scala source to /home/matt/Documents/transledge/app/target/scala-2.9.2/test-classes...
[error] /home/matt/Documents/transledge/app/src/test/scala/com/transledge/drewes/parser_suite.scala:40: overloaded method value should with alternatives:
[error] (notWord: ParserSuite.this.NotWord)ParserSuite.this.ResultOfNotWordForSeq[com.transledge.Instruction,List[com.transledge.Instruction]] <and>
[error] (haveWord: ParserSuite.this.HaveWord)ParserSuite.this.ResultOfHaveWordForSeq[com.transledge.Instruction] <and>
[error] (beWord: ParserSuite.this.BeWord)ParserSuite.this.ResultOfBeWordForAnyRef[List[com.transledge.Instruction]] <and>
[error] (rightMatcher: org.scalatest.matchers.Matcher[List[com.transledge.Instruction]])Unit
[error] cannot be applied to (org.scalatest.matchers.Matcher[Traversable[com.transledge.AddNode]])
[error] parsing(square_node, input) should contain(AddNode("foo"))
[error] ^
[error] one error found
[error] (test:compile) Compilation failed
[error] Total time: 3 s, completed 21-Feb-2013 15:15:04
有问题的测试套件是:
import org.scalatest.FunSpec
import scala.util.parsing.combinator._
import com.transledge.drewes.{Parser => DrewesParser}
import com.transledge._
import org.scalatest.matchers.ShouldMatchers
class ParserSuite extends DrewesParser with FunSpec with ShouldMatchers {
def parsing[A](parser: Parser[A], input: String): A = parse(parser, input).get
// snipping other tests
describe("square_node") {
val input = """\squarenode{foo}(1cm, 2cm)"""
it("should create a node") {
parsing(square_node, input) should contain(AddNode("foo")) // Line 40
}
}
}
AddNode
/ Instruction
的定义非常基本:
package com.transledge
abstract class Instruction
case class AddNode(id: String) extends Instruction
以下是解析器的简要定义:
package com.transledge.drewes
import scala.util.parsing.combinator._
import com.transledge._
trait Parser extends RegexParsers {
def node_id: Parser[String] = "[a-zA-Z\\-_:0-9]+".r
def node_name: Parser[String] = ("{" ~> node_id <~ "}") | node_id
def point: Parser[String] = "[^,()]+".r
def position: Parser[(String, String)] = "(" ~> point ~ "," ~ point <~ ")" ^^ { case a ~ "," ~ b => (a.trim, b.trim) }
def square_node: Parser[List[Instruction]] = "\\squarenode" ~> node_name ~ position ^^ { case name ~ position => List(AddNode(name)) }
}
我对此的理解是Scala编译器应该使用变体should(rightMatcher: Matcher[List[T]])
,但是获取Traversable
而不是List
的实例,以及Traversable
是List
包含的特征,Traversable
不能在List
预期的位置使用。
那么如何检查列表是否包含元素?
答案 0 :(得分:6)
这是如何实施的简化图片:
trait Matcher[T]
implicit class ListShouldWrapper[T](a:List[T]) {
def should(rightMatcher: Matcher[List[T]]): Unit = ???
}
object contain {
def apply[T](expectedElement: T): Matcher[GenTraversable[T]] = ???
}
如果您使用以下方法测试该实现:
val x:List[Int] = ???
x should contain(3)
您将收到编译错误,告知您已找到GenTraversable
且需要List
。如果我们实现如下所示的实现可能会更好。请注意,这不是实际的解决方案,因为这只是一些孤立的代码。
trait Matcher[T]
implicit class AnyToShould[T](a: T) {
def should(a: Matcher[T]) = ???
}
def contain[C[_] <: Traversable[_], T](x:T):Matcher[C[T]] = ???
问题是可以解决的,所以我建议你提交一个错误(甚至可能自己创建一个补丁)。为了能够继续,你有几个选择:
def square_node: Parser[List[Instruction]]
contain
方法,返回Matcher