CsCheck/Check.cs
/// <summary>Sample model-based operations on a random initial state checking that actual and model are equal.
/// If not the failing initial state and sequence will be shrunk down to the shortest and simplest.</summary>
/// <param name="initial">The initial state generator.</param>
/// <param name="operations">The operation generators that can act on the state.</param>
/// <param name="equal">A function to check if the actual and model are the same (default Check.ModelEqual).</param>
/// <param name="seed">The initial seed to use for the first iteration.</param>
/// <param name="iter">The number of iterations to run in the sample (default 100).</param>
/// <param name="time">The number of seconds to run the sample.</param>
/// <param name="threads">The number of threads to run the sample on (default number logical CPUs).</param>
/// <param name="printActual">A function to convert the actual state to a string for error reporting (default Check.Print).</param>
/// <param name="printModel">A function to convert the model state to a string for error reporting (default Check.Print).</param>
Sample model-based operations on a random initial state checking that actual and model are equal.
If not the failing initial state and sequence will be shrunk down to the shortest and simplest.
Sample model - based operations on a random initial state checking that actual and model are equal . If not the failing initial state and sequence will be shrunk down to the shortest and simplest .
public static void SampleModelBased<Actual, Model>(this Gen<(Actual, Model)> initial, GenOperation<Actual, Model>[] operations,
            Func<Actual, Model, bool> equal = null, string seed = null, long iter = -1, int time = -1, int threads = -1,
            Func<Actual, string> printActual = null, Func<Model, string> printModel = null)
        {
            if (equal is null) equal = ModelEqual;
            if (seed is null) seed = Seed;
            if (iter == -1) iter = Iter;
            if (time == -1) time = Time;
            if (threads == -1) threads = Threads;
            if (printActual is null) printActual = Print;
            if (printModel is null) printModel = Print;
            var opNameActions = new Gen<(string, Action<Actual, Model>)>[operations.Length];
            for (int i = 0; i < operations.Length; i++)
            {
                var op = operations[i];
                var opName = "Op" + i;
                opNameActions[i] = op.AddOpNumber ? op.Select(t => (opName + t.Item1, t.Item2)) : op;
            }
            Gen.Create((PCG pcg, Size min, out Size size) =>
            {
                var stream = pcg.Stream;
                var seed = pcg.Seed;
                return (initial.Generate(pcg, null, out size), stream, seed);
            })
            .Select(Gen.OneOf(opNameActions).Array, (a, b) =>
                 new ModelBasedData<Actual, Model>
                 {
                     ActualState = a.Item1.Item1,
                     ModelState = a.Item1.Item2,
                     Stream = a.stream,
                     Seed = a.seed,
                     Operations = b
                 })
            .Sample(d =>
            {
                try
                {
                    foreach (var operation in d.Operations)
                        operation.Item2(d.ActualState, d.ModelState);
                    return equal(d.ActualState, d.ModelState);
                }
                catch (Exception e)
                {
                    d.Exception = e;
                    return false;
                }
            }, seed, iter, time, threads,
            p =>
            {
                if (p == null) return "";
                var sb = new StringBuilder();
                sb.Append("\n    Operations: ").Append(Print(p.Operations.Select(i => i.Item1).ToList()));
                var initialState = initial.Generate(new PCG(p.Stream, p.Seed), null, out _);
                sb.Append("\nInitial Actual: ").Append(printActual(initialState.Item1));
                sb.Append("\nInitial  Model: ").Append(printModel(initialState.Item2));
                if (p.Exception is null)
                {
                    sb.Append("\n  Final Actual: ").Append(printActual(p.ActualState));
                    sb.Append("\n  Final  Model: ").Append(printModel(p.ModelState));
                }
                else
                {
                    sb.Append("\n     Exception: ").Append(p.Exception.ToString());
                }
                return sb.ToString();
            });
        }
public static void SampleModelBased < Actual , Model > ( this Gen < ( Actual , Model ) > initial , GenOperation < Actual , Model > [ ] operations , Func < Actual , Model , bool > equal = null , string seed = null , long iter = - 1 , int time = - 1 , int threads = - 1 , Func < Actual , string > printActual = null , Func < Model , string > printModel = null ) { if ( equal is null ) equal = ModelEqual ; if ( seed is null ) seed = Seed ; if ( iter == - 1 ) iter = Iter ; if ( time == - 1 ) time = Time ; if ( threads == - 1 ) threads = Threads ; if ( printActual is null ) printActual = Print ; if ( printModel is null ) printModel = Print ; var opNameActions = new Gen < ( string , Action < Actual , Model > ) > [ operations . Length ] ; for ( int i = 0 ; i < operations . Length ; i ++ ) { var op = operations [ i ] ; var opName = " " + i ; opNameActions [ i ] = op . AddOpNumber ? op . Select ( t => ( opName + t . Item1 , t . Item2 ) ) : op ; } Gen . Create ( ( PCG pcg , Size min , out Size size ) => { var stream = pcg . Stream ; var seed = pcg . Seed ; return ( initial . Generate ( pcg , null , out size ) , stream , seed ) ; } ) . Select ( Gen . OneOf ( opNameActions ) . Array , ( a , b ) => new ModelBasedData < Actual , Model > { ActualState = a . Item1 . Item1 , ModelState = a . Item1 . Item2 , Stream = a . stream , Seed = a . seed , Operations = b } ) . Sample ( d => { try { foreach ( var operation in d . Operations ) operation . Item2 ( d . ActualState , d . ModelState ) ; return equal ( d . ActualState , d . ModelState ) ; } catch ( Exception e ) { d . Exception = e ; return false ; } } , seed , iter , time , threads , p => { if ( p == null ) return " " ; var sb = new StringBuilder ( ) ; sb . Append ( " \n " ) . Append ( Print ( p . Operations . Select ( i => i . Item1 ) . ToList ( ) ) ) ; var initialState = initial . Generate ( new PCG ( p . Stream , p . Seed ) , null , out _ ) ; sb . Append ( " \n " ) . Append ( printActual ( initialState . Item1 ) ) ; sb . Append ( " \n " ) . Append ( printModel ( initialState . Item2 ) ) ; if ( p . Exception is null ) { sb . Append ( " \n " ) . Append ( printActual ( p . ActualState ) ) ; sb . Append ( " \n " ) . Append ( printModel ( p . ModelState ) ) ; } else { sb . Append ( " \n " ) . Append ( p . Exception . ToString ( ) ) ; } return sb . ToString ( ) ; } ) ; }
Sample model-based operations on a random initial state checking that actual and model are equal.
Sample model - based operations on a random initial state checking that actual and model are equal .
Gen<(Actual, Model)>
this
operations
GenOperation<Actual, Model>[]
The operation generators that can act on the state.
The operation generators that can act on the state .
equal
Func<Actual, Model, bool>
A function to check if the actual and model are the same (default Check.ModelEqual).
A function to check if the actual and model are the same ( default Check . ModelEqual ) .
seed
string
The initial seed to use for the first iteration.
The initial seed to use for the first iteration .
iter
long
The number of iterations to run in the sample (default 100).
The number of iterations to run in the sample ( default 100 ) .
time
int
The number of seconds to run the sample.
The number of seconds to run the sample .
threads
int
The number of threads to run the sample on (default number logical CPUs).
The number of threads to run the sample on ( default number logical CPUs ) .
printActual
Func<Actual, string>
A function to convert the actual state to a string for error reporting (default Check.Print).
A function to convert the actual state to a string for error reporting ( default Check . Print ) .
printModel
Func<Model, string>
A function to convert the model state to a string for error reporting (default Check.Print).
A function to convert the model state to a string for error reporting ( default Check . Print ) .
initial
The initial state generator.
The initial state generator .