2017-07-06 9 views
1

Ich habe eine Eigenschaft, die ich auf eine Sammlung von Stuff testen möchte, wo eine der Stuff eine bestimmte Eigenschaft erfüllt. Ich habe eine Möglichkeit, eine Stuff zu erzeugen, die die Eigenschaft erfüllt, und eine Möglichkeit, ein Stuff zu erzeugen, das nicht tut.Kombinieren von zwei Generatoren zu einem einzigen willkürlichen in FsCheck

Heute mache ich so etwas wie diese (ja, ich bin FsCheck in C#):

IEnumerable<Stuff> GetStuffCollection(int input) 
{ 
    yield return GenerateStuffSatisfyingProperty(input); 
    yield return GenerateStuffNotSatisfyingProperty(input); 
} 

[Fact] 
public void PropertyForCollectionHolds() 
{ 
    Prop.ForAll(Arb.Choose(1,5), input => 
    { 
     var collection = GetStuffCollection(input); 

     return collection.SatisfiesProperty(); 
    }).VerboseCheckThrowOnFailure(); 
} 

aber diese Fest Codes der Bestellung, dh die Stuff in der Sammlung, die die Eigenschaft erfüllt ; Ich würde das gerne auch vermitteln.

Eine Möglichkeit wäre, Prop.ForAll Anrufe zu verschachteln; eine äußere, die etwas erzeugt, die die Reihenfolge bestimmt, und eine innere, der derjenige ist, aber ich oben verläuft, einen Parameter-Bestell zur Sammlung Builder Steuerung:

IEnumerable<Stuff> GetStuffCollection(int input, bool first) 
{ 
    if (first) 
    { 
     yield return GenerateStuffSatisfyingProperty(input); 
     yield return GenerateStuffNotSatisfyingProperty(input); 
    } 
    else 
    { 
     yield return GenerateStuffNotSatisfyingProperty(input); 
     yield return GenerateStuffSatisfyingProperty(input); 
    } 
} 

[Fact] 
public void PropertyForCollectionHolds() 
{ 
    Prop.ForAll(Arb.Default.Bool(), first => 
     Prop.ForAll(Arb.Choose(1,5), input => 
     { 
      var collection = GetStuffCollection(input, first); 

      return collection.SatisfiesProperty(); 
     }).VerboseCheckThrowOnFailure() 
    ).VerboseCheckThrowOnFailure(); 
} 

Aber dies fühlt und klunky gewunden. Gibt es einen einfacheren und/oder mehr idiomatischen Weg, um dasselbe zu erreichen, d. H. Das kartesische Produkt der Ausgabe von zwei Schiedsverfahren zu testen?

Antwort

0

Sie können Gen.Shuffle verwenden Sequenzen in unterschiedlicher Reihenfolge zu generieren:

var gen = from input in Gen.Choose(1, 5) 
      let sc = GetStuffCollection(input) 
      from shuffled in Gen.Shuffle(sc) 
      select shuffled 

dann

Prop.ForAll(gen, collection => { ... }) 
Verwandte Themen