fix: make ==/Equals ignore build metadata for precedence

Previously SemanticVersion was a record struct whose ==/Equals/
GetHashCode were synthesized from all fields, so versions that
differ only in build metadata were not equal. Range matching
already used precedence (ignoring metadata), creating an
inconsistency.

Change the type to a plain readonly struct implementing
IEquatable<SemanticVersion> and define ==/Equals/GetHashCode
in terms of SemanticVersionComparer.Priority, so build
metadata is ignored. The custom ToString already existed, so no
display behaviour is lost.

Add a failing-then-passing test.
This commit is contained in:
Louis Seubert 2026-07-11 21:57:45 +02:00
commit 95eb4f05a2
7 changed files with 54 additions and 5 deletions

View file

@ -212,6 +212,19 @@ internal sealed class SemanticVersionTests
await Assert.That(SemanticVersion.TryParse(input, out _)).IsTrue();
}
[Test]
public async Task I_can_treat_versions_as_equal_when_only_build_metadata_differs()
{
var a = SemanticVersion.Parse("1.2.3");
var b = SemanticVersion.Parse("1.2.3+build.7");
await Assert.That(a == b).IsTrue();
await Assert.That(a.GetHashCode()).IsEqualTo(b.GetHashCode());
var c = SemanticVersion.Parse("1.2.3-alpha");
await Assert.That(a == c).IsFalse();
}
[Test]
public async Task I_can_handle_invalid_json_token()
{