Skip to content

Commit

Permalink
SampleConcurrent async overloads
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyLloyd committed Feb 14, 2024
1 parent 1b6ecc6 commit fab981f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 66 deletions.
109 changes: 47 additions & 62 deletions CsCheck/Gen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace CsCheck;

using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Xml.Linq;

/// <summary>Size representation of Gen generated data.</summary>
public sealed class Size
Expand Down Expand Up @@ -82,43 +83,14 @@ public abstract class Gen<T> : IGen<T>
{
public abstract T Generate(PCG pcg, Size? min, out Size size);

public GenOperation<S> Operation<S>(Func<T, string> name, Action<S, T> 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<S> Operation<S>(Action<S, T> 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<Actual, Model> Operation<Actual, Model>(Func<T, string> name, Action<Actual, Model, T> 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<Actual, Model> Operation<Actual, Model>(Action<Actual, Model, T> 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<S> Metamorphic<S>(Func<T, string> name, Action<S, T> action1, Action<S, T> 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<S> Metamorphic<S>(Action<S, T> action1, Action<S, T> 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<S> Operation<S>(Func<T, string> name, Action<S, T> action) => GenOperation.Create(this, name, action);
public GenOperation<S> Operation<S>(Func<T, string> name, Func<S, T, Task> async) => GenOperation.Create(this, name, (S s, T t) => async(s, t).Wait());
public GenOperation<S> Operation<S>(Action<S, T> action) => GenOperation.Create(this, action);
public GenOperation<S> Operation<S>(Func<S, T, Task> async) => GenOperation.Create(this, (S s, T t) => async(s, t).Wait());
public GenOperation<Actual, Model> Operation<Actual, Model>(Func<T, string> name, Action<Actual, Model, T> action) => GenOperation.Create(this, name, action);
public GenOperation<Actual, Model> Operation<Actual, Model>(Action<Actual, Model, T> action) => GenOperation.Create(this, action);
public GenMetamorphic<S> Metamorphic<S>(Func<T, string> name, Action<S, T> action1, Action<S, T> action2) => GenOperation.Create(this, name, action1, action2);
public GenMetamorphic<S> Metamorphic<S>(Action<S, T> action1, Action<S, T> action2) => GenOperation.Create(this, Check.Print, action1, action2);

/// <summary>Generator for an array of <typeparamref name="T"/></summary>
public GenArray<T> Array => new(this);
Expand All @@ -132,7 +104,6 @@ public GenOperation<Actual, Model> Operation<Actual, Model>(Action<Actual, Model
public GenArrayUnique<T> ArrayUnique => new(this);
}

delegate T GenDelegate<out T>(PCG pcg, Size? min, out Size size);
public delegate T GenMap<T>(T v, ref Size size);

/// <summary>Provides a set of static methods for composing generators.</summary>
Expand Down Expand Up @@ -1481,17 +1452,12 @@ sealed class GenNull<T>(Gen<T> gen, uint nullLimit) : Gen<T?> where T : class
return new GenNull<T>(gen, (uint)(nullFraction * uint.MaxValue));
}

public static GenOperation<T> Operation<T>(string name, Action<T> action)
=> new((PCG _, Size? __, out Size size) => { size = new Size(0); return (name, action); });

public static GenOperation<T> Operation<T>(Action<T> action)
=> new((PCG _, Size? __, out Size size) => { size = new Size(0); return ("", action); }, true);

public static GenOperation<Actual, Model> Operation<Actual, Model>(string name, Action<Actual, Model> action)
=> new((PCG _, Size? __, out Size size) => { size = new Size(0); return (name, action); });

public static GenOperation<Actual, Model> Operation<Actual, Model>(Action<Actual, Model> action)
=> new((PCG _, Size? __, out Size size) => { size = new Size(0); return ("", action); }, true);
public static GenOperation<T> Operation<T>(string name, Action<T> action) => GenOperation.Create(name, action);
public static GenOperation<T> Operation<T>(string name, Func<T, Task> async) => GenOperation.Create(name, (T t) => async(t).Wait());
public static GenOperation<T> Operation<T>(Action<T> action) => GenOperation.Create(action);
public static GenOperation<T> Operation<T>(Func<T, Task> async) => GenOperation.Create((T t) => async(t).Wait());
public static GenOperation<Actual, Model> Operation<Actual, Model>(string name, Action<Actual, Model> action) => GenOperation.Create(name, action);
public static GenOperation<Actual, Model> Operation<Actual, Model>(Action<Actual, Model> action) => GenOperation.Create(action);

/// <summary>Generator for bool.</summary>
public static readonly GenBool Bool = new();
Expand Down Expand Up @@ -2876,33 +2842,52 @@ public override SortedDictionary<K, V> Generate(PCG pcg, Size? min, out Size siz
public sealed class GenOperation<T> : Gen<(string, Action<T>)>
{
public bool AddOpNumber;
readonly GenDelegate<(string, Action<T>)> generate;
internal GenOperation(GenDelegate<(string, Action<T>)> generate) => this.generate = generate;
internal GenOperation(GenDelegate<(string, Action<T>)> generate, bool addOpNumber)
readonly Gen<(string, Action<T>)> gen;
internal GenOperation(Gen<(string, Action<T>)> gen, bool addOpNumber)
{
this.generate = generate;
this.gen = gen;
AddOpNumber = addOpNumber;
}
public override (string, Action<T>) Generate(PCG pcg, Size? min, out Size size) => generate(pcg, min, out size);
public override (string, Action<T>) Generate(PCG pcg, Size? min, out Size size) => gen.Generate(pcg, min, out size);
}

public sealed class GenOperation<T1, T2> : Gen<(string, Action<T1, T2>)>
{
public bool AddOpNumber;
readonly GenDelegate<(string, Action<T1, T2>)> generate;
internal GenOperation(GenDelegate<(string, Action<T1, T2>)> generate) => this.generate = generate;
internal GenOperation(GenDelegate<(string, Action<T1, T2>)> generate, bool addOpNumber)
readonly Gen<(string, Action<T1, T2>)> gen;
internal GenOperation(Gen<(string, Action<T1, T2>)> gen, bool addOpNumber)
{
this.generate = generate;
this.gen = gen;
AddOpNumber = addOpNumber;
}
public override (string, Action<T1, T2>) Generate(PCG pcg, Size? min, out Size size) => generate(pcg, min, out size);
public override (string, Action<T1, T2>) Generate(PCG pcg, Size? min, out Size size) => gen.Generate(pcg, min, out size);
}

public sealed class GenMetamorphic<T> : Gen<(string, Action<T>, Action<T>)>
{
readonly GenDelegate<(string, Action<T>, Action<T>)> generate;
internal GenMetamorphic(GenDelegate<(string, Action<T>, Action<T>)> generate) => this.generate = generate;
readonly Gen<(string, Action<T>, Action<T>)> gen;
internal GenMetamorphic(Gen<(string, Action<T>, Action<T>)> gen) => this.gen = gen;
public override (string, Action<T>, Action<T>) Generate(PCG pcg, Size? min, out Size size) => gen.Generate(pcg, min, out size);
}

public override (string, Action<T>, Action<T>) Generate(PCG pcg, Size? min, out Size size) => generate(pcg, min, out size);
public static class GenOperation
{
public static GenOperation<S> Create<S, T>(Gen<T> gen, Action<S, T> action) =>
new(gen.Select<T, (string, Action<S>)>(t => (" " + Check.Print(t), s => action(s, t))), true);
public static GenOperation<S> Create<S, T>(Gen<T> gen, Func<T, string> name, Action<S, T> action) =>
new(gen.Select<T, (string, Action<S>)>(t => (name(t), s => action(s, t))), false);
public static GenOperation<S1, S2> Create<S1, S2, T>(Gen<T> gen, Action<S1, S2, T> action) =>
new(gen.Select<T, (string, Action<S1, S2>)>(t => (" " + Check.Print(t), (s1, s2) => action(s1, s2, t))), true);
public static GenOperation<S1, S2> Create<S1, S2, T>(Gen<T> gen, Func<T, string> name, Action<S1, S2, T> action) =>
new(gen.Select<T, (string, Action<S1, S2>)>(t => (name(t), (s1, s2) => action(s1, s2, t))), false);
public static GenOperation<T> Create<T>(Action<T> action)
=> new(Gen.Const(("", action)), true);
public static GenOperation<T> Create<T>(string name, Action<T> action)
=> new(Gen.Const((name, action)), false);
public static GenOperation<T1, T2> Create<T1, T2>(Action<T1, T2> action)
=> new(Gen.Const(("", action)), true);
public static GenOperation<T1, T2> Create<T1, T2>(string name, Action<T1, T2> action)
=> new(Gen.Const((name, action)), false);
public static GenMetamorphic<S> Create<S, T>(Gen<T> gen, Func<T, string> name, Action<S, T> action1, Action<S, T> action2) =>
new(gen.Select<T, (string, Action<S>, Action<S>)>(t => (name(t), s => action1(s, t), s => action2(s, t))));
}
6 changes: 2 additions & 4 deletions Tests/CacheTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<K, V> : ConcurrentDictionary<K, V>, ICache<K, V> where K : notnull
Expand All @@ -20,7 +18,7 @@ public void GetOrAddAtomicAsync_SampleConcurrent()
{
Check.SampleConcurrent(
Gen.Const(() => new ConcurrentDictionaryCache<int, int>()),
Gen.Int[1, 5].Operation<ConcurrentDictionaryCache<int, int>>((d, i) => d.GetOrAddAtomicAsync(i, i => Task.FromResult(i)).AsTask().Wait()),
Gen.Int[1, 5].Operation<ConcurrentDictionaryCache<int, int>>((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)
);
Expand All @@ -41,4 +39,4 @@ public async Task GetOrAddAtomicAsync_ExceptionSync()
var exception = await Assert.ThrowsAsync<CsCheckException>(() => cache.GetOrAddAtomicAsync(1, _ => throw new CsCheckException("no")).AsTask());
Assert.Equal("no", exception.Message);
}
}
}

0 comments on commit fab981f

Please sign in to comment.