diff --git a/CsCheck/Gen.cs b/CsCheck/Gen.cs index 4e423ec..b365bf3 100644 --- a/CsCheck/Gen.cs +++ b/CsCheck/Gen.cs @@ -16,6 +16,7 @@ namespace CsCheck; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; +using System.Xml.Linq; /// Size representation of Gen generated data. public sealed class Size @@ -82,43 +83,14 @@ public abstract class Gen : IGen { public abstract T Generate(PCG pcg, Size? min, out Size size); - public GenOperation Operation(Func name, Action action) => new((PCG pcg, Size? min, out Size size) => - { - var t = Generate(pcg, min, out size); - return (name(t), m => action(m, t)); - }); - - public GenOperation Operation(Action action) => new((PCG pcg, Size? min, out Size size) => - { - var t = Generate(pcg, min, out size); - return (" " + Check.Print(t), m => action(m, t)); - }, true); - - public GenOperation Operation(Func name, Action action) - => new((PCG pcg, Size? min, out Size size) => - { - var t = Generate(pcg, min, out size); - return (name(t), (a, m) => action(a, m, t)); - }); - - public GenOperation Operation(Action action) - => new((PCG pcg, Size? min, out Size size) => - { - var t = Generate(pcg, min, out size); - return (" " + Check.Print(t), (a, m) => action(a, m, t)); - }, true); - - public GenMetamorphic Metamorphic(Func name, Action action1, Action action2) => new((PCG pcg, Size? min, out Size size) => - { - var t = Generate(pcg, min, out size); - return (name(t), m => action1(m, t), m => action2(m, t)); - }); - - public GenMetamorphic Metamorphic(Action action1, Action action2) => new((PCG pcg, Size? min, out Size size) => - { - var t = Generate(pcg, min, out size); - return (Check.Print(t), m => action1(m, t), m => action2(m, t)); - }); + public GenOperation Operation(Func name, Action action) => GenOperation.Create(this, name, action); + public GenOperation Operation(Func name, Func async) => GenOperation.Create(this, name, (S s, T t) => async(s, t).Wait()); + public GenOperation Operation(Action action) => GenOperation.Create(this, action); + public GenOperation Operation(Func async) => GenOperation.Create(this, (S s, T t) => async(s, t).Wait()); + public GenOperation Operation(Func name, Action action) => GenOperation.Create(this, name, action); + public GenOperation Operation(Action action) => GenOperation.Create(this, action); + public GenMetamorphic Metamorphic(Func name, Action action1, Action action2) => GenOperation.Create(this, name, action1, action2); + public GenMetamorphic Metamorphic(Action action1, Action action2) => GenOperation.Create(this, Check.Print, action1, action2); /// Generator for an array of public GenArray Array => new(this); @@ -132,7 +104,6 @@ public GenOperation Operation(Action ArrayUnique => new(this); } -delegate T GenDelegate(PCG pcg, Size? min, out Size size); public delegate T GenMap(T v, ref Size size); /// Provides a set of static methods for composing generators. @@ -1481,17 +1452,12 @@ sealed class GenNull(Gen gen, uint nullLimit) : Gen where T : class return new GenNull(gen, (uint)(nullFraction * uint.MaxValue)); } - public static GenOperation Operation(string name, Action action) - => new((PCG _, Size? __, out Size size) => { size = new Size(0); return (name, action); }); - - public static GenOperation Operation(Action action) - => new((PCG _, Size? __, out Size size) => { size = new Size(0); return ("", action); }, true); - - public static GenOperation Operation(string name, Action action) - => new((PCG _, Size? __, out Size size) => { size = new Size(0); return (name, action); }); - - public static GenOperation Operation(Action action) - => new((PCG _, Size? __, out Size size) => { size = new Size(0); return ("", action); }, true); + public static GenOperation Operation(string name, Action action) => GenOperation.Create(name, action); + public static GenOperation Operation(string name, Func async) => GenOperation.Create(name, (T t) => async(t).Wait()); + public static GenOperation Operation(Action action) => GenOperation.Create(action); + public static GenOperation Operation(Func async) => GenOperation.Create((T t) => async(t).Wait()); + public static GenOperation Operation(string name, Action action) => GenOperation.Create(name, action); + public static GenOperation Operation(Action action) => GenOperation.Create(action); /// Generator for bool. public static readonly GenBool Bool = new(); @@ -2876,33 +2842,52 @@ public override SortedDictionary Generate(PCG pcg, Size? min, out Size siz public sealed class GenOperation : Gen<(string, Action)> { public bool AddOpNumber; - readonly GenDelegate<(string, Action)> generate; - internal GenOperation(GenDelegate<(string, Action)> generate) => this.generate = generate; - internal GenOperation(GenDelegate<(string, Action)> generate, bool addOpNumber) + readonly Gen<(string, Action)> gen; + internal GenOperation(Gen<(string, Action)> gen, bool addOpNumber) { - this.generate = generate; + this.gen = gen; AddOpNumber = addOpNumber; } - public override (string, Action) Generate(PCG pcg, Size? min, out Size size) => generate(pcg, min, out size); + public override (string, Action) Generate(PCG pcg, Size? min, out Size size) => gen.Generate(pcg, min, out size); } public sealed class GenOperation : Gen<(string, Action)> { public bool AddOpNumber; - readonly GenDelegate<(string, Action)> generate; - internal GenOperation(GenDelegate<(string, Action)> generate) => this.generate = generate; - internal GenOperation(GenDelegate<(string, Action)> generate, bool addOpNumber) + readonly Gen<(string, Action)> gen; + internal GenOperation(Gen<(string, Action)> gen, bool addOpNumber) { - this.generate = generate; + this.gen = gen; AddOpNumber = addOpNumber; } - public override (string, Action) Generate(PCG pcg, Size? min, out Size size) => generate(pcg, min, out size); + public override (string, Action) Generate(PCG pcg, Size? min, out Size size) => gen.Generate(pcg, min, out size); } public sealed class GenMetamorphic : Gen<(string, Action, Action)> { - readonly GenDelegate<(string, Action, Action)> generate; - internal GenMetamorphic(GenDelegate<(string, Action, Action)> generate) => this.generate = generate; + readonly Gen<(string, Action, Action)> gen; + internal GenMetamorphic(Gen<(string, Action, Action)> gen) => this.gen = gen; + public override (string, Action, Action) Generate(PCG pcg, Size? min, out Size size) => gen.Generate(pcg, min, out size); +} - public override (string, Action, Action) Generate(PCG pcg, Size? min, out Size size) => generate(pcg, min, out size); +public static class GenOperation +{ + public static GenOperation Create(Gen gen, Action action) => + new(gen.Select)>(t => (" " + Check.Print(t), s => action(s, t))), true); + public static GenOperation Create(Gen gen, Func name, Action action) => + new(gen.Select)>(t => (name(t), s => action(s, t))), false); + public static GenOperation Create(Gen gen, Action action) => + new(gen.Select)>(t => (" " + Check.Print(t), (s1, s2) => action(s1, s2, t))), true); + public static GenOperation Create(Gen gen, Func name, Action action) => + new(gen.Select)>(t => (name(t), (s1, s2) => action(s1, s2, t))), false); + public static GenOperation Create(Action action) + => new(Gen.Const(("", action)), true); + public static GenOperation Create(string name, Action action) + => new(Gen.Const((name, action)), false); + public static GenOperation Create(Action action) + => new(Gen.Const(("", action)), true); + public static GenOperation Create(string name, Action action) + => new(Gen.Const((name, action)), false); + public static GenMetamorphic Create(Gen gen, Func name, Action action1, Action action2) => + new(gen.Select, Action)>(t => (name(t), s => action1(s, t), s => action2(s, t)))); } \ No newline at end of file diff --git a/Tests/CacheTests.cs b/Tests/CacheTests.cs index 1b2fc87..3bfad01 100644 --- a/Tests/CacheTests.cs +++ b/Tests/CacheTests.cs @@ -5,8 +5,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; -#pragma warning disable xUnit1031 // Do not use blocking task operations in test method - public class CacheTests { class ConcurrentDictionaryCache : ConcurrentDictionary, ICache where K : notnull @@ -20,7 +18,7 @@ public void GetOrAddAtomicAsync_SampleConcurrent() { Check.SampleConcurrent( Gen.Const(() => new ConcurrentDictionaryCache()), - Gen.Int[1, 5].Operation>((d, i) => d.GetOrAddAtomicAsync(i, i => Task.FromResult(i)).AsTask().Wait()), + Gen.Int[1, 5].Operation>((d, i) => d.GetOrAddAtomicAsync(i, i => Task.FromResult(i)).AsTask()), equal: (a, b) => Check.Equal(a.Keys, b.Keys), print: a => Check.Print(a.Keys) ); @@ -41,4 +39,4 @@ public async Task GetOrAddAtomicAsync_ExceptionSync() var exception = await Assert.ThrowsAsync(() => cache.GetOrAddAtomicAsync(1, _ => throw new CsCheckException("no")).AsTask()); Assert.Equal("no", exception.Message); } -} +} \ No newline at end of file