Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
using StellaOps.Concelier.Normalization.Distro;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Normalization.Tests;
|
||||
|
||||
public sealed class ApkVersionParserTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalString_RoundTripsExplicitPkgRel()
|
||||
{
|
||||
var parsed = ApkVersion.Parse(" 3.1.4-r0 ");
|
||||
@@ -13,7 +15,8 @@ public sealed class ApkVersionParserTests
|
||||
Assert.Equal("3.1.4-r0", parsed.ToCanonicalString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalString_SuppressesImplicitPkgRel()
|
||||
{
|
||||
var parsed = ApkVersion.Parse("1.2.3_alpha");
|
||||
@@ -21,7 +24,8 @@ public sealed class ApkVersionParserTests
|
||||
Assert.Equal("1.2.3_alpha", parsed.ToCanonicalString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryParse_TracksExplicitRelease()
|
||||
{
|
||||
var success = ApkVersion.TryParse("2.0.1-r5", out var parsed);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using StellaOps.Concelier.Normalization.Identifiers;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Normalization.Tests;
|
||||
|
||||
public sealed class CpeNormalizerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalizeCpe_Preserves2Dot3Format()
|
||||
{
|
||||
var input = "cpe:2.3:A:Example:Product:1.0:*:*:*:*:*:*:*";
|
||||
@@ -15,7 +17,8 @@ public sealed class CpeNormalizerTests
|
||||
Assert.Equal("cpe:2.3:a:example:product:1.0:*:*:*:*:*:*:*", normalized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalizeCpe_UpgradesUriBinding()
|
||||
{
|
||||
var input = "cpe:/o:RedHat:Enterprise_Linux:8";
|
||||
@@ -26,7 +29,8 @@ public sealed class CpeNormalizerTests
|
||||
Assert.Equal("cpe:2.3:o:redhat:enterprise_linux:8:*:*:*:*:*:*:*", normalized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalizeCpe_InvalidInputReturnsFalse()
|
||||
{
|
||||
var success = IdentifierNormalizer.TryNormalizeCpe("not-a-cpe", out var normalized);
|
||||
@@ -35,7 +39,8 @@ public sealed class CpeNormalizerTests
|
||||
Assert.Null(normalized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalizeCpe_DecodesPercentEncodingAndEscapes()
|
||||
{
|
||||
var input = "cpe:/a:Example%20Corp:Widget%2fSuite:1.0:update:%7e:%2a";
|
||||
@@ -46,7 +51,8 @@ public sealed class CpeNormalizerTests
|
||||
Assert.Equal(@"cpe:2.3:a:example\ corp:widget\/suite:1.0:update:*:*:*:*:*:*", normalized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalizeCpe_ExpandsEditionFields()
|
||||
{
|
||||
var input = "cpe:/a:Vendor:Product:1.0:update:~pro~~windows~~:en-US";
|
||||
@@ -57,7 +63,8 @@ public sealed class CpeNormalizerTests
|
||||
Assert.Equal("cpe:2.3:a:vendor:product:1.0:update:*:en-us:pro:*:windows:*", normalized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalizeCpe_PreservesEscapedCharactersIn23()
|
||||
{
|
||||
var input = @"cpe:2.3:a:example:printer\/:1.2.3:*:*:*:*:*:*:*";
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using StellaOps.Concelier.Models;
|
||||
using StellaOps.Concelier.Normalization.Cvss;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Normalization.Tests;
|
||||
|
||||
public sealed class CvssMetricNormalizerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalize_ComputesCvss31Defaults()
|
||||
{
|
||||
var vector = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H";
|
||||
@@ -27,7 +29,8 @@ public sealed class CvssMetricNormalizerTests
|
||||
Assert.Equal(provenance, metric.Provenance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalize_NormalizesCvss20Severity()
|
||||
{
|
||||
var vector = "AV:N/AC:M/Au:S/C:P/I:P/A:P";
|
||||
@@ -41,7 +44,8 @@ public sealed class CvssMetricNormalizerTests
|
||||
Assert.Equal("medium", normalized.BaseSeverity);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalize_ReturnsFalseWhenVectorMissing()
|
||||
{
|
||||
var success = CvssMetricNormalizer.TryNormalize("3.1", string.Empty, 9.8, "CRITICAL", out var normalized);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using StellaOps.Concelier.Normalization.Distro;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Normalization.Tests;
|
||||
|
||||
public sealed class DebianEvrParserTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalString_RoundTripsExplicitEpoch()
|
||||
{
|
||||
var parsed = DebianEvr.Parse(" 1:1.2.3-1 ");
|
||||
@@ -13,7 +15,8 @@ public sealed class DebianEvrParserTests
|
||||
Assert.Equal("1:1.2.3-1", parsed.ToCanonicalString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalString_SuppressesZeroEpochWhenMissing()
|
||||
{
|
||||
var parsed = DebianEvr.Parse("1.2.3-1");
|
||||
@@ -21,7 +24,8 @@ public sealed class DebianEvrParserTests
|
||||
Assert.Equal("1.2.3-1", parsed.ToCanonicalString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalString_HandlesMissingRevision()
|
||||
{
|
||||
var parsed = DebianEvr.Parse("2:4.5");
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using StellaOps.Concelier.Normalization.Text;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Normalization.Tests;
|
||||
|
||||
public sealed class DescriptionNormalizerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Normalize_RemovesMarkupAndCollapsesWhitespace()
|
||||
{
|
||||
var candidates = new[]
|
||||
@@ -18,7 +20,8 @@ public sealed class DescriptionNormalizerTests
|
||||
Assert.Equal("en", result.Language);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Normalize_FallsBackToPreferredLanguage()
|
||||
{
|
||||
var candidates = new[]
|
||||
@@ -33,7 +36,8 @@ public sealed class DescriptionNormalizerTests
|
||||
Assert.Equal("en", result.Language);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Normalize_ReturnsDefaultWhenEmpty()
|
||||
{
|
||||
var result = DescriptionNormalizer.Normalize(Array.Empty<LocalizedText>());
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using StellaOps.Concelier.Normalization.Distro;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Normalization.Tests;
|
||||
|
||||
public sealed class NevraParserTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalString_RoundTripsTrimmedInput()
|
||||
{
|
||||
var parsed = Nevra.Parse(" kernel-0:4.18.0-80.el8.x86_64 ");
|
||||
@@ -13,7 +15,8 @@ public sealed class NevraParserTests
|
||||
Assert.Equal("kernel-0:4.18.0-80.el8.x86_64", parsed.ToCanonicalString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalString_ReconstructsKnownArchitecture()
|
||||
{
|
||||
var parsed = Nevra.Parse("bash-5.2.15-3.el9_4.arm64");
|
||||
@@ -21,7 +24,8 @@ public sealed class NevraParserTests
|
||||
Assert.Equal("bash-5.2.15-3.el9_4.arm64", parsed.ToCanonicalString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ToCanonicalString_HandlesMissingArchitecture()
|
||||
{
|
||||
var parsed = Nevra.Parse("openssl-libs-1:1.1.1k-7.el8");
|
||||
@@ -29,7 +33,8 @@ public sealed class NevraParserTests
|
||||
Assert.Equal("openssl-libs-1:1.1.1k-7.el8", parsed.ToCanonicalString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryParse_ReturnsTrueForExplicitZeroEpoch()
|
||||
{
|
||||
var success = Nevra.TryParse("glibc-0:2.36-8.el9.x86_64", out var nevra);
|
||||
@@ -41,7 +46,8 @@ public sealed class NevraParserTests
|
||||
Assert.Equal("glibc-0:2.36-8.el9.x86_64", nevra.ToCanonicalString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryParse_IgnoresUnknownArchitectureSuffix()
|
||||
{
|
||||
var success = Nevra.TryParse("package-1.0-1.el9.weirdarch", out var nevra);
|
||||
@@ -53,7 +59,8 @@ public sealed class NevraParserTests
|
||||
Assert.Equal("package-1.0-1.el9.weirdarch", nevra.ToCanonicalString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryParse_ReturnsFalseForMalformedNevra()
|
||||
{
|
||||
var success = Nevra.TryParse("bad-format", out var nevra);
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using System.Linq;
|
||||
using StellaOps.Concelier.Normalization.Identifiers;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Normalization.Tests;
|
||||
|
||||
public sealed class PackageUrlNormalizerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalizePackageUrl_LowersTypeAndNamespace()
|
||||
{
|
||||
var input = "pkg:NPM/Acme/Widget@1.0.0?Arch=X86_64";
|
||||
@@ -20,7 +22,8 @@ public sealed class PackageUrlNormalizerTests
|
||||
Assert.Equal("widget", parsed.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalizePackageUrl_OrdersQualifiers()
|
||||
{
|
||||
var input = "pkg:deb/debian/openssl?distro=x%2Fy&arch=amd64";
|
||||
@@ -31,7 +34,8 @@ public sealed class PackageUrlNormalizerTests
|
||||
Assert.Equal("pkg:deb/debian/openssl?arch=amd64&distro=x%2Fy", normalized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void TryNormalizePackageUrl_TrimsWhitespace()
|
||||
{
|
||||
var input = " pkg:pypi/Example/Package ";
|
||||
|
||||
@@ -2,13 +2,15 @@ using StellaOps.Concelier.Models;
|
||||
using StellaOps.Concelier.Normalization.SemVer;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Concelier.Normalization.Tests;
|
||||
|
||||
public sealed class SemVerRangeRuleBuilderTests
|
||||
{
|
||||
private const string Note = "spec:test";
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData("< 1.5.0", null, NormalizedVersionRuleTypes.LessThan, null, true, "1.5.0", false, null, false)]
|
||||
[InlineData(">= 1.0.0, < 2.0.0", null, NormalizedVersionRuleTypes.Range, "1.0.0", true, "2.0.0", false, null, false)]
|
||||
[InlineData(">1.2.3, <=1.3.0", null, NormalizedVersionRuleTypes.Range, "1.2.3", false, null, false, "1.3.0", true)]
|
||||
@@ -46,7 +48,8 @@ public sealed class SemVerRangeRuleBuilderTests
|
||||
Assert.Equal(patched is null && expectedIntroduced is null && expectedFixed is null && expectedLastAffected is null ? null : Note, normalized.Notes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_UsesPatchedVersionWhenUpperBoundMissing()
|
||||
{
|
||||
var results = SemVerRangeRuleBuilder.Build(">= 4.0.0", "4.3.6", Note);
|
||||
@@ -65,7 +68,8 @@ public sealed class SemVerRangeRuleBuilderTests
|
||||
Assert.Equal(Note, normalized.Notes);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData("^1.2.3", "1.2.3", "2.0.0")]
|
||||
[InlineData("~1.2.3", "1.2.3", "1.3.0")]
|
||||
[InlineData("~> 1.2", "1.2.0", "1.3.0")]
|
||||
@@ -81,7 +85,8 @@ public sealed class SemVerRangeRuleBuilderTests
|
||||
Assert.Equal(NormalizedVersionRuleTypes.Range, normalized.Type);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData("1.2.x", "1.2.0", "1.3.0")]
|
||||
[InlineData("1.x", "1.0.0", "2.0.0")]
|
||||
public void Build_HandlesWildcardNotation(string range, string expectedMin, string expectedMax)
|
||||
@@ -97,7 +102,8 @@ public sealed class SemVerRangeRuleBuilderTests
|
||||
Assert.Equal(NormalizedVersionRuleTypes.Range, normalized.Type);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_PreservesPreReleaseAndMetadataInExactRule()
|
||||
{
|
||||
var results = SemVerRangeRuleBuilder.Build("= 2.5.1-alpha.1+build.7", null, Note);
|
||||
@@ -111,7 +117,8 @@ public sealed class SemVerRangeRuleBuilderTests
|
||||
Assert.Equal(Note, normalized.Notes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_ParsesComparatorWithoutCommaSeparators()
|
||||
{
|
||||
var results = SemVerRangeRuleBuilder.Build(">=1.0.0 <1.2.0", null, Note);
|
||||
@@ -133,7 +140,8 @@ public sealed class SemVerRangeRuleBuilderTests
|
||||
Assert.Equal(Note, normalized.Notes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Build_HandlesMultipleSegmentsSeparatedByOr()
|
||||
{
|
||||
var results = SemVerRangeRuleBuilder.Build(">=1.0.0 <1.2.0 || >=2.0.0 <2.2.0", null, Note);
|
||||
@@ -159,7 +167,8 @@ public sealed class SemVerRangeRuleBuilderTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void BuildNormalizedRules_ProjectsNormalizedRules()
|
||||
{
|
||||
var rules = SemVerRangeRuleBuilder.BuildNormalizedRules(">=1.0.0 <1.2.0", null, Note);
|
||||
@@ -174,7 +183,8 @@ public sealed class SemVerRangeRuleBuilderTests
|
||||
Assert.Equal(Note, rule.Notes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void BuildNormalizedRules_ReturnsEmptyWhenNoRules()
|
||||
{
|
||||
var rules = SemVerRangeRuleBuilder.BuildNormalizedRules(" ", null, Note);
|
||||
|
||||
@@ -8,5 +8,6 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Models/StellaOps.Concelier.Models.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Normalization/StellaOps.Concelier.Normalization.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user