1

I have been working with some XML data and have been trying to write a test that tries to match that the direct children of two xml trees have all the same nodes of type bar.

I started off using a simple test to ensure that both data structures match.

The assertion matching them as strings works:

result.toString should be(expected.toString)

but the assertion matching each individual element fails:

result should contain allElementsOf expected

which I found on this answer here

because these simpler assertion did not work:

result should be(expected)
result should contain(expected(1))

The test sets up the XML using before block in the test class:

  var foo: Elem = _

  before {
   foo = <foo>
     <bar type="greet" style="pleasent" target="anyone">hi</bar>
     <bar type="count">1</bar>
     <bar type="color">yellow</bar>
     <baz>
      <bar type="bad">Bad</bar>
    </baz>
  </foo>
}

This is the code of the test:

it should "allow use of map and filter" in {
  import scala.collection.mutable.ArrayBuffer

  val expected = ArrayBuffer(
    (
      "bar",
      Map(
        "type" -> "greet",
        "style" -> "pleasent",
        "target" -> "anyone"
      ),
      "hi"
    ),
    (
      "bar",
      Map("type" -> "count"),
      "1"
    ),
    (
      "bar",
      Map("type" -> "color"),
      "yellow"
    )
  )

  val result = foo.child.map(x => {
    x match {
      case <bar>{text}</bar> => (x.label, x.attributes.asAttrMap, text)
      case <baz>_</baz> => (x.label, Map[String,String](), "")
      case _ => ("", Map[String,String](), "")
    }
  })
  .filter(x => {
    x match {
      case ("bar", _, _) => true
      case _ => false
    }
  })


  result.toString should be(expected.toString) // works
 // result should contain allElementsOf expected // fails

}

vamsiampolu
  • 6,328
  • 19
  • 82
  • 183
  • I'm not sure of what the question is. :) – stefanobaghino Dec 07 '17 at 07:52
  • I want to know what the appropriate assertion to use here and why my assertion is failing. My source code is **[here](https://github.com/vamsiampolu/scalaexercises/blob/master/src/test/scala/example/XmlSpec.scala#L262)** . Could it be because I use `OptionValues` trait of scalatest? – vamsiampolu Dec 07 '17 at 08:21

1 Answers1

2

The type of elements in the collections you are comparing are different:

  • result contains elements of type (String, Map[String, String], Object)
  • expected contains elements of type (String, Map[String, String], String)

They might have the same toString representation, but that doesn't mean they are equal. The type of result is probably not what you expected from this pattern match:

x match {
  case <bar>{text}</bar> => (x.label, x.attributes.asAttrMap, text)
  case <baz>_</baz> => (x.label, Map[String,String](), "")
  case _ => ("", Map[String,String](), "")
}

Here text is of type xml.Node. If you want to extract the contents of the node you can use text.text which also makes the test pass.

Aside: Recently there was a PR merged to Scala to issue a warning when the Object type is inferred (scala/scala#6178), because it's usually a programmer error.

g.krastev
  • 1,193
  • 7
  • 19