Skip to content

Instantly share code, notes, and snippets.

@nth-commit
Last active March 3, 2021 20:06
Show Gist options
  • Save nth-commit/52007b01ddec00a31b859150bb498c71 to your computer and use it in GitHub Desktop.
Save nth-commit/52007b01ddec00a31b859150bb498c71 to your computer and use it in GitHub Desktop.
A potential API to define properties
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