Skip to content

Commit

Permalink
Merge changes from v6 branch
Browse files Browse the repository at this point in the history
- Add workspaces (gated behind configuration)
- Switch from handlers to providers for DI
- Fix for #597
  • Loading branch information
Guy Fankam committed Jul 29, 2024
2 parents e7b1414 + 5b4b148 commit bee3a2f
Show file tree
Hide file tree
Showing 169 changed files with 20,308 additions and 12,406 deletions.
2 changes: 1 addition & 1 deletion tools/code/aspire/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ private static void Main(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);

//builder.AddProject<extractor>("extractor");
builder.AddProject<integration_tests>("integration-tests");
//.WithEnvironment("CSCHECK_SEED", "0000KOIPe036");

builder.Build().Run();
}
Expand Down
6 changes: 4 additions & 2 deletions tools/code/aspire/aspire.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand All @@ -9,11 +9,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.0.1" />
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\extractor\extractor.csproj" />
<ProjectReference Include="..\integration.tests\integration.tests.csproj" />
<ProjectReference Include="..\publisher\publisher.csproj" />
</ItemGroup>

</Project>
265 changes: 145 additions & 120 deletions tools/code/common.tests/CsCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,26 @@
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text.Json.Nodes;

namespace common.tests;

public static class Generator
{
public static Gen<Internet> Internet { get; } = Gen.Const(new Internet());
public static Gen<Internet> Internet { get; } =
new GenBogusDataSet<Internet>(() => new Internet());

public static Gen<Address> Address { get; } = Gen.Const(new Address());
public static Gen<Address> Address { get; } =
new GenBogusDataSet<Address>(() => new Address());

public static Gen<Lorem> Lorem { get; } = Gen.Const(new Lorem());
public static Gen<Lorem> Lorem { get; } =
new GenBogusDataSet<Lorem>(() => new Lorem());

public static Gen<Uri> AbsoluteUri { get; } =
from internet in Internet
select new Uri(internet.Url());

public static Gen<Bogus.DataSets.System> BogusSystem { get; } = Gen.Const(new Bogus.DataSets.System());
public static Gen<Bogus.DataSets.System> BogusSystem { get; } =
new GenBogusDataSet<Bogus.DataSets.System>(() => new Bogus.DataSets.System());

public static Gen<DirectoryInfo> DirectoryInfo { get; } =
from system in BogusSystem
Expand All @@ -34,158 +37,89 @@ from system in BogusSystem
from system in BogusSystem
select new FileInfo(system.FilePath());

public static Gen<string> FileName { get; } =
from system in BogusSystem
select system.FileName();

public static Gen<string> NonEmptyString { get; } =
Gen.String.Where(x => string.IsNullOrWhiteSpace(x) is false);

public static Gen<JsonValue> JsonValue { get; } = GenerateJsonValue();

public static Gen<JsonObject> JsonObject { get; } = GenerateJsonObject();

public static Gen<JsonArray> JsonArray { get; } = GenerateJsonArray();

public static Gen<JsonNode> JsonNode { get; } = GenerateJsonNode();

private static Gen<JsonValue> GenerateJsonValue() =>
Gen.OneOf(Gen.Bool.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.Byte.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.Char.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.DateTime.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.DateTimeOffset.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.Decimal.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.Double.Where(double.IsFinite).Where(x => double.IsNaN(x) is false).Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.Float.Where(float.IsFinite).Where(x => float.IsNaN(x) is false).Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.Guid.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.Int.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.Long.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.SByte.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.Short.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.String.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.UInt.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.ULong.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)),
Gen.UShort.Select(x => System.Text.Json.Nodes.JsonValue.Create(x)));

private static Gen<JsonObject> GenerateJsonObject() =>
GenerateJsonObject(GenerateJsonNode(), limits: 100);

private static Gen<JsonObject> GenerateJsonObject(Gen<JsonNode> nodeGen, uint limits) =>
Gen.Dictionary(Gen.String.AlphaNumeric,
nodeGen.Null())[0, (int)limits]
.Select(x => new JsonObject(x));

private static Gen<JsonArray> GenerateJsonArray() =>
GenerateJsonArray(GenerateJsonNode(), limits: 100);

