scala - ScalaTest - writing custom matchers -


i running problem while writing custom matcher nodeseq:

private def matchxml(expected: nodeseq) = new matcher[nodeseq] {   def apply(left: nodeseq): matchresult = matchresult(left xml_== expected,     "xml structure not same (watch spaces in tag texts)",     "xml messages equal") } 

this compiles, following piece of code:

val expected : nodeseq = ... val xml : nodeseq = ...  xml should matchxml(expected) 

causes:

error: overloaded method value should alternatives: (beword: xmlstripdecoratortests.this.beword)xmlstripdecoratortests.this.resultofbewordforanyref[scala.collection.genseq[scala.xml.node]] <and> (notword: xmlstripdecoratortests.this.notword)xmlstripdecoratortests.this.resultofnotwordforanyref[scala.collection.genseq[scala.xml.node]] <and> (haveword: xmlstripdecoratortests.this.haveword)xmlstripdecoratortests.this.resultofhavewordforseq[scala.xml.node] <and> (rightmatcher: org.scalatest.matchers.matcher[scala.collection.genseq[scala.xml.node]])unit cannot applied (org.scalatest.matchers.matcher[scala.xml.nodeseq]) xml should (matchxml(expected)) 

any ideas means?

why fails typecheck:

the type checker works in following way.

xml.should(matchxml(expected)) 
  • because method should not part of nodeseq, compiler tries find implicit conversion xml shouldmatcher. book "programming in scala" specifies such implicit conversion should specific:

"up through scala 2.7, end of story. whenever multiple implicit conversions applied, compiler refused choose between them. ... scala 2.8 loosens rule. if 1 of available conversions strictly more specific others, compiler choose more specific one. ... 1 implicit conversion more specific if 1 of following applies: argument type of former subtype of latter’s. .."

  • because nodeseq extends seq[node], following function

    converttoseqshouldwrapper[t](o : scala.genseq[t]) : seqshouldwrapper[t]

    is therefore specific 1 among others.

the program rewritten as:

`converttoseqshouldwrapper(xml).should(matchxml(expected))` 

where converttoseqshouldwrapper(xml) seqshouldwrapper[t] t = genseq[node].

the method should seqshouldwrapper accepts matcher[t] function of type t => matchresult. therefore, accepts matcher[genseq[node]].

because t appearing left of arrow, matchers not covariant in t, contravariant. nodeseq genseq[node], matcher[genseq[node]] matcher[nodeseq], not opposite.this explains above error, method should cannot accept matcher[nodeseq] , requires matcher[genseq[node]].

2 solutions

  • replace instances of nodeseq genseq[node] type matches everywhere.
  • alternatively, wrap xml explicitely conversion function.

    converttoanyshouldwrapper(xml).should(matchxml(expected))


Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -