Написание собственного сопоставления для NodeSeq

Я пытаюсь написать простой пользовательский сопоставитель для NodeSeq с помощью scalatest v.2.0.M5b.

package test

import org.scalatest.matchers.{MatchResult, Matcher, ShouldMatchers}

import scala.xml.NodeSeq
import org.scalatest.FunSpec

class MySpec extends FunSpec with ShouldMatchers with MyMatcher {

  describe("where is wrong?") {
    it("showOK") {
      val xml = <span>abc</span>
      xml should contn("b")
    }
  }
}

trait MyMatcher {

  class XmlMatcher(str: String) extends Matcher[NodeSeq] {
    def apply(xml: NodeSeq) = {
      val x = xml.toString.contains(str)
      MatchResult(
        x,
        "aaa",
        "bbb"
      )
    }
  }

  def contn(str: String) = new XmlMatcher(str)

}

Когда я компилирую его, он сообщает об ошибке:

[error] /Users/freewind/src/test/scala/test/MyMacher.scala:14: overloaded method value should with alternatives:
[error]   (beWord: MySpec.this.BeWord)MySpec.this.ResultOfBeWordForAnyRef[scala.collection.GenSeq[scala.xml.Node]] <and>
[error]   (notWord: MySpec.this.NotWord)MySpec.this.ResultOfNotWordForAnyRef[scala.collection.GenSeq[scala.xml.Node]] <and>
[error]   (haveWord: MySpec.this.HaveWord)MySpec.this.ResultOfHaveWordForSeq[scala.xml.Node] <and>
[error]   (rightMatcher: org.scalatest.matchers.Matcher[scala.collection.GenSeq[scala.xml.Node]])Unit
[error]  cannot be applied to (MySpec.this.XmlMatcher)
[error]       xml should contn("b")
[error]           ^
[error] one error found
[error] (test:compile) Compilation failed

Где не так?


Обновлять:

Файл build.sbt, который я использую:

name := "scalatest-test"

scalaVersion := "2.10.1"

version := "1.0"

resolvers ++= Seq("snapshots"     at "http://oss.sonatype.org/content/repositories/snapshots",
            "releases"        at "http://oss.sonatype.org/content/repositories/releases",
            "googlecode"      at "http://sass-java.googlecode.com/svn/repo"
            )

libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M5b" % "test"

И демонстрационный проект: https://github.com/freewind/scalest-test.


person Freewind    schedule 14.06.2013    source источник


Ответы (1)


По причине того, что компилятор scala жалуется, см. этот ответ.

Но похоже, что с тех пор ScalaTest API сильно изменился, поэтому оба предложенных решения нуждаются в некоторой модификации (проверено для ScalaTest 2.0.M5b):

  • Замените все экземпляры NodeSeq на GenSeq[Node], чтобы тип везде совпадал.

    См. SeqShouldWrapper класс ScalaTest.

  • В качестве альтернативы, оберните xml явно с помощью функции преобразования, т.е. вручную задайте требуемый тип, но я не рекомендую этого, потому что это делает клиентский код уродливым.

    new AnyRefShouldWrapper(xml).should(contn("b"))

Кстати, хорошо иметь небольшой, но полный проект на github, чтобы другие могли его настроить. Это делает этот вопрос гораздо более привлекательным.

person xiefei    schedule 14.06.2013