Last active
March 3, 2021 20:06
-
-
Save nth-commit/52007b01ddec00a31b859150bb498c71 to your computer and use it in GitHub Desktop.
A potential API to define properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Test | |
{ | |
// The generator will give random, disassociated values, and those values will be chucked away if they don't abide by the precise | |
// constraints. This filter is particularly inefficient, with a discard rate of about 8 : 1. Can all be done without actually | |
// needing to return a Property, which is the benefit of this API. | |
[Property] | |
public void APropertyThatNeedsValuesToBeCoupledToEachOther_Preconditions( | |
int min, | |
int max, | |
int origin) | |
{ | |
Property.Precondition(origin >= min); | |
Property.Precondition(max >= origin); | |
// All the values are now in scope and abide by the constrains, write the test function below | |
} | |
// The right information is fed to the generators at the right times, so that the generators can always give values that abide by the | |
// constraints and nothing is discarded. | |
// | |
// However, this API is a lot more verbose, and there's a particularly annoying step of having to wrap everything up in a tuple, then | |
// unwrap the tuple almost immediately following. You also need to return a Property, so it can be evaluated. | |
// | |
// Far more efficient than the example above, and the efficiency will scale if we add more parameters with more distinct | |
// preconditions. | |
[Property] | |
public Property APropertyThatNeedsValuesToBeCoupledToEachOther_CurrentBestSyntax() | |
{ | |
var gen = | |
from min in Gen.Int32() | |
from max in Gen.Int32().GreaterThanEqual(min) | |
from origin in Gen.Int32().Between(min, max) | |
select (min, max, origin); | |
return gen.ForAll((input) => | |
{ | |
var (min, max, origin) = input; | |
// All the values are now in scope and abide by the constrains, write the test function below | |
}); | |
} | |
// Mechanically similar to the previous example - but the property function is defined within LINQ. | |
[Property] | |
public Property APropertyThatNeedsValuesToBeCoupledToEachOther_PossibleFutureSyntax() => | |
from min in Gen.Int32() | |
from max in Gen.Int32().GreaterThanEqual(min) | |
from origin in Gen.Int32().Between(min, max) | |
select Property.ForThese(() => | |
{ | |
// All the values are now in scope and abide by the constrains, write the test function below | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment