3

ケースクラスのリストに特定のインスタンスが含まれていることを確認しようとしていますが、そうしようとすると、次のエラーが発生します。

[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]])インスタンスを取得しており、を含む特性と同様に、期待される場所では使用できません。TraversableListTraversableListTraversableList

では、リストに要素が含まれていることを確認するにはどうすればよいですか?

4

1 に答える 1

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
  • 別のScala仕様ライブラリを使用する
于 2013-02-21T22:39:12.573 に答える