2010-09-07 6 views
2

Dans le user guide de scalacheck il y a le paragraphe "Générer des classes de cas". Je modifié par exemple de celui-ci à utiliser des classes régulières au lieu des classes de cas:Générateurs pour les classes régulières dans scalacheck

import org.scalacheck._ 
import Gen._ 
import Arbitrary._ 

sealed abstract class Tree 
object Leaf extends Tree 
class Node(left:Tree, rigth:Tree, v:Int) extends Tree 

object Main { 

    val genLeaf = value(Leaf) 
    val genNode = for{ 
    v <- Arbitrary.arbitrary[Int] 
    left <- genTree 
    rigth <- genTree 
    } yield new Node(left, rigth, v) 

    val genTree:Gen[Tree] = oneOf(genLeaf, genNode) 


    def main(args:Array[String]){  
    println(genTree.sample) 
    } 
} 

Il tout semble fonctionner mais j'ai peur d'utiliser cette approche dans le code de production avant que je demande ici: est-il des pièges?

Répondre

2

Cela devrait fonctionner correctement. Il n'y a rien sur les classes de cas qui sont particulièrement magiques à propos des classes de cas en ce qui concerne ScalaCheck. Toute ancienne classe peut obtenir un générateur, ou même être convertible en Arbitraire. En ce qui concerne les tests, une différence est que chaque arbre non-case-case que vous générez sera unique, et donc pour deux arbres que vous générez, tree1 == tree2. Cela est différent de ce qu'il est avec la classe de cas, qui testent l'égalité en fonction de la valeur plutôt que de l'identité. Vous aurez peut-être besoin de plus de tests pour gérer les problèmes d'alias qui deviennent possibles lorsque vous avez une égalité basée sur l'identité plutôt que sur la valeur.

2

Je ne vois aucun problème ici. La raison pour laquelle les classes de cas sont utilisées dans cet exemple est que le Tree affiché est un type de données algébriques, rendu possible par les classes de cas. Avec les classes normales, vous ne pouvez pas faire correspondre le motif sur l'arbre, et, en fait, vous ne pourrez même pas obtenir left, right et v sans les déclarer val.

Questions connexes