Refactor code structure for improved readability and maintainability; optimize performance in key functions.

This commit is contained in:
master
2025-12-22 19:06:31 +02:00
parent dfaa2079aa
commit 4602ccc3a3
1444 changed files with 109919 additions and 8058 deletions

View File

@@ -0,0 +1,58 @@
using FluentAssertions;
using StellaOps.Canonicalization.Json;
using StellaOps.Canonicalization.Ordering;
using Xunit;
namespace StellaOps.Canonicalization.Tests;
public class CanonicalJsonSerializerTests
{
[Fact]
public void Serialize_Dictionary_OrdersKeysAlphabetically()
{
var dict = new Dictionary<string, int> { ["z"] = 1, ["a"] = 2, ["m"] = 3 };
var json = CanonicalJsonSerializer.Serialize(dict);
json.Should().Be("{\"a\":2,\"m\":3,\"z\":1}");
}
[Fact]
public void Serialize_DateTimeOffset_UsesUtcIso8601()
{
var dt = new DateTimeOffset(2024, 1, 15, 10, 30, 0, TimeSpan.FromHours(5));
var obj = new { Timestamp = dt };
var json = CanonicalJsonSerializer.Serialize(obj);
json.Should().Contain("2024-01-15T05:30:00.000Z");
}
[Fact]
public void Serialize_NullValues_AreOmitted()
{
var obj = new { Name = "test", Value = (string?)null };
var json = CanonicalJsonSerializer.Serialize(obj);
json.Should().NotContain("value");
}
[Fact]
public void SerializeWithDigest_ProducesConsistentDigest()
{
var obj = new { Name = "test", Value = 123 };
var (_, digest1) = CanonicalJsonSerializer.SerializeWithDigest(obj);
var (_, digest2) = CanonicalJsonSerializer.SerializeWithDigest(obj);
digest1.Should().Be(digest2);
}
}
public class PackageOrdererTests
{
[Fact]
public void StableOrder_OrdersByPurlFirst()
{
var packages = new[]
{
(purl: "pkg:npm/b@1.0.0", name: "b", version: "1.0.0"),
(purl: "pkg:npm/a@1.0.0", name: "a", version: "1.0.0")
};
var ordered = packages.StableOrder(p => p.purl, p => p.name, p => p.version, _ => null).ToList();
ordered[0].purl.Should().Be("pkg:npm/a@1.0.0");
}
}

View File

@@ -0,0 +1,46 @@
using FsCheck;
using FsCheck.Xunit;
using StellaOps.Canonicalization.Json;
using StellaOps.Canonicalization.Ordering;
namespace StellaOps.Canonicalization.Tests.Properties;
public class CanonicalJsonProperties
{
[Property]
public Property Serialize_IsIdempotent(Dictionary<string, int> dict)
{
var json1 = CanonicalJsonSerializer.Serialize(dict);
var json2 = CanonicalJsonSerializer.Serialize(dict);
return (json1 == json2).ToProperty();
}
[Property]
public Property Serialize_OrderIndependent(Dictionary<string, int> dict)
{
var reversed = dict.Reverse().ToDictionary(x => x.Key, x => x.Value);
var json1 = CanonicalJsonSerializer.Serialize(dict);
var json2 = CanonicalJsonSerializer.Serialize(reversed);
return (json1 == json2).ToProperty();
}
[Property]
public Property Digest_IsDeterministic(string input)
{
var obj = new { Value = input ?? string.Empty };
var (_, digest1) = CanonicalJsonSerializer.SerializeWithDigest(obj);
var (_, digest2) = CanonicalJsonSerializer.SerializeWithDigest(obj);
return (digest1 == digest2).ToProperty();
}
}
public class OrderingProperties
{
[Property]
public Property PackageOrdering_IsStable(List<(string purl, string name, string version)> packages)
{
var ordered1 = packages.StableOrder(p => p.purl, p => p.name, p => p.version, _ => null).ToList();
var ordered2 = packages.StableOrder(p => p.purl, p => p.name, p => p.version, _ => null).ToList();
return ordered1.SequenceEqual(ordered2).ToProperty();
}
}

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FsCheck.Xunit" Version="2.16.6" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\StellaOps.Canonicalization\StellaOps.Canonicalization.csproj" />
</ItemGroup>
</Project>