private static Gen<JsonArray> GenerateJsonArray(Gen<JsonNode> nodeGen, uint limits) =>
nodeGen.Null()
.Array[0, (int)limits]
.Select(x => new JsonArray(x));

private static Gen<JsonNode> GenerateJsonNode() =>
Gen.Recursive<JsonNode>((depth, gen) =>
depth == 3
? GenerateJsonValue().Select(x => x as JsonNode)
: Gen.OneOf(GenerateJsonValue().Select(x => x as JsonNode),
GenerateJsonObject(gen, limits: (uint)depth).Select(x => x as JsonNode),
GenerateJsonArray(gen, limits: (uint)depth).Select(x => x as JsonNode)));
public static Gen<string> AlphaNumericStringBetween(int minimumLength, int maximumLength) =>
Gen.Char
.AlphaNumeric
.Array[minimumLength, maximumLength]
.Select(x => new string(x));

public static Gen<string> AlphaNumericStringWithLength(int length) =>
Gen.Char.AlphaNumeric.Array[length].Select(x => new string(x));

public static Gen<string> AlphaNumericStringBetween(int minimumLength, int maximumLength) =>
Gen.Char.AlphaNumeric.Array[minimumLength, maximumLength].Select(x => new string(x));
Gen.Char
.AlphaNumeric
.Array[length]
.Select(x => new string(x));

public static Gen<ImmutableArray<T>> ImmutableArrayOf<T>(this Gen<T> gen) =>
gen.List.Select(x => x.ToImmutableArray());
gen.List
.Select(x => x.ToImmutableArray());

public static Gen<ImmutableArray<T>> ImmutableArrayOf<T>(this Gen<T> gen, int minimumCount, int maximumCount) =>
gen.List[minimumCount, maximumCount].Select(x => x.ToImmutableArray());
gen.List[minimumCount, maximumCount]
.Select(x => x.ToImmutableArray());

public static Gen<ImmutableArray<T>> SubImmutableArrayOf<T>(IEnumerable<T> enumerable)
public static Gen<ImmutableArray<T>> SubImmutableArrayOf<T>(ICollection<T> enumerable)
{
var array = enumerable.ToArray();

return from items in Gen.Shuffle(array, 0, array.Length)
select items.ToImmutableArray();
}

public static Gen<FrozenSet<T>> FrozenSetOf<T>(this Gen<T> gen) =>
gen.List.Select(x => x.ToFrozenSet());

public static Gen<FrozenSet<T>> FrozenSetOf<T>(this Gen<T> gen, int minimumCount, int maximumCount)
{
if (maximumCount < minimumCount)
{
throw new ArgumentException("Maximum count must be greater than or equal to minimum count.", nameof(maximumCount));
}

ArgumentOutOfRangeException.ThrowIfNegative(minimumCount, nameof(minimumCount));

return gen.List[minimumCount, maximumCount].Select(x => x.ToFrozenSet());
}

public static Gen<FrozenSet<T>> FrozenSetOf<T>(this Gen<T> gen, IEqualityComparer<T> comparer) =>
gen.List.Select(x => x.ToFrozenSet(comparer));

public static Gen<FrozenSet<T>> FrozenSetOf<T>(this Gen<T> gen, IEqualityComparer<T> comparer, int minimumCount, int maximumCount)
{
if (maximumCount < minimumCount)
{
throw new ArgumentException("Maximum count must be greater than or equal to minimum count.", nameof(maximumCount));
}

ArgumentOutOfRangeException.ThrowIfNegative(minimumCount, nameof(minimumCount));

return gen.List[minimumCount, maximumCount].Select(x => x.ToFrozenSet(comparer));
}

public static Gen<FrozenSet<T>> FrozenSetOf<T, TKey>(this Gen<T> gen, Func<T, TKey> keySelector)
public static Gen<FrozenSet<T>> FrozenSetOf<T, TKey>(this Gen<T> gen, Func<T, TKey> keySelector, int minimumCount, int maximumCount)
{
var comparer = EqualityComparerBuilder.For<T>().EquateBy(keySelector);

return gen.FrozenSetOf(comparer);
return gen.FrozenSetOf(minimumCount, maximumCount, comparer);
}

