Files
git.stella-ops.org/src/__Tests/__Libraries/StellaOps.Testing.Determinism.Properties/JsonObjectArbitraries.cs
StellaOps Bot 907783f625 Add property-based tests for SBOM/VEX document ordering and Unicode normalization determinism
- Implement `SbomVexOrderingDeterminismProperties` for testing component list and vulnerability metadata hash consistency.
- Create `UnicodeNormalizationDeterminismProperties` to validate NFC normalization and Unicode string handling.
- Add project file for `StellaOps.Testing.Determinism.Properties` with necessary dependencies.
- Introduce CI/CD template validation tests including YAML syntax checks and documentation content verification.
- Create validation script for CI/CD templates ensuring all required files and structures are present.
2025-12-26 15:17:58 +02:00

82 lines
2.8 KiB
C#

using FsCheck;
namespace StellaOps.Testing.Determinism.Properties;
/// <summary>
/// FsCheck arbitrary generators for JSON-compatible data types.
/// </summary>
public static class JsonObjectArbitraries
{
/// <summary>
/// Generates dictionaries with string keys and values.
/// </summary>
public static Arbitrary<Dictionary<string, string>> StringDictionary()
{
return Gen.Sized(size =>
{
var count = Gen.Choose(0, Math.Min(size, 20));
return count.SelectMany(n =>
{
var keys = Gen.ArrayOf(n, Arb.Generate<NonEmptyString>().Select(s => s.Get))
.Select(arr => arr.Distinct().ToArray());
var values = Gen.ArrayOf(n, Arb.Generate<NonEmptyString>().Select(s => s.Get));
return keys.SelectMany(ks =>
values.Select(vs =>
{
var dict = new Dictionary<string, string>();
for (int i = 0; i < Math.Min(ks.Length, vs.Length); i++)
{
dict[ks[i]] = vs[i];
}
return dict;
}));
});
}).ToArbitrary();
}
/// <summary>
/// Generates dictionaries with nullable object values.
/// </summary>
public static Arbitrary<Dictionary<string, object?>> ObjectDictionary()
{
return Gen.Sized(size =>
{
var count = Gen.Choose(0, Math.Min(size, 15));
return count.SelectMany(n =>
{
var keys = Gen.ArrayOf(n, Arb.Generate<NonEmptyString>().Select(s => s.Get))
.Select(arr => arr.Distinct().ToArray());
var values = Gen.ArrayOf(n, JsonValueGen());
return keys.SelectMany(ks =>
values.Select(vs =>
{
var dict = new Dictionary<string, object?>();
for (int i = 0; i < Math.Min(ks.Length, vs.Length); i++)
{
dict[ks[i]] = vs[i];
}
return dict;
}));
});
}).ToArbitrary();
}
/// <summary>
/// Generates JSON-compatible values (strings, numbers, bools, nulls).
/// </summary>
private static Gen<object?> JsonValueGen()
{
return Gen.OneOf(
Arb.Generate<NonEmptyString>().Select(s => (object?)s.Get),
Arb.Generate<int>().Select(i => (object?)i),
Arb.Generate<double>()
.Where(d => !double.IsNaN(d) && !double.IsInfinity(d))
.Select(d => (object?)d),
Arb.Generate<bool>().Select(b => (object?)b),
Gen.Constant<object?>(null)
);
}
}