Как использовать ScalaTest "содержать allOf" в двух списках?

Я искал матчи ScalaTest, чтобы проверить, что список содержит все необходимые элементы (данные в другом списке), но это могут быть и другие.

contain allOf требует получить два фиксированных элемента по какой-либо причине, остальные как varargs.

Я могу сделать обходной путь, как это, но это ужасно уродливо:

val list = List(1,2,3,4)
val wanted = List(1,2,3)
list should contain allOf ( wanted.head, wanted.tail.head, wanted.tail.tail  :_* )    // ugly workaround

Для указания списка в качестве совпадения есть contain theSameElementsAs. Однако, это не позволяет посторонним элементам находиться в пробном значении (я думаю).

Итак:

  • Я что-то упустил?
  • Почему allOf объявлен таким образом, что ему должны быть заданы два фиксированных элемента в фронте (т.е. почему бы не просто передать varargs?)
  • должен ли быть метод theSameElementsAndMaybeMoreThan (предположительно с лучшим именем)?

Некоторый код, который я пробовал с помощью:

val list = List.empty[String]
//list should contain allOf("a")         // does not compile
list should contain allOf("a","b")
list should contain allOf("a","b","c")

val wanted = List("a","b","c")
//list should contain allOf( wanted )    // does not compile
list should contain allOf( wanted.head, wanted.tail )   // compiles, but tests the wrong thing; against List(head,List(tail))

документация:

Scala 2.11.4, ScalaTest 2.2.1

Edit:

Я, вероятно, в конечном итоге использую что-то вроде:

wanted.foreach( list should contain(_) )

Однако это не кажется мне доступным для чтения (should является встроенным) как встроенные конструкторы коллекции.

Ответ 1

Билл Веннерс сказал это в списке рассылки ScalaTest:

Да, мы не хотели задерживать выпуск 2.0, чтобы добавить это, но так как добавил. Я считаю, что мы добавили его к мастеру, хотя и не 2.2.x филиал. Независимо от того, синтаксис выглядит следующим образом:

xSet should contain allElementsOf (ySet)

Ссылка на сообщение.

Ответ 2

Я не думаю, что для этого есть веская причина. Вы можете исправить это с помощью сутенера моего класса:

object ScalaTestUtils {
    import org.scalatest.words.ResultOfContainWord

    implicit class ResultOfContainWordImprovements[T](val contains: ResultOfContainWord[Seq[T]]) {
        def allOf(right: Seq[T]) = contains allOf(right.head, right.tail.head, right.tail.tail :_*)
    }
}

Вероятно, вы должны сделать эту учетную запись для Seqs с менее чем двумя элементами (для которых это не получится).

Затем вы можете сделать:

import ScalaTestUtils._
Seq(1, 2, 3) should contain allOf Seq(1, 2)

Ответ 3

Еще одно возможное решение:

import org.scalatest.Inspectors.forAll

forAll(list) { wanted should contain(_) }

Ожидайте сообщение об ошибке, подобное этому:

scala> forAll(List(1, 2)) { List(1) should contain(_) }
org.scalatest.exceptions.TestFailedException: forAll failed, because:
  at index 1, List(1) did not contain element 2 (<console>:18)
in List(1, 2)
...
Caused by: org.scalatest.exceptions.TestFailedException: List(1) did not contain element 2