web-dev-qa-db-fra.com

Comparaison du contenu d'une collection avec ScalaTest

J'essaie de tester un peu certains Scala qui est très chargé en collections. Ces collections sont renvoyées sous la forme Iterable[T], je m'intéresse donc au contenu de la collection, même si les types sous-jacents diffèrent. Il s'agit en fait de deux problèmes liés:

  1. Comment puis-je affirmer que deux collections ordonnées contiennent la même séquence d'éléments?
  2. Comment puis-je affirmer que deux collections non ordonnées contiennent le même ensemble d'éléments?

En résumé, je cherche l'équivalent Scala de NUnit CollectionAssert.AreEqual (commandé) et CollectionAssert.AreEquivalent (non ordonné) dans ScalaTest:

Set(1, 2) should equal (List(1, 2))          // ordered, pass
Iterable(2, 1) should equal (Iterable(1, 2)) // unordered, pass
40
Michael Koval

Tu pourrais essayer .toSeq pour les collections ordonnées et .toSet pour non ordonné, qui capture ce que vous voulez pour autant que je le comprenne.

Les passes suivantes:

class Temp extends FunSuite with ShouldMatchers {
  test("1")  { Array(1, 2).toSeq should equal (List(1, 2).toSeq) }
  test("2")  { Array(2, 1).toSeq should not equal (List(1, 2).toSeq) }
  test("2b") { Array(2, 1) should not equal (List(1, 2)) }  
  test("3")  { Iterable(2, 1).toSet should equal (Iterable(1, 2).toSet) }
  test("4")  { Iterable(2, 1) should not equal (Iterable(1, 2)) }
}

BTW un Set n'est pas commandé.

edit: Pour éviter de supprimer les éléments en double, essayez toSeq.sorted. Le pass suivant:

  test("5")  { Iterable(2, 1).toSeq.sorted should equal (Iterable(1, 2).toSeq.sorted) }
  test("6")  { Iterable(2, 1).toSeq should not equal (Iterable(1, 2).toSeq) }

edit 2: Pour les collections non ordonnées où les éléments ne peuvent pas être triés, vous pouvez utiliser cette méthode:

  def sameAs[A](c: Traversable[A], d: Traversable[A]): Boolean = 
    if (c.isEmpty) d.isEmpty
    else {
      val (e, f) = d span (c.head !=)
      if (f.isEmpty) false else sameAs(c.tail, e ++ f.tail)
    }

par exemple. (notez l'utilisation des symboles 'a 'b 'c sans ordre défini)

  test("7")  { assert( sameAs(Iterable(2, 1),    Iterable(1, 2)     )) }
  test("8")  { assert( sameAs(Array('a, 'c, 'b), List('c, 'a, 'b)   )) }
  test("9")  { assert( sameAs("cba",             Set('a', 'b', 'c') )) }

Implémentation alternative de sameAs:

  def sameAs[A](c: Traversable[A], d: Traversable[A]) = {
    def counts(e: Traversable[A]) = e groupBy identity mapValues (_.size)
    counts(c) == counts(d)
  }
22
Luigi Plinge

Pendant ce temps, vous pouvez utiliser

Iterable(2, 1) should contain theSameElementsAs Iterable(1, 2)

Pour tester l'ensemble ordonné, vous devez le convertir en une séquence.

Set(1, 2).toSeq should contain theSameElementsInOrderAs List(1, 2)
89