Создать произвольную функцию 1 в ScalaCheck - PullRequest
2 голосов
/ 15 января 2020

Для моего тестирования я хотел бы сгенерировать произвольные случайные функции типа String => Boolean.

Возможно ли это сделать с помощью ScalaCheck?

Ответы [ 2 ]

5 голосов
/ 15 января 2020

Да, точно так же, как вы генерировали бы произвольные значения других типов:

import org.scalacheck._

// Int instead of Boolean to better see that it is a function
val arb = implicitly[Arbitrary[String => Int]].arbitrary.sample.get

println(arb("a"))
println(arb("a")) // same
println(arb("b"))

, потому что существуют неявные Cogen[String] и Arbitrary[Boolean]. Cogen не задокументировано в руководстве пользователя, но оно эквивалентно CoArbitrary QuickCheck, которое объясняется в https://kseo.github.io/posts/2016-12-14-how-quick-check-generate-random-functions.html и https://begriffs.com/posts/2017-01-14-design-use-quickcheck.html (в разделе «CoArbitrary and Gen (a -> b) ").

Можно ли тогда генерировать произвольную функцию из класса случайных случаев? Например,

case class File(name: Str, size:Long)

Этого должно быть достаточно для определения Cogen[File]. Либо вручную:

implicit val cogenFile: Cogen[File] = Cogen { 
  (seed: Seed, file: File) => Cogen.perturbPair(seed, (file.name, file.size))
}

Чуть больше кода, но обобщается более чем в 2 поля:

implicit val cogenFile: Cogen[File] = Cogen { (seed: Seed, file: File) => 
  val seed1 = Cogen.perturb(seed, file.name)
  Cogen.perturb(seed1, file.size)
}

Или автоматически используется scalacheck-shapeless :

implicit val cogenFile: Cogen[File] = MkCogen[File].cogen
2 голосов
/ 15 января 2020

Не думаю, что вам нужно что-то генерировать. Если вам нужна случайная функция, просто создайте случайную функцию:

    val randomFunction: String => Boolean = _ => Random.nextBoolean 

Или если вы хотите, чтобы вывод был стабильным (тот же результат для нескольких вызовов одной и той же функции с одним и тем же параметром):

   def newRandomFunction: String => Boolean =
     mutable.Map.empty[String, Boolean].getOrElseUpdate(_, Random.nextBoolean)
...