public static Gen<FrozenSet<T>> FrozenSetOf<T, TKey>(this Gen<T> gen, Func<T, TKey> keySelector, int minimumCount, int maximumCount)
public static Gen<FrozenSet<T>> FrozenSetOf<T, TKey>(this Gen<T> gen, Func<T, TKey> keySelector)
{
var comparer = EqualityComparerBuilder.For<T>().EquateBy(keySelector);

return gen.FrozenSetOf(comparer, minimumCount, maximumCount);
return gen.List
.Select(x => x.ToFrozenSet(comparer));
}

public static Gen<FrozenSet<T>> SubFrozenSetOf<T>(IEnumerable<T> enumerable) =>
SubImmutableArrayOf(enumerable)
.Select(x => x.ToFrozenSet());
public static Gen<FrozenSet<T>> FrozenSetOf<T>(this Gen<T> gen, IEqualityComparer<T>? comparer = default) =>
gen.List
.Select(x => x.ToFrozenSet(comparer));

public static Gen<FrozenSet<T>> SubFrozenSetOf<T>(IEnumerable<T> enumerable, IEqualityComparer<T> comparer) =>
SubImmutableArrayOf(enumerable)
public static Gen<FrozenSet<T>> FrozenSetOf<T>(this Gen<T> gen, int minimumCount, int maximumCount, IEqualityComparer<T>? comparer = default) =>
gen.List[minimumCount, maximumCount]
.Select(x => x.ToFrozenSet(comparer));

public static Gen<FrozenSet<T>> SubFrozenSetOf<T, TKey>(IEnumerable<T> enumerable, Func<T, TKey> keySelector)
public static Gen<FrozenSet<T>> SubFrozenSetOf<T>(ICollection<T> enumerable, IEqualityComparer<T>? comparer = default)
{
var comparer = EqualityComparerBuilder.For<T>().EquateBy(keySelector);

return SubFrozenSetOf(enumerable, comparer);
var comparerToUse = comparer switch
{
null => enumerable switch
{
FrozenSet<T> frozenSet => frozenSet.Comparer,
_ => comparer
},
_ => comparer
};

return SubImmutableArrayOf(enumerable)
.Select(x => x.ToFrozenSet(comparerToUse));
}

public static Gen<FrozenSet<T>> DistinctBy<T, TKey>(this Gen<FrozenSet<T>> gen, Func<T, TKey> keySelector) =>
from set in gen
select set.DistinctBy(keySelector)
.ToFrozenSet(set.Comparer);

public static Gen<Option<T>> OptionOf<T>(this Gen<T> gen) =>
Gen.Frequency((1, Gen.Const(Option<T>.None)),
(4, gen.Select(Option<T>.Some)));

public static Gen<string> ToUpperInvariant(this GenString gen) =>
gen.Select(x => x.ToUpperInvariant());

public static Gen<Option<T>> Sequence<T>(this Option<Gen<T>> option) =>
option.Match(gen => gen.Select(Option<T>.Some),
() => Gen.Const(Option<T>.None));

public static Gen<FrozenSet<T>> SequenceToFrozenSet<T, TKey>(this IEnumerable<Gen<T>> gens, Func<T, TKey> keySelector) =>
gens.SequenceToImmutableArray()
.Select(x => x.ToFrozenSet(keySelector));

public static Gen<FrozenSet<T>> SequenceToFrozenSet<T>(this IEnumerable<Gen<T>> gens, IEqualityComparer<T>? comparer = null) =>
gens.SequenceToImmutableArray()
.Select(x => x.ToFrozenSet(comparer));

/// <summary>
/// Converts a list of generators to a generator of lists
/// </summary>
Expand All @@ -195,4 +129,95 @@ from list in gens.Aggregate(Gen.Const(ImmutableList<T>.Empty),
from t in gen
select list.Add(t))
select list.ToImmutableArray();

/// <summary>
/// Converts a list of generators to a generator of frozen sets
/// </summary>
public static Gen<FrozenSet<T>> SequenceToFrozenSet<T, TKey>(this IEnumerable<Gen<T>> gens, Func<T, TKey> keySelector) =>
gens.SequenceToImmutableArray()
.Select(x => x.ToFrozenSet(keySelector));


/// <summary>
/// Converts a list of generators to a generator of frozen sets
/// </summary>
public static Gen<FrozenSet<T>> SequenceToFrozenSet<T>(this IEnumerable<Gen<T>> gens, IEqualityComparer<T>? comparer = null) =>
gens.SequenceToImmutableArray()
.Select(x => x.ToFrozenSet(comparer));

public static Gen<FrozenSet<T>> GenerateNewSet<T>(FrozenSet<T> original, Gen<FrozenSet<T>> newGen, Func<T, Gen<T>> updateGen) =>
GenerateNewSet(original, newGen, updateGen, ChangeParameters.All);

private static Gen<FrozenSet<T>> GenerateNewSet<T>(FrozenSet<T> original, Gen<FrozenSet<T>> newGen, Func<T, Gen<T>> updateGen, ChangeParameters changeParameters)
{
var generator = from originalItems in Gen.Const(original)
from itemsRemoved in changeParameters.Remove ? RemoveItems(originalItems) : Gen.Const(originalItems)
from itemsAdded in changeParameters.Add ? AddItems(itemsRemoved, newGen) : Gen.Const(itemsRemoved)
from itemsModified in changeParameters.Modify ? ModifyItems(itemsAdded, updateGen) : Gen.Const(itemsAdded)
select itemsModified;

return changeParameters.MaxSize.Map(maxSize => generator.SelectMany(set => set.Count <= maxSize
? generator
: from smallerSet in Gen.Shuffle(set.ToArray(), maxSize)
select smallerSet.ToFrozenSet(set.Comparer)))
.IfNone(generator);
}

private static Gen<FrozenSet<T>> RemoveItems<T>(FrozenSet<T> set) =>
from itemsToRemove in Generator.SubFrozenSetOf(set)
select set.Except(itemsToRemove, set.Comparer)
.ToFrozenSet(set.Comparer);

private static Gen<FrozenSet<T>> AddItems<T>(FrozenSet<T> set, Gen<FrozenSet<T>> gen) =>
from itemsToAdd in gen
select set.Concat(itemsToAdd)
.ToFrozenSet(set.Comparer);

private static Gen<FrozenSet<T>> ModifyItems<T>(FrozenSet<T> set, Func<T, Gen<T>> updateGen) =>
from itemsToModify in Generator.SubFrozenSetOf(set)
from modifiedItems in itemsToModify.Select(updateGen).SequenceToImmutableArray()
select set.Concat(itemsToModify)
.Concat(modifiedItems)
.ToFrozenSet(set.Comparer);

private sealed record ChangeParameters
{
public required bool Add { get; init; }
public required bool Modify { get; init; }
public required bool Remove { get; init; }

public static ChangeParameters None { get; } = new()
{
Add = false,
Modify = false,
Remove = false
};

public static ChangeParameters All { get; } = new()
{
Add = true,
Modify = true,
Remove = true
};

public Option<int> MaxSize { get; init; } = Option<int>.None;
}
}

/// <summary>
/// Generator for Bogus dataset <typeparamref name="T"/>. It's set to a constant value,
/// and its randomizer is seeded with the <see cref="Gen"/> seed.
/// </summary>
file sealed class GenBogusDataSet<T>(Func<T> creator) : Gen<T> where T : Bogus.DataSet
{
public override T Generate(PCG pcg, Size? min, out Size size)
{
var t = creator();
t.Random = new Bogus.Randomizer((int)pcg.Seed);

size = new Size(0);

return t;
}
}
7 changes: 2 additions & 5 deletions tools/code/common.tests/Group.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using CsCheck;
using LanguageExt;
using Nito.Comparers;
using System.Collections.Frozen;
using System.Linq;

Expand Down Expand Up @@ -35,8 +34,6 @@ from lorem in Generator.Lorem
select lorem.Paragraph();

public static Gen<FrozenSet<GroupModel>> GenerateSet() =>
Generate().FrozenSetOf(EqualityComparerBuilder.For<GroupModel>()
.EquateBy(x => x.Name)
.ThenEquateBy(x => x.DisplayName),
0, 10);
Generate().FrozenSetOf(x => x.Name, 0, 10)
.DistinctBy(x => x.DisplayName);
}
Loading

0 comments on commit bee3a2f

Please sign in to comment.