### Regression Testing with Single Source: https://context7.com/anthonylloyd/cscheck/llms.txt Single searches for a random example satisfying a predicate (multithreaded), throws reporting the seed, then uses the seed to reproduce and verify the same example on subsequent calls. Use this to pin failing examples. ```csharp using System.Linq; using Xunit; using FsCheck; // Assuming ModelGen and Bond/Equity are defined elsewhere // public static class ModelGen { public static Gen Portfolio { get; } = null; public static Gen Price { get; } = null; } // public class Portfolio { public Position[] Positions { get; set; } } // public class Position { public Instrument Instrument { get; set; } } // public abstract class Instrument {} // public class Bond : Instrument {} // public class Equity : Instrument {} // public class Price {} public class SingleTests { // First run: finds and reports seed, e.g. "Example Portfolio seed = \"0N0XIzNsQ0O2\"" // Subsequent runs: reproduces and verifies the pinned example [Fact] public void Portfolio_Regression() { // var portfolio = ModelGen.Portfolio.Single( // p => p.Positions.Count == 5 // && p.Positions.Any(p => p.Instrument is Bond) // && p.Positions.Any(p => p.Instrument is Equity), // "0N0XIzNsQ0O2" // omit this line on first run to discover the seed // ); // Assert.Equal(5, portfolio.Positions.Count); // Pin a second piece of data // var rates = ModelGen.Price.Array[3].Single( // a => a.All(r => r is > 0.5 and < 2.0), // "ftXKwKhS6ec4" // ); // Assert.Equal(3, rates.Length); } } ``` -------------------------------- ### Basic CsCheck Operations Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Demonstrates Count, Set, Get, Info, and Call operations for debugging and testing. ```csharp public void Normal_Code(int z) { Dbg.Count(); var d = Calc1(z).DbgSet("d"); Dbg.Call("helpful"); var c = Calc2(d).DbgInfo("c"); Dbg.CallAdd("test cache", () => { Dbg.Info(Dbg.Get("d")); Dbg.Info(cacheItems); }); } [Test] public void Test() { Dbg.CallAdd("helpful", () => { var d = (double)Dbg.Get("d"); // ... Dbg.Set("d", d); }); Normal_Code(z); Dbg.Call("test cache"); Dbg.Output(writeLine); } ``` -------------------------------- ### Create a Default Generator in C# Source: https://github.com/anthonylloyd/cscheck/blob/master/Why.md Demonstrates creating a default generator for a list of double arrays. This is a starting point for more specific generator configurations. ```csharp Gen.Double.Array.List ``` -------------------------------- ### Causal Profiling Example Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Demonstrates causal profiling by measuring the performance of a specific region of code. Useful for identifying performance bottlenecks in concurrent applications. ```csharp [Test] public void Fasta() { Causal.Profile(() => FastaUtils.Fasta.NotMain(10_000_000, null)).Output(writeLine); } ``` ```csharp static int[] Rnds(int i, int j, ref int seed) { var region = Causal.RegionStart("rnds"); var a = intPool.Rent(BlockSize1); var s = a.AsSpan(0, i); s[0] = j; for (i = 1, j = Width; i < s.Length; i++) { if (j-- == 0) { j = Width; s[i] = IM * 3 / 2; } else { s[i] = seed = (seed * IA + IC) % IM; } } Causal.RegionEnd(region); return a; } ``` -------------------------------- ### Test Async HTTP Response with SampleAsync Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use SampleAsync for testing asynchronous operations. This example fetches data from a cache and throws an exception if the result is null. ```csharp // --- Async form --- [Test] public async Task Http_Response_Sample() { await Gen.String[Gen.Char.AlphaNumeric, 3, 10] .SampleAsync(async key => { var result = await FetchFromCache(key); if (result is null) throw new Exception($"Null result for key: {key}"); }, iter: 50); } ``` -------------------------------- ### Running Tests with Environment Variables and Filters Source: https://context7.com/anthonylloyd/cscheck/llms.txt Example of setting environment variables for CsCheck configuration and using dotnet CLI to run specific tests in Release mode. This demonstrates a practical approach for targeted testing and fuzzing campaigns. ```powershell # Example: run all *_Faster tests in Release mode with higher sigma # $env:CsCheck_Sigma=50 # dotnet run -c Release --project Tests --treenode-filter /*/*/*/*_Faster # rm env:CsCheck* ``` -------------------------------- ### Test Equality Contract for a Record Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use Equality to verify that a type's Equals, GetHashCode, and IEquatable implementations are consistent. This example tests a record type which automatically generates these methods. ```csharp Gen.Select(Gen.Int, Gen.String) .Select((id, name) => new MyRecord(id, name)) .Equality(); ``` ```csharp record MyRecord(int Id, string Name); ``` -------------------------------- ### Test List Reverse Involution with Action Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use the Action form when the predicate should throw an exception on failure. This example tests the involution property of reversing a list twice. ```csharp // --- Action form: throw exception on failure --- [Test] public void List_Reverse_Involution() { Gen.Int.List .Sample(list => { var reversed = list.AsEnumerable().Reverse().Reverse().ToList(); if (!list.SequenceEqual(reversed)) throw new Exception($"Reverse-reverse not equal: {string.Join(",", list)}"); }); } ``` -------------------------------- ### F# Version Generation and Property Test Source: https://github.com/anthonylloyd/cscheck/blob/master/Comparison.md Defines a F# generator for a Version type and a property that checks if Major, Minor, and Build are not all equal. This example demonstrates a scenario where traditional path-exploring shrinkers might struggle. ```fsharp let version = Range.constantBounded () |> Gen.byte |> Gen.map int |> Gen.tuple3 |> Gen.map (fun (ma, mi, bu) -> Version (ma, mi, bu)) Property.print <| property { let! v = version return not(v.Major = v.Minor && v.Minor = v.Build) } ``` -------------------------------- ### Regression Test for Portfolio Calculation Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Performs regression testing on portfolio calculations using single value and hash checks. 'Single' finds specific examples, while 'Hash' checks a number of results for consistency. ```csharp [Test] public void Portfolio_Small_Mixed_Example() { var portfolio = ModelGen.Portfolio.Single(p => p.Positions.Count == 5 && p.Positions.Any(p => p.Instrument is Bond) && p.Positions.Any(p => p.Instrument is Equity) , "0N0XIzNsQ0O2"); var currencies = portfolio.Positions.Select(p => p.Instrument.Currency).Distinct().ToArray(); var fxRates = ModelGen.Price.Array[currencies.Length].Single(a => a.All(p => pp is > 0.75 and < 1.5) , "ftXKwKhS6ec4"); double fxRate(Currency c) => fxRates[Array.IndexOf(currencies, c)]; Check.Hash(h => { h.Add(portfolio.Positions.Select(p => p.Profit)); h.Add(portfolio.Profit(fxRate)); h.Add(portfolio.RiskByPosition(fxRate)); }, 5857230471108592669, decimalPlaces: 2); } ``` -------------------------------- ### Test Int Range Bounds with Func Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use the Func form when the predicate should return false on failure. This example verifies that a generated integer falls within a dynamically determined range. ```csharp // --- Func form: return false on failure --- [Test] public void Int_Range_Bounds() { (from t in Gen.Select(Gen.Int, Gen.Int) let lo = Math.Min(t.V0, t.V1) let hi = Math.Max(t.V0, t.V1) from v in Gen.Int[lo, hi] select (v, lo, hi)) .Sample(x => x.lo <= x.v && x.v <= x.hi); } ``` -------------------------------- ### Debug Utilities: Time Workflow Phases Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use Dbg.Time to measure the duration of workflow phases. The `using var time = Dbg.Time();` pattern automatically starts timing, and `time.Line()` logs cumulative time at checkpoints. ```csharp public void SlowWorkflow() { using var time = Dbg.Time(); DoPhase1(); time.Line(); // checkpoint: logs cumulative time here DoPhase2(); time.Line(); DoPhase3(); } ``` ```csharp SlowWorkflow(); Dbg.Output(Console.WriteLine); ``` -------------------------------- ### Test String Concatenation Length with Multi-Generator Tuple Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use Gen.Select to combine multiple generators into a tuple for testing. This example verifies that the length of concatenated strings equals the sum of their individual lengths. ```csharp // --- Multi-generator tuple form --- [Test] public void String_Concat_Length() { Gen.Select(Gen.String, Gen.String) .Sample((a, b) => (a + b).Length == a.Length + b.Length); } ``` -------------------------------- ### Perform Unit Random Test in C# Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Uses CsCheck's Gen.Single.Unit.Sample to test a condition against generated single unit values. Failures are aggressively shrunk to the simplest example. The default sample size is 100 iterations. ```csharp [Test] public void Single_Unit_Range() { Gen.Single.Unit.Sample(f => f is >= 0f and <= 0.9999999f); } ``` -------------------------------- ### Create JSON Document Generator in C# Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Composes generators for JSON documents using CsCheck's Gen class and Linq methods. Shrinking is handled automatically. This example defines generators for strings, primitive JSON values, and recursively for JSON objects and arrays. ```csharp static readonly Gen genString = Gen.String[Gen.Char.AlphaNumeric, 2, 5]; static readonly Gen genJsonValue = Gen.OneOf( Gen.Bool.Select(x => JsonValue.Create(x)), Gen.Byte.Select(x => JsonValue.Create(x)), Gen.Char.AlphaNumeric.Select(x => JsonValue.Create(x)), Gen.DateTime.Select(x => JsonValue.Create(x)), Gen.DateTimeOffset.Select(x => JsonValue.Create(x)), Gen.Decimal.Select(x => JsonValue.Create(x)), Gen.Double.Select(x => JsonValue.Create(x)), Gen.Float.Select(x => JsonValue.Create(x)), Gen.Guid.Select(x => JsonValue.Create(x)), Gen.Int.Select(x => JsonValue.Create(x)), Gen.Long.Select(x => JsonValue.Create(x)), Gen.SByte.Select(x => JsonValue.Create(x)), Gen.Short.Select(x => JsonValue.Create(x)), genString.Select(x => JsonValue.Create(x)), Gen.UInt.Select(x => JsonValue.Create(x)), Gen.ULong.Select(x => JsonValue.Create(x)), Gen.UShort.Select(x => JsonValue.Create(x))); static readonly Gen genJsonNode = Gen.Recursive((depth, genJsonNode) => { if (depth == 5) return genJsonValue; var genJsonObject = Gen.Dictionary(genString, genJsonNode.Null())[0, 5].Select(d => new JsonObject(d)); var genJsonArray = genJsonNode.Null().Array[0, 5].Select(i => new JsonArray(i)); return Gen.OneOf(genJsonObject, genJsonArray, genJsonValue); }); ``` -------------------------------- ### Configure Gen.Sample Options Source: https://context7.com/anthonylloyd/cscheck/llms.txt Illustrates various configuration options for Gen.Sample, including pinning a seed, setting iteration count, time limits, parallelism, and custom failure messages. ```csharp // Configuration options available on every Sample call: Gen.Int.Sample( i => i >= 0, seed: "0N0XIzNsQ0O2", // pin to a specific seed for reproducibility iter: 10_000, // number of iterations (default 100) time: 5, // OR run for N seconds threads: 4, // parallelism (default: CPU count) print: i => $"value={i}" // custom failure message ); ``` -------------------------------- ### Per-Call Configuration for Gen.Int.Sample Source: https://context7.com/anthonylloyd/cscheck/llms.txt Configure individual test runs with specific parameters like iterations, time limits, seeds, parallelism, custom serializers, and standard deviation for Faster tests. Defaults are used if not specified. ```csharp // Per-call configuration Gen.Int.Sample( i => i > 0, iter: 10_000, // iterations (default: 100) time: 30, // OR seconds to run seed: "0N0XIzNsQ0O2",// pin first iteration seed threads: 2, // parallelism print: i => $"{i}", // custom failure serializer sigma: 10.0 // std deviations for Faster (default 6) ); ``` -------------------------------- ### Setting CsCheck Configuration via Environment Variables Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Demonstrates how to configure CsCheck parameters like iterations, seed, and threads using environment variables in PowerShell. ```powershell $env:CsCheck_Iter=10000;dotnet run -c Release --project Tests --no-restore --disable-logo --output Detailed --treenode-filter /*/*/GenTests/*;rm env:CsCheck* $env:CsCheck_Time=10;dotnet run -c Release --project Tests --no-restore --disable-logo --output Detailed --treenode-filter /*/*/FloatingPointTests/*;rm env:CsCheck* $env:CsCheck_Seed="0N0XIzNsQ0O2";dotnet run -c Release --project Tests --no-restore --disable-logo --output Detailed --treenode-filter /*/*/*/NSum_Shuffle_Check;rm env:CsCheck* $env:CsCheck_Sigma=50;dotnet run -c Release --project Tests --no-restore --disable-logo --output Detailed --treenode-filter /*/*/*/*_Faster;rm env:CsCheck* $env:CsCheck_Threads=1;dotnet run -c Release --project Tests --no-restore --disable-logo --output Detailed --treenode-filter /*/*/*/*_Perf;rm env:CsCheck* ``` -------------------------------- ### Test Serialization Roundtrip for Int and Double Source: https://context7.com/anthonylloyd/cscheck/llms.txt Demonstrates a generic pattern for testing serialization and deserialization roundtrips. Requires custom serialize and deserialize functions. ```csharp // --- Serialization roundtrip pattern --- static void TestRoundtrip(Gen gen, Action serialize, Func deserialize) where T : IEquatable { gen.Sample(t => { using var ms = new MemoryStream(); serialize(ms, t); ms.Position = 0; return deserialize(ms).Equals(t); }); } [Test] public void Roundtrip_Int() => TestRoundtrip(Gen.Int, WriteInt32, ReadInt32); [Test] public void Roundtrip_Double() => TestRoundtrip(Gen.Double, WriteDouble, ReadDouble); ``` -------------------------------- ### Profile Causal Regions in Production Code Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use Causal.Profile to identify performance bottlenecks by artificially speeding up regions of code. Mark concurrent regions in production code using Causal.RegionStart and Causal.RegionEnd. ```csharp static void ProcessItems(int[] items) { var region1 = Causal.RegionStart("parse"); var parsed = ParseAll(items); Causal.RegionEnd(region1); var region2 = Causal.RegionStart("compute"); var result = ComputeAll(parsed); Causal.RegionEnd(region2); } ``` ```csharp Causal.Profile(() => ProcessItems(data)) .Output(Console.WriteLine); ``` -------------------------------- ### Model-Based Test for SetSlim Add Operation Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Demonstrates model-based testing for a SetSlim collection. It compares the behavior of SetSlim.Add with the standard HashSet.Add operation by applying random operations to both and checking for consistency. ```csharp using cscheck; using System; using System.Collections.Generic; public class Tests { [Test] public void SetSlim_ModelBased() { Gen.Int.Array.Select(a => (new SetSlim(a), new HashSet(a))) .SampleModelBased( Gen.Int.Operation, HashSet>( (ss, i) => ss.Add(i), (hs, i) => hs.Add(i) ) // ... other operations ); } // Assume SetSlim and Gen are defined elsewhere } ``` -------------------------------- ### Primitive Generators in CsCheck Source: https://context7.com/anthonylloyd/cscheck/llms.txt Demonstrates the creation of basic generators for primitive types and collections. Supports range indexers and LINQ methods. ```csharp // Primitive generators — all support range indexers Gen genBool = Gen.Bool; Gen genInt = Gen.Int[1, 100]; // int in [1, 100] Gen genDouble = Gen.Double.Unit; // double in [0.0, 1.0) Gen genStr = Gen.String[Gen.Char.AlphaNumeric, 2, 10]; // alphanumeric, len 2–10 Gen genGuid = Gen.Guid; Gen genDt = Gen.DateTime; ``` ```csharp // Collection generators via properties on Gen Gen arr = Gen.Int[0, 99].Array[10, 50]; // array of 10–50 ints Gen arr2d = Gen.Int.Array2D; // 2D array Gen> list = Gen.Int.List[5]; // list of exactly 5 Gen> hs = Gen.Int.HashSet; Gen unique = Gen.Int.ArrayUnique; // unique elements ``` -------------------------------- ### CsCheck Regression Testing Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Illustrates how to use CsCheck for regression testing by adding and checking data. ```csharp public double[] Calculation(InputData input) { var part1 = CalcPart1(input); // Add items to the regression on first pass, throw/break here if different on subsequent. Dbg.Regression.Add(part1); var part2 = CalcPart2(part1).DbgTee(Dbg.Regression.Add); // Tee can be used to do this inline. // ... return CalcFinal(partN).DbgTee(Dbg.Regression.Add); } [Test] public void Test() { // Remove any previously saved regression data. Dbg.Regression.Delete(); Calculation(InputSource1()); // End first pass save mode (only needed if second pass is in this process run). Dbg.Regression.Close(); // Subsequent pass could be now or a code change and rerun (without the Delete). Calculation(InputSource2()); // Check full number of items have been reconciled (optional). Dbg.Regression.Close(); } ``` -------------------------------- ### Create a Specific Generator in C# Source: https://github.com/anthonylloyd/cscheck/blob/master/Why.md Shows how to create a more specific generator for a list of double arrays, defining ranges for values, array size, and list size. This allows for fine-grained control over generated data. ```csharp Gen.Double[0.0, 100.0].Array[5].List[1, 10] ``` -------------------------------- ### Composing Generators with LINQ in CsCheck Source: https://context7.com/anthonylloyd/cscheck/llms.txt Shows how to combine generators using LINQ's Select and SelectMany for more complex data structures. ```csharp // Composing generators with Select / LINQ query syntax Gen hexStr = Gen.Byte.Array[1, 16] .Select(bytes => Convert.ToHexString(bytes)); ``` ```csharp // Compose multiple generators Gen<(int, string)> pair = Gen.Select(Gen.Int[1, 1000], Gen.String); ``` ```csharp // Monadic composition with SelectMany / LINQ query syntax Gen rangedArray = from len in Gen.Int[1, 20] from arr in Gen.Int[0, 100].Array[len] select arr; ``` -------------------------------- ### Debug Utilities: Count, Set, Info, Call Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use Dbg.Count, Dbg.Set, Dbg.Info, and Dbg.Call for debugging in production code. Dbg.Count tracks execution frequency, Dbg.Set stores values for test access, Dbg.Info logs values, and Dbg.Call triggers test-registered actions. ```csharp public double[] ProcessData(InputData input) { Dbg.Count(); // count how often this runs var part1 = CalcPart1(input).DbgSet("part1"); // store for test access Dbg.Call("validate"); // call a function registered by the test var part2 = CalcPart2(part1).DbgInfo("part2"); // log the value return part2; } ``` ```csharp Dbg.CallAdd("validate", () => { var p = (double[])Dbg.Get("part1")!; Dbg.Info(p.Sum(), "part1 sum"); }); ProcessData(new InputData { /* ... */ }); Dbg.Output(Console.WriteLine); ``` -------------------------------- ### Generate Int Distribution with Func Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use the Func form to classify generated values for distribution analysis. The 'writeLine' parameter is mandatory for this form. The 'iter' parameter controls the number of iterations. ```csharp // --- Func classify form: produces distribution table --- [Test] public void Int_Distribution_Classify() { Gen.Int[0, 9] .Sample( i => i < 5 ? "low" : "high", writeLine: Console.WriteLine, // mandatory for classify iter: 1_000); } // Output (example): // | | Count | % | // |------|------:|-------:| // | low | 498 | 49.80% | // | high | 502 | 50.20% | ``` -------------------------------- ### Model-Based Testing for PriorityQueue with Custom Equivalence Source: https://context7.com/anthonylloyd/cscheck/llms.txt Demonstrates model-based testing for a PriorityQueue using a SortedSet as the model. It uses custom operations and implicitly relies on the default equality comparison. ```csharp // Using equal: parameter for custom equivalence [Test] public void PriorityQueue_ModelBased() { Gen.Int.Array .Select(a => (new PriorityQueue(a.Select(x => (x, x))), new SortedSet(a))) .SampleModelBased( Gen.Int.Operation, SortedSet>( i => $"Enqueue({i})", (pq, i) => pq.Enqueue(i, i), (ss, i) => ss.Add(i) ) ); } ``` -------------------------------- ### C# Version Shrinking Test Source: https://github.com/anthonylloyd/cscheck/blob/master/Comparison.md A C# test case using CsCheck to sample Version objects and assert that Major, Minor, and Build are not all equal. The output shows the failure details, including the seed and the number of skipped tests, illustrating CsCheck's shrinking process. ```csharp [Test] public void Version_Same() { Gen.Select(Gen.Byte, Gen.Byte, Gen.Byte) .Select(t => new Version(t.V0, t.V1, t.V2)) .Sample(v => { if(v.Major == v.Minor && v.Minor == v.Build) { writeLine("Fail: " + v.ToString()); return false; } return true; }, size: 100_000_000); } ``` -------------------------------- ### Metamorphic Testing with SampleMetamorphic Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use SampleMetamorphic to generate two identical initial states and apply different operation sequences, asserting that the end results are equal. This is useful when a simple model does not exist. ```csharp using System.Collections.Generic; using Xunit; using FsCheck; using FsCheck.Fluent; public class SampleMetamorphicTests { [Fact] public void Dictionary_Metamorphic_Insert_Order() { // Verify that inserting two distinct keys in either order produces same dict Gen.Dictionary(Gen.Int, Gen.String) .Select(d => new Dictionary(d)) .SampleMetamorphic( Gen.Select(Gen.Int[0, 100], Gen.String, Gen.Int[0, 100], Gen.String) .Metamorphic>( // Apply: k1=v1, k2=v2 (dict, t) => { dict[t.V0] = t.V1; dict[t.V2] = t.V3; }, // Equivalent: if keys differ, apply in reverse order (dict, t) => { if (t.V0 == t.V2) dict[t.V2] = t.V3; else { dict[t.V2] = t.V3; dict[t.V0] = t.V1; } } ) ); } } ``` -------------------------------- ### Verify Random Distribution with ChiSquared Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use Check.ChiSquared to verify if a random distribution is correct. This is useful for testing random number generators or data sampling. ```csharp int buckets = 10, frequency = 50; int[] expected = Enumerable.Repeat(frequency, buckets).ToArray(); Gen.Int[0, buckets - 1] .Array[frequency * buckets] .Select(sample => { var counts = new int[buckets]; foreach (var i in sample) counts[i]++; return counts; }) .Sample(actual => Check.ChiSquared(expected, actual)); ``` -------------------------------- ### Parallel Testing with SampleParallel Source: https://context7.com/anthonylloyd/cscheck/llms.txt SampleParallel runs operations in parallel against a shared initial state and verifies the result matches at least one valid linearization. It fully supports shrinking of failing interleavings. ```csharp using System.Collections.Concurrent; using System.Collections.Generic; using Xunit; using FsCheck; using FsCheck.Fluent; public class SampleParallelTests { // Test a concurrent collection for race conditions [Fact] public void ConcurrentBag_Parallel() { Gen.Const(() => new ConcurrentBag()) .SampleParallel( Gen.Int.Operation>( i => $"Add({i})", (bag, i) => bag.Add(i)), Gen.Operation>( "TryTake()", (bag, _) => bag.TryTake(out _)) ); } // Test against a non-thread-safe model [Test] public void ConcurrentQueue_Parallel_WithModel() { Gen.Const(() => (new ConcurrentQueue(), new Queue())) .SampleParallel( Gen.Int.Operation, Queue>( i => $"Enqueue({i})", (cq, i) => cq.Enqueue(i), (q, i) => q.Enqueue(i)), Gen.Operation, Queue>( "TryDequeue()", (cq, _) => cq.TryDequeue(out _), (q, _) => { if (q.Count > 0) q.Dequeue(); }) ); } } ``` -------------------------------- ### Faster Linq Random Performance Test Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Compares the performance of two LINQ methods for aggregating byte array data. The output shows the percentage and times faster improvement, sigma, and minimum times. ```csharp [Test] public void Faster_Linq_Random() { Gen.Byte.Array[100, 1000] .Faster( data => data.Aggregate(0.0, (t, b) => t + b), data => data.Select(i => (double)i).Sum(), writeLine: TUnitX.WriteLine ); } ``` -------------------------------- ### Model-Based Testing for Stack Operations Source: https://context7.com/anthonylloyd/cscheck/llms.txt Implements model-based testing for a Stack using Gen.SampleModelBased. It compares the actual Stack with a model List through Push and Pop operations. ```csharp [Test] public void Stack_ModelBased() { // Initial state: actual = Stack, model = List Gen.Int.Array .Select(a => (new Stack(a), new List(a))) .SampleModelBased( // Push operation Gen.Int.Operation, List>( i => $"Push({i})", (stack, i) => stack.Push(i), (list, i) => list.Add(i) ), // Pop operation Gen.Operation, List>( "Pop()", (stack, _) => { if (stack.Count > 0) stack.Pop(); }, (list, _) => { if (list.Count > 0) list.RemoveAt(list.Count - 1); } ) ); } ``` -------------------------------- ### CsCheck Timing Operations Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Shows how to use CsCheck's `Time` feature to measure code execution duration. ```csharp public Result CalcPart2(InputData input) { using var time = Dbg.Time(); // Calc time.Line(); // Calc more time.Line(); // ... return result; } public void LongProcess() { using var time = Dbg.Time(); var part1 = CalcPart1(input); time.Line(); var part2 = new List(); foreach(var item in part1) part2.Add(CalcPart2(item)); time.Line(); // ... return CalcFinal(partN); } [Test] public void Test() { LongProcess(); Dbg.Output(writeLine); } ``` -------------------------------- ### Classify AllocatorMany Results Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Classifies the results of the AllocatorMany algorithm based on its output. This snippet demonstrates how to use the Sample method with a custom classification output and writeLine action to generate a summary table. ```csharp using cscheck; using System; using System.Linq; using System.IO; public class Tests { [Test] public void AllocatorMany_Classify() { Gen.Select(Gen.Int[3, 30], Gen.Int[3, 15]).SelectMany((rows, cols) => Gen.Select( Gen.Int[0, 5].Array[cols].Where(a => a.Sum() > 0).Array[rows], Gen.Int[900, 1000].Array[rows], Gen.Int.Uniform)) .Sample((solution, rowPrice, seed) => { var rowTotal = Array.ConvertAll(solution, row => row.Sum()); var colTotal = Enumerable.Range(0, solution[0].Length).Select(col => solution.SumCol(col)).ToArray(); var allocation = AllocatorMany.Allocate(rowPrice, rowTotal, colTotal, new(seed), time: 60); if (!TotalsCorrectly(rowTotal, colTotal, allocation.Solution)) throw new Exception("Does not total correctly"); return $"{(allocation.KnownGlobal ? "Global" : "Local")}/{allocation.SolutionType}"; }, TUnitX.WriteLine, time: 900); } // Assume AllocatorMany, TotalsCorrectly, SumCol, TUnitX are defined elsewhere } ``` -------------------------------- ### Filtering Generators with Where in CsCheck Source: https://context7.com/anthonylloyd/cscheck/llms.txt Illustrates filtering generated values using the Where clause. Use sparingly as overly restrictive filters can impact performance. ```csharp // Filter with Where (use sparingly — may throw if too restrictive) Gen evenInt = Gen.Int[0, 50].Where(n => n % 2 == 0); ``` -------------------------------- ### Global Defaults via Environment Variables (PowerShell) Source: https://context7.com/anthonylloyd/cscheck/llms.txt Set global default parameters for CsCheck tests using environment variables in PowerShell. This is useful for CI/release-mode runs to avoid code changes. Remember to unset them after use if necessary. ```powershell # Global defaults via environment variables (PowerShell) # $env:CsCheck_Iter=10000 # $env:CsCheck_Time=10 # $env:CsCheck_Seed="0N0XIzNsQ0O2" # $env:CsCheck_Sigma=50 # $env:CsCheck_Threads=1 # $env:CsCheck_Timeout=120 ``` -------------------------------- ### Debug Utilities: In-Code Regression Snapshots Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use Dbg.Regression for in-code regression testing. Add values with `Dbg.Regression.Add()`, save/compare on each call, and use `Dbg.Regression.Delete()` to clear state and `Dbg.Regression.Close()` to end save/verify modes. ```csharp public double[] Calculation(InputData input) { var part1 = CalcPart1(input); Dbg.Regression.Add(part1); // save/compare on each call var part2 = CalcPart2(part1).DbgTee(Dbg.Regression.Add); return CalcFinal(part2).DbgTee(Dbg.Regression.Add); } ``` ```csharp Dbg.Regression.Delete(); // clear saved state Calculation(InputSource1()); // first pass: saves Dbg.Regression.Close(); // end save mode Calculation(InputSource2()); // second pass: compares (throws at first diff) Dbg.Regression.Close(); // verify all items were reconciled ``` -------------------------------- ### Test Serialization Roundtrip for Various Types Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Tests the serialization and deserialization process for different data types (Varint, Double, DateTime). Ensures that data can be written to and read from a stream without loss of information. ```csharp using cscheck; using System; using System.IO; public class Tests { static void TestRoundtrip(Gen gen, Action serialize, Func deserialize) { gen.Sample(t => { using var ms = new MemoryStream(); serialize(ms, t); ms.Position = 0; return deserialize(ms).Equals(t); }); } [Test] public void Varint() { TestRoundtrip(Gen.UInt, StreamSerializer.WriteVarint, StreamSerializer.ReadVarint); } [Test] public void Double() { TestRoundtrip(Gen.Double, StreamSerializer.WriteDouble, StreamSerializer.ReadDouble); } [Test] public void DateTime() { TestRoundtrip(Gen.DateTime, StreamSerializer.WriteDateTime, StreamSerializer.ReadDateTime); } // Assume StreamSerializer and Gen are defined elsewhere } ``` -------------------------------- ### Metamorphic Test for MapSlim Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Compares two identical initial samples by applying two functions and asserting equal results. Useful when a model is a reimplementation. ```csharp [Test] public void MapSlim_Metamorphic() { Gen.Dictionary(Gen.Int, Gen.Byte) .Select(d => new MapSlim(d)) .SampleMetamorphic( Gen.Select(Gen.Int[0, 100], Gen.Byte, Gen.Int[0, 100], Gen.Byte).Metamorphic>( (d, t) => { d[t.V0] = t.V1; d[t.V2] = t.V3; }, (d, t) => { if (t.V0 == t.V2) d[t.V2] = t.V3; else { d[t.V2] = t.V3; d[t.V0] = t.V1; } } ) ); } ``` -------------------------------- ### Performance Testing with Faster Source: https://context7.com/anthonylloyd/cscheck/llms.txt Faster statistically determines if one implementation is faster than another by running both in parallel and applying a binomial test. It outputs improvement percentage, multiplier, sigma, and timing. ```csharp using System; using System.Linq; using System.Text; using Xunit; using FsCheck; using FsCheck.Fluent; public class FasterTests { // Compare two implementations with random inputs [Fact] public void Sort_Faster() { Gen.Int.Array[10, 1000] .Faster( arr => { var a = (int[])arr.Clone(); Array.Sort(a); }, arr => { var a = (int[])arr.Clone(); a = a.OrderBy(x => x).ToArray(); }, writeLine: Console.WriteLine ); } // Output: 45.23%[38.10%..52.15%] 1.82x[1.61x..2.09x] faster, sigma=50.0 (3821 vs 312), min=123ns vs 224ns // Without generator — fixed inputs [Fact] public void StringConcat_Faster() { Check.Faster( () => { var sb = new StringBuilder(); for (int i = 0; i < 100; i++) sb.Append(i); _ = sb.ToString(); }, () => { var s = ""; for (int i = 0; i < 100; i++) s += i; }, sigma: 10, repeat: 50, writeLine: Console.WriteLine ); } // Verify results are equal AND measure performance [Fact] public void MatrixMultiply_Faster() { var genDim = Gen.Int[5, 30]; Gen.SelectMany(genDim, genDim, genDim, (i, j, k) => Gen.Select(Gen.Double.Unit.Array2D[i, j], Gen.Double.Unit.Array2D[j, k])) .Faster( (a, b) => MultiplyIKJ(a, b), (a, b) => MultiplyIJK(a, b) ); } // Dummy methods for MatrixMultiply_Faster example private double[,] MultiplyIKJ(double[,] a, double[,] b) { return new double[1,1]; } private double[,] MultiplyIJK(double[,] a, double[,] b) { return new double[1,1]; } } ``` -------------------------------- ### Varint Encoding/Decoding Performance Test Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Compares the performance of ArraySerializer's Write/ReadVarint against Write/ReadPrefixVarint. The test is repeated 200 times due to the speed of the operations. ```csharp [Test] public void Varint_Faster() { Gen.Select(Gen.UInt, Gen.Const(() => new byte[8])) .Faster( (i, bytes) => { int pos = 0; ArraySerializer.WriteVarint(bytes, ref pos, i); pos = 0; return ArraySerializer.ReadVarint(bytes, ref pos); }, (i, bytes) => { int pos = 0; ArraySerializer.WritePrefixVarint(bytes, ref pos, i); pos = 0; return ArraySerializer.ReadPrefixVarint(bytes, ref pos); }, sigma: 10, repeat: 200, writeLine: TUnitX.WriteLine); } ``` -------------------------------- ### Faster Matrix Multiply Performance Test Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Tests the performance difference between two matrix multiplication algorithms (MulIKJ and MulIJK) using randomly generated dimensions and arrays. ```csharp [Test] public void Faster_Matrix_Multiply_Range() { var genDim = Gen.Int[5, 30]; var genArray = Gen.Double.Unit.Array2D; Gen.SelectMany(genDim, genDim, genDim, (i, j, k) => Gen.Select(genArray[i, j], genArray[j, k])) .Faster( MulIKJ, MulIJK ); } ``` -------------------------------- ### Test Int Distribution with Chi-Squared Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Tests the distribution of generated integers across a specified number of buckets. Uses the Chi-Squared test to compare expected and actual frequencies. ```csharp using cscheck; using System; using System.Linq; public class Tests { [Test] public void Int_Distribution() { int buckets = 70; int frequency = 10; int[] expected = Enumerable.Repeat(frequency, buckets).ToArray(); Gen.Int[0, buckets - 1].Array[frequency * buckets] .Select(sample => Tally(buckets, sample)) .Sample(actual => Check.ChiSquared(expected, actual)); } // Assume Tally and Check.ChiSquared are defined elsewhere private static int[] Tally(int buckets, int[] sample) { return null; } // Placeholder } ``` -------------------------------- ### MapSlim Increment Performance Test Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Compares the performance of incrementing values in a MapSlim against a standard Dictionary. The test is repeated 100 times to ensure accuracy for quick operations. ```csharp [Test] public void MapSlim_Performance_Increment() { Gen.Byte.Array .Select(a => (a, new MapSlim(), new Dictionary())) .Faster( (items, mapslim, _) => { foreach (var b in items) mapslim.GetValueOrNullRef(b)++; }, (items, _, dict) => { foreach (var b in items) { dict.TryGetValue(b, out int c); dict[b] = c + 1; } }, repeat: 100, writeLine: TUnitX.WriteLine); } ``` -------------------------------- ### Reverse Complement Performance Test Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Tests the performance of two implementations (New and Old) for the Reverse Complement operation on FASTA formatted data. It ensures the FASTA file exists before running. ```csharp [Test] public void ReverseComplement_Faster() { if (!File.Exists(Utils.Fasta.Filename)) Utils.Fasta.NotMain(new[] { "25000000" }); Check.Faster( ReverseComplementNew.RevComp.NotMain, ReverseComplementOld.RevComp.NotMain, threads: 1, timeout: 600_000, sigma: 6 writeLine: TUnitX.WriteLine); } ``` -------------------------------- ### Setting Global Defaults in Code Source: https://context7.com/anthonylloyd/cscheck/llms.txt Configure global default settings for CsCheck directly within your C# code. This approach is suitable for setting consistent defaults across your project without relying on environment variables. ```csharp // Set global defaults in code Check.Iter = 1_000; Check.Sigma = 10.0; Check.Timeout = 120; ``` -------------------------------- ### Compute and Pin Regression Hash Source: https://context7.com/anthonylloyd/cscheck/llms.txt Use Check.Hash to compute a hash of values for regression testing. On the first run, discover the hash value. On subsequent runs, it verifies the hash matches, reporting differences if any. ```csharp Check.Hash(h => { var result = MyCalculation.Run(input); h.Add(result.NetValue); // double h.Add(result.Positions.Select(p => p.Risk)); // IEnumerable h.Add(result.Summary); // string }, expected: 5857230471108592669, // set to 0 on first run to discover hash decimalPlaces: 4); ``` -------------------------------- ### Test Shrinking Challenge for Large Union List Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Tests a complex scenario involving nested arrays of integers, aiming to ensure that the shrinking mechanism correctly identifies minimal test cases. It checks if the total number of unique integers across all nested lists reaches a threshold. ```csharp using cscheck; using System; using System.Collections.Generic; public class Tests { [Test] public void No2_LargeUnionList() { Gen.Int.Array.Array .Sample(aa => { var hs = new HashSet(); foreach (var a in aa) { foreach (var i in a) hs.Add(i); if (hs.Count >= 5) return false; } return true; }); } } ``` -------------------------------- ### Parallel Test with Model for ConcurrentQueue Source: https://github.com/anthonylloyd/cscheck/blob/master/README.md Tests ConcurrentQueue operations in parallel against a model. This allows testing thread-safe collections against a non-thread-safe model. ```csharp [Test] public void SampleParallelModel_ConcurrentQueue() { Gen.Const(() => (new ConcurrentQueue(), new Queue())) .SampleParallel( Gen.Int.Operation, Queue>(i => $"Enqueue({i})", (q, i) => q.Enqueue(i), (q, i) => q.Enqueue(i)), Gen.Operation, Queue>("TryDequeue()", q => q.TryDequeue(out _), q => q.TryDequeue(out _)) ); } ``` -------------------------------- ### Advanced Generator Types in CsCheck Source: https://context7.com/anthonylloyd/cscheck/llms.txt Covers specialized generators including enums, mixed types, weighted selection, recursive structures, nullable types, dictionaries, and constant values. ```csharp // Enum generator Gen genDay = Gen.Enum(); ``` ```csharp // OneOf — pick randomly among generators Gen genMixed = Gen.OneOf( Gen.Int.Select(x => (object)x), Gen.String.Select(x => (object)x)); ``` ```csharp // Frequency — weighted selection Gen genWeighted = Gen.FrequencyConst( (3, "common"), (1, "rare")); ``` ```csharp // Recursive generator for tree-like data record Tree(int Value, Tree[] Children); Gen genTree = Gen.Recursive((depth, self) => Gen.Select( Gen.Int, self.Array[0, depth < 4 ? 3 : 0], (v, c) => new Tree(v, c))); ``` ```csharp // Nullable / null variants Gen genNullableInt = Gen.Int.Nullable(nullFraction: 0.1); Gen genNullStr = Gen.String.Null(nullFraction: 0.2); ``` ```csharp // Dictionary generator Gen> genDict = Gen.Dictionary(Gen.String[Gen.Char.Alpha, 1, 8], Gen.Int[0, 100]); ``` ```csharp // Const — always returns the same value / fresh instance Gen> genFresh = Gen.Const(() => new List()); ``` ```csharp // Clone — generate two independent copies of the same value Gen<(int, int)> genClone = Gen.Int.Clone(); ```