2017-04-17 3 views
3

J'écris un générateur FsCheck pour créer des chaînes ayant les propriétés suivantes:Comment définir un générateur FsCheck afin qu'il puisse découvrir

  • Ils sont non nulle
  • les parage ne sera pas affecter la longueur
  • Ils ne contiennent aucun espace.

Voici mon code générateur:

namespace Example 

open FsCheck.Arb 

module public Generation = 

    let hasChars (s : string) = 
     (isNull s |> not) 
     && s.Length > 0 

    let isTrimmed (s : string) = 
     s.Trim().Length = s.Length 

    let isContinuous (s : string) = 
     s 
     |> Seq.exists ((=) ' ') 
     |> not 

    [<AbstractClass; Sealed>] 
    type public Generators = class end 

    type public ContinuousString = ContinuousString of string with 
     member x.Get = match x with ContinuousString r -> r 
     override x.ToString() = x.Get 

    type public Generators with 

     static member ContinuousString() = 
      Default.String() 
      |> filter hasChars 
      |> filter isTrimmed 
      |> filter isContinuous 
      |> convert ContinuousString string 

Et voici un test destiné à vérifier la génération:

[<Property(Arbitrary=[| typeof<ContinuousString> |], MaxTest=2)>] 
let ``A continuous string contains no spaces`` (s: ContinuousString) = 
    s.Get.Contains " " |> not 

Quand je lance ce test, je reçois:

System.Exception: No instances found on type Example.Generation+ContinuousString. Check that the type is public and has public static members with the right signature. 

Pour autant que je peux dire en regardant le code source FSCheck, le membre que j'ai Une amende devrait être trouvée par le filtre de découverte, et la méthode semble analogue à ceux intégrés similaires tels que NonEmptyString.

Qu'est-ce que j'ai manqué? Merci!

+1

Je pense que 'typeof ' devrait être 'typeof '. Aussi, je ne pense pas que vous ayez besoin de le définir deux fois: la définition 'type public Generators = class end' ne fait rien pour vous, AFAIK. – rmunn

+0

Aussi: 'isNull s |> not' pourrait être juste' s <> null'. Aussi: 'ContinuousString.Get' est une propriété, mais nommé comme une méthode. De plus: vous n'avez pas besoin de 'Get', vous pouvez définir le paramètre de la fonction de test en tant que' (ContinuousString s) 'au lieu de' (s: ContinuousString) '. –

+0

Super, merci @rmunn! Le 'typeof <>' corrigé l'a corrigé. Le type vide était juste là, donc je reproduisais le plus fidèlement possible le code de FSCheck - je ne m'attendais pas à ce qu'il ait un effet. Si vous voulez transférer votre commentaire à une réponse, je marquerai comme accepté. Merci encore! – Kit

Répondre

5

Vous passez le mauvais type FsCheck. Vous devriez passer votre classe Generators, pas votre ContinuousString DU. -À-dire, ceci:

[<Property(Arbitrary=[| typeof<ContinuousString> |], MaxTest=2)>] 
let ``A continuous string contains no spaces`` (s: ContinuousString) = 
    s.Get.Contains " " |> not 

aurait dû être:

[<Property(Arbitrary=[| typeof<Generators> |], MaxTest=2)>] 
let ``A continuous string contains no spaces`` (s: ContinuousString) = 
    s.Get.Contains " " |> not 

Le message d'erreur FsCheck a essayé de vous le dire ainsi:

Vérifiez que le type est public et a publique membres statiques avec la bonne signature.

Le type que vous avez créé qui correspond à ce qu'il recherche est Generators.