diff --git a/TUnit.Example.FsCheck.TestProject/PropertyTests.cs b/TUnit.Example.FsCheck.TestProject/PropertyTests.cs index 27193b2b26..a406b42b36 100644 --- a/TUnit.Example.FsCheck.TestProject/PropertyTests.cs +++ b/TUnit.Example.FsCheck.TestProject/PropertyTests.cs @@ -4,6 +4,19 @@ namespace TUnit.Example.FsCheck.TestProject; +/// +/// Custom arbitrary that generates positive integers only. +/// +public class PositiveIntArbitrary +{ + public static Arbitrary PositiveInt() + { + return ArbMap.Default.GeneratorFor() + .Where(x => x > 0) + .ToArbitrary(); + } +} + public class PropertyTests { [Test, FsCheckProperty] @@ -88,4 +101,9 @@ public Property StringReversalProperty() }); } + [Test, FsCheckProperty(Arbitrary = new[] { typeof(PositiveIntArbitrary) })] + public bool PositiveNumbersArePositive(int value) + { + return value > 0; + } } diff --git a/docs/docs/examples/fscheck.md b/docs/docs/examples/fscheck.md index 5f31dda131..00246fcd3c 100644 --- a/docs/docs/examples/fscheck.md +++ b/docs/docs/examples/fscheck.md @@ -122,14 +122,21 @@ public bool MyProperty(int value) ## Custom Generators -You can provide custom `Arbitrary` implementations for generating test data: +You can provide custom `Arbitrary` implementations for generating test data. FsCheck 3.x uses `ArbMap.Default` to access default arbitraries: ```csharp +using FsCheck; +using FsCheck.Fluent; + public class PositiveIntArbitrary { public static Arbitrary PositiveInt() { - return Arb.Default.Int32().Filter(x => x > 0); + // Use ArbMap.Default to get a generator for a type, + // then filter with Where() and convert to Arbitrary + return ArbMap.Default.GeneratorFor() + .Where(x => x > 0) + .ToArbitrary(); } } @@ -140,6 +147,44 @@ public bool PositiveNumbersArePositive(int value) } ``` +### Alternative: Using Gen.Choose + +For simple ranges, use `Gen.Choose` directly: + +```csharp +public class PositiveIntArbitrary +{ + public static Arbitrary PositiveInt() + { + // Generate integers in a specific range + return Gen.Choose(1, int.MaxValue).ToArbitrary(); + } +} +``` + +### Custom types + +For custom types, compose generators using LINQ: + +```csharp +public class Person +{ + public string Name { get; set; } + public int Age { get; set; } +} + +public class PersonArbitrary +{ + public static Arbitrary Person() + { + var gen = from name in ArbMap.Default.GeneratorFor() + from age in Gen.Choose(0, 120) + select new Person { Name = name, Age = age }; + return gen.ToArbitrary(); + } +} +``` + ## Limitations - **Native AOT**: TUnit.FsCheck is not compatible with Native AOT publishing because FsCheck requires reflection and dynamic code generation