Как переопределить некоторые генераторы для ScalaCheck, чтобы заставить (автоматически) генерировать очищенные типы? Только непустые списки, например - PullRequest
2 голосов
/ 28 марта 2019

У меня довольно большая структура классов дел, и где-то глубоко внутри этой структуры у меня есть поля, которые я хочу уточнить, например, сделать списки непустыми. Можно ли сказать ScalaCheck, чтобы эти списки были непустыми, используя автоматический вывод из проекта scalacheck-magnolia (без указания каждого поля отдельно)? Пример:

import com.mrdziuban.ScalacheckMagnolia.deriveArbitrary
import org.scalacheck.Arbitrary
import org.scalacheck.Gen

case class A(b: B, c: C)
case class B(list: List[Long])
case class C(list: List[Long])

// I've tried:
def genNEL[T: Gen]: Gen[List[T]] = Gen.nonEmptyListOf(implicitly[Gen[T]])
implicit val deriveNEL = Arbitrary(genNEL)

implicit val deriveA = implicitly[Arbitrary[A]](deriveArbitrary)

Но это не сработало.

1 Ответ

1 голос
/ 28 марта 2019

Я не уверен, как быть универсальным, так как я не знаком с получением автоматической деривации для Arbitrary с scalacheck-magnolia.Кажется, что scalacheck-magnolia хорош для получения Arbitrary для классов дел, но, возможно, не для контейнеров (списков, векторов, массивов и т. Д.).

Если вы хотите просто использовать простой ScalaCheck, вымог бы просто определить неявное Arbitrary для A.Делать это вручную - это дополнительный пример, но у вас есть преимущество в том, что вы имеете больший контроль, если хотите использовать разные генераторы для разных частей вашей структуры данных.

Вот пример, где список Arbitrarylongs не является пустым по умолчанию, но пуст для B.

implicit val listOfLong =
  Arbitrary(Gen.nonEmptyListOf(Arbitrary.arbitrary[Long]))


implicit val arbC = Arbitrary {
  Gen.resultOf(C)
}

implicit val arbB = Arbitrary {
  implicit val listOfLong =
    Arbitrary(Gen.listOf(Arbitrary.arbitrary[Long]))
  Gen.resultOf(B)
}

implicit val arbA = Arbitrary {
  Gen.resultOf(A)
}

property("arbitrary[A]") = {
  Prop.forAll { a: A =>
    a.b.list.size >= 0 && a.c.list.size > 0
  }
}
...