Problem writing HaveMatcher on scala.xml.Node

72 views
Skip to first unread message

Matt

unread,
Apr 24, 2012, 10:58:39 AM4/24/12
to scalatest-users
I'm trying to write a custom HaveMatcher so I can test a boolean
attribute on an XML node. Specifically, I want this so that when the
test fails, I can see the text of the entire node, rather than
"expected true, got false".

Following the example from http://www.scalatest.org/scaladoc/1.7.2/#org.scalatest.matchers.HavePropertyMatcher
I have:

[code]
import org.scalatest.matchers._
import org.scalatest._
import scala.xml.Node

trait NodeHaveMatchers {
def completeStatus(expectedValue: Boolean):
HavePropertyMatcher[Node, Boolean] = {
new HavePropertyMatcher[Node, Boolean] {
def apply(node: Node) = {
HavePropertyMatchResult(
(node \ "@complete").toString.toBoolean == expectedValue,
"complete",
expectedValue,
(node \ "@complete").toString.toBoolean
)
}
}
}
}

class NodeSpec extends Spec with ShouldMatchers with NodeHaveMatchers
{

describe("A node") {
it("should have the complete status") {

val summary: Node = <summary complete="true" />
summary should have (
completeStatus (true),
)
}
}
}
[code]

The trait compiles fine, but when I can't get the call site to
compile. Any direction would be very helpful, thanks.

error: overloaded method value should with alternatives:
[ERROR] (beWord:
NodeSpec.this.BeWord)NodeSpec.this.ResultOfBeWordForAnyRef[Seq[scala.xml.Node]]
<and>
[ERROR] (notWord:
NodeSpec.this.NotWord)NodeSpec.this.ResultOfNotWordForAnyRef[Seq[scala.xml.Node]]
<and>
[ERROR] (haveWord:
NodeSpec.this.HaveWord)NodeSpec.this.ResultOfHaveWordForSeq[scala.xml.Node]
<and>
[ERROR] (rightMatcher:
org.scalatest.matchers.Matcher[Seq[scala.xml.Node]])Unit
[ERROR] cannot be applied to
(org.scalatest.matchers.Matcher[scala.xml.Node])
[ERROR] summary should have (completeStatus (true))

Bill Venners

unread,
Apr 24, 2012, 11:37:57 AM4/24/12
to scalate...@googlegroups.com
Hi Matt,

The problem here is that a Node is a Seq[Node], so it is looking on
ResultOfHaveWordForSeq[Node] instead of Have on AnyRef, because that
implicit is more specific. Or something like that. Having Node be a
Seq[Node] is a very questionable design choice, but to deal with it
you need to say Seq[Node] not Node when you make the
HavePropertyMatcher. This compiles:

import org.scalatest.matchers._
import org.scalatest._
import scala.xml.Node

trait NodeHaveMatchers {
def completeStatus(expectedValue: Boolean):

HavePropertyMatcher[Seq[Node], Boolean] = {
new HavePropertyMatcher[Seq[Node], Boolean] {
def apply(node: Seq[Node]) = {


HavePropertyMatchResult(
(node \ "@complete").toString.toBoolean == expectedValue,
"complete",
expectedValue,
(node \ "@complete").toString.toBoolean
)
}
}
}
}

class NodeSpec extends Spec with ShouldMatchers with NodeHaveMatchers {

describe("A node") {
it("should have the complete status") {

val summary: Node = <summary complete="true" />
summary should have (
completeStatus (true)

)
}
}
}

And runs too:

scala> import org.scalatest._
import org.scalatest._

scala> run(new NodeSpec)
NodeSpec:
A node
- should have the complete status

I'll think about whether I could do anything to make this smoother.

Bill

> --
> You received this message because you are subscribed to the Google
> Groups "scalatest-users" group.
> To post to this group, send email to scalate...@googlegroups.com
> To unsubscribe from this group, send email to
> scalatest-use...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/scalatest-users?hl=en
> ScalaTest itself, and documentation, is available here:
> http://www.artima.com/scalatest

--
Bill Venners
Artima, Inc.
http://www.artima.com

Matt Hughes

unread,
Apr 24, 2012, 11:42:52 AM4/24/12
to scalate...@googlegroups.com
Ahh that certainly explains the compiler message.  Thanks a lot!
Reply all
Reply to author
Forward
0 new messages