Skip to content

Commit

Permalink
fix ranges for changes to BigInteger #73
Browse files Browse the repository at this point in the history
  • Loading branch information
WalkerCodeRanger committed Apr 14, 2023
1 parent 60f3977 commit 52cbb15
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 129 deletions.
2 changes: 0 additions & 2 deletions Semver.Test/Ranges/LeftBoundedRangeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ public class LeftBoundedRangeTests
new LeftBoundedRange(SemVersion.MinRelease, false),
new LeftBoundedRange(Version("1.2.3"), true),
new LeftBoundedRange(Version("1.2.3"), false),
new LeftBoundedRange(SemVersion.Max, true),
new LeftBoundedRange(SemVersion.Max, false),
}.AsReadOnly();

internal static readonly IReadOnlyList<(LeftBoundedRange, LeftBoundedRange)> RangePairs
Expand Down
1 change: 0 additions & 1 deletion Semver.Test/Ranges/RightBoundedRangeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public class RightBoundedRangeTests
new RightBoundedRange(SemVersion.MinRelease, true),
new RightBoundedRange(Version("1.2.3"), false),
new RightBoundedRange(Version("1.2.3"), true),
new RightBoundedRange(SemVersion.Max, false),
RightBoundedRange.Unbounded,
}.AsReadOnly();

Expand Down
4 changes: 1 addition & 3 deletions Semver.Test/SemVersionRangeNpmParsingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,9 @@ public class SemVersionRangeNpmParsingTests
Valid("^*", true, All),

// Going past max version
Valid(">2147483647.*.*", InclusiveOfStart("2147483647.0.0", "2147483648.0.0-0")),
Valid(">1.2147483647.*", InclusiveOfStart("1.2147483647.0", "1.2147483648.0-0")),
Valid("~2147483647.*.*", InclusiveOfStart("2147483647.0.0", "2147483648.0.0-0")),
Valid("~1.2147483647.3", InclusiveOfStart("1.2147483647.3", "1.2147483648.0-0")),
Valid("^2147483647.2.3", InclusiveOfStart("2147483647.0.0", "2147483648.0.0-0")),
Valid("^2147483647.2.3", InclusiveOfStart("2147483647.2.3", "2147483648.0.0-0")),
Valid("^0.2147483647.3", InclusiveOfStart("0.2147483647.3", "0.2147483648.0-0")),
Valid("^0.0.2147483647", InclusiveOfStart("0.0.2147483647", "0.0.2147483648-0")),
Valid("2147483647.*", InclusiveOfStart("2147483647.0.0", "2147483648.0.0-0")),
Expand Down
16 changes: 0 additions & 16 deletions Semver.Test/SemVersionRangeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,6 @@ public void GreaterThanVersion(bool includeAllPrerelease)
Assert.Equal(new[] { UnbrokenSemVersionRange.GreaterThan(FakeVersion, includeAllPrerelease) }, range);
}

[Fact]
public void GreaterThanMaxVersionEmpty()
{
var range = SemVersionRange.GreaterThan(SemVersion.Max);
Assert.Same(SemVersionRange.Empty, range);
}

[Fact]
public void AtLeastNullVersion()
{
Expand Down Expand Up @@ -428,15 +421,6 @@ public void ExclusiveEmpty(bool includeAllPrerelease)
Assert.Same(SemVersionRange.Empty, range);
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void ExclusiveAtMaxEmpty(bool includeAllPrerelease)
{
var range = SemVersionRange.Exclusive(SemVersion.Max, SemVersion.Max, includeAllPrerelease);
Assert.Same(SemVersionRange.Empty, range);
}

[Fact]
public void CreateEnumerableEmpty()
{
Expand Down
34 changes: 6 additions & 28 deletions Semver.Test/UnbrokenSemVersionRangeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,10 @@ public void MinReleaseVersionIsZero()
}

[Fact]
public void MaxVersionIsIntMax()
{
Assert.Equal(new SemVersion(int.MaxValue, int.MaxValue, int.MaxValue), SemVersion.Max);
}

[Fact]
public void EmptyIsMaximallyEmpty()
public void EmptyIsLessThanMin()
{
var empty = UnbrokenSemVersionRange.Empty;
Assert.Equal(SemVersion.Max, empty.Start);
Assert.Null(empty.Start);
Assert.False(empty.StartInclusive, "Start Inclusive");
Assert.Equal(SemVersion.Min, empty.End);
Assert.False(empty.EndInclusive, "End Inclusive");
Expand Down Expand Up @@ -67,8 +61,8 @@ public void AllReleaseProperties()
var allRelease = UnbrokenSemVersionRange.AllRelease;
Assert.Null(allRelease.Start);
Assert.False(allRelease.StartInclusive, "Start Inclusive");
Assert.Equal(SemVersion.Max, allRelease.End);
Assert.True(allRelease.EndInclusive, "End Inclusive");
Assert.Null(allRelease.End);
Assert.False(allRelease.EndInclusive, "End Inclusive");
Assert.False(allRelease.IncludeAllPrerelease, "Include All Prerelease");
}

Expand All @@ -86,8 +80,8 @@ public void AllProperties()
var all = UnbrokenSemVersionRange.All;
Assert.Null(all.Start);
Assert.False(all.StartInclusive, "Start Inclusive");
Assert.Equal(SemVersion.Max, all.End);
Assert.True(all.EndInclusive, "End Inclusive");
Assert.Null(all.End);
Assert.False(all.EndInclusive, "End Inclusive");
Assert.True(all.IncludeAllPrerelease, "Include All Prerelease");
}

Expand Down Expand Up @@ -935,13 +929,6 @@ public void ExclusivePrereleaseContains(string version, bool expected)
Assert.Equal(expected, range.Contains(semVersion));
}

[Fact]
public void GreaterThanMaxVersionEmpty()
{
var range = UnbrokenSemVersionRange.GreaterThan(SemVersion.Max);
Assert.Same(UnbrokenSemVersionRange.Empty, range);
}

[Fact]
public void LessThanMinReleaseVersionEmpty()
{
Expand Down Expand Up @@ -993,15 +980,6 @@ public void ExclusiveEmpty()
Assert.Equal(UnbrokenSemVersionRange.Empty, range);
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void ExclusiveAtMaxEmpty(bool includeAllPrerelease)
{
var range = UnbrokenSemVersionRange.Exclusive(SemVersion.Max, SemVersion.Max, includeAllPrerelease);
Assert.Same(UnbrokenSemVersionRange.Empty, range);
}

[Fact]
public void ContainsNullVersion()
{
Expand Down
5 changes: 3 additions & 2 deletions Semver/Parsing/NpmRangeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ private static bool TrySplitOnHyphenRangeSeparator(
switch (@operator)
{
case StandardOperator.GreaterThan:
return GreaterThan(includeAllPrerelease, ex, ref leftBound, versionSegment, semver, wildcardVersion);
return GreaterThan(includeAllPrerelease, ex, ref leftBound, ref rightBound, versionSegment, semver, wildcardVersion);
case StandardOperator.GreaterThanOrEqual:
WildcardLowerBound(includeAllPrerelease, ref leftBound, semver, wildcardVersion);
return null;
Expand Down Expand Up @@ -319,6 +319,7 @@ private static bool TrySplitOnHyphenRangeSeparator(
bool includeAllPrerelease,
Exception? ex,
ref LeftBoundedRange leftBound,
ref RightBoundedRange rightBound,
StringSegment versionSegment,
SemVersion semver,
WildcardVersion wildcardVersion)
Expand All @@ -330,7 +331,7 @@ private static bool TrySplitOnHyphenRangeSeparator(
{
case WildcardVersion.MajorMinorPatchWildcard:
// No version matches
leftBound = leftBound.Max(new LeftBoundedRange(SemVersion.Max, false));
rightBound = new RightBoundedRange(SemVersion.Min, false);
return null;
case WildcardVersion.MinorPatchWildcard:
{
Expand Down
2 changes: 2 additions & 0 deletions Semver/PublicAPI/net5.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ Semver.SemVersion.WithMajor(System.Numerics.BigInteger major) -> Semver.SemVersi
Semver.SemVersion.WithMinor(System.Numerics.BigInteger minor) -> Semver.SemVersion!
Semver.SemVersion.WithParsedFrom(System.Numerics.BigInteger? major = null, System.Numerics.BigInteger? minor = null, System.Numerics.BigInteger? patch = null, string? prerelease = null, string? metadata = null, bool allowLeadingZeros = false) -> Semver.SemVersion!
Semver.SemVersion.WithPatch(System.Numerics.BigInteger patch) -> Semver.SemVersion!
*REMOVED*Semver.UnbrokenSemVersionRange.End.get -> Semver.SemVersion!
Semver.UnbrokenSemVersionRange.End.get -> Semver.SemVersion?
2 changes: 2 additions & 0 deletions Semver/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ Semver.SemVersion.WithMajor(System.Numerics.BigInteger major) -> Semver.SemVersi
Semver.SemVersion.WithMinor(System.Numerics.BigInteger minor) -> Semver.SemVersion!
Semver.SemVersion.WithParsedFrom(System.Numerics.BigInteger? major = null, System.Numerics.BigInteger? minor = null, System.Numerics.BigInteger? patch = null, string? prerelease = null, string? metadata = null, bool allowLeadingZeros = false) -> Semver.SemVersion!
Semver.SemVersion.WithPatch(System.Numerics.BigInteger patch) -> Semver.SemVersion!
*REMOVED*Semver.UnbrokenSemVersionRange.End.get -> Semver.SemVersion!
Semver.UnbrokenSemVersionRange.End.get -> Semver.SemVersion?
2 changes: 2 additions & 0 deletions Semver/PublicAPI/netstandard2.1/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ Semver.SemVersion.WithMajor(System.Numerics.BigInteger major) -> Semver.SemVersi
Semver.SemVersion.WithMinor(System.Numerics.BigInteger minor) -> Semver.SemVersion!
Semver.SemVersion.WithParsedFrom(System.Numerics.BigInteger? major = null, System.Numerics.BigInteger? minor = null, System.Numerics.BigInteger? patch = null, string? prerelease = null, string? metadata = null, bool allowLeadingZeros = false) -> Semver.SemVersion!
Semver.SemVersion.WithPatch(System.Numerics.BigInteger patch) -> Semver.SemVersion!
*REMOVED*Semver.UnbrokenSemVersionRange.End.get -> Semver.SemVersion!
Semver.UnbrokenSemVersionRange.End.get -> Semver.SemVersion?
24 changes: 7 additions & 17 deletions Semver/Ranges/LeftBoundedRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,16 @@ public LeftBoundedRange(SemVersion? version, bool inclusive)

public bool Contains(SemVersion version)
{
DebugChecks.IsNotNull(version, nameof(version));
var comparison = SemVersion.ComparePrecedence(Version, version);
return Inclusive ? comparison <= 0 : comparison < 0;
}

public LeftBoundedRange Min(LeftBoundedRange other)
{
var comparison = SemVersion.ComparePrecedence(Version, other.Version);
if (comparison == 0)
// If the versions are equal, then inclusive will be min
return new LeftBoundedRange(Version, Inclusive || other.Inclusive);
return comparison < 0 ? this : other;
}
public LeftBoundedRange Min(LeftBoundedRange other)
=> CompareTo(other) <= 0 ? this : other;

public LeftBoundedRange Max(LeftBoundedRange other)
{
var comparison = SemVersion.ComparePrecedence(Version, other.Version);
if (comparison == 0)
// If the versions are equal, then non-inclusive will be max
return new LeftBoundedRange(Version, Inclusive && other.Inclusive);
return comparison < 0 ? other : this;
}
public LeftBoundedRange Max(LeftBoundedRange other)
=> CompareTo(other) >= 0 ? this : other;

#region Equality
public bool Equals(LeftBoundedRange other)
Expand All @@ -85,7 +74,8 @@ public override int GetHashCode()

public int CompareTo(RightBoundedRange other)
{
var comparison = SemVersion.PrecedenceComparer.Compare(Version!, other.Version);
if(other.Version is null) return -1;
var comparison = PrecedenceComparer.Instance.Compare(Version!, other.Version);
if (comparison != 0) return comparison;
return Inclusive && other.Inclusive ? 0 : 1;
}
Expand Down
63 changes: 35 additions & 28 deletions Semver/Ranges/RightBoundedRange.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,43 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Semver.Comparers;
using Semver.Utility;

namespace Semver.Ranges
{
/// <summary>
/// A range of versions that is bounded only on the right. That is a range defined by some version
/// <c>x</c> such that <c>v &lt; x</c> or <c>v &lt;= x</c> depending on whether it is inclusive.
/// A right-bounded range forms the upper limit for a version range.
/// A range of versions that is bounded only on the right. That is a range defined by some
/// version <c>x</c> such that <c>v &lt; x</c> or <c>v &lt;= x</c> depending on whether it is
/// inclusive. A right-bounded range forms the upper limit for a version range.
/// </summary>
/// <remarks>An "unbounded" right-bounded range is represented by an inclusive upper bound of
/// <see cref="SemVersion.Max"/>.</remarks>
/// <see langword="null"/> since there is no maximum <see cref="SemVersion"/>. This requires
/// special checking for comparison.</remarks>
[StructLayout(LayoutKind.Auto)]
internal readonly struct RightBoundedRange : IEquatable<RightBoundedRange>
{
public static readonly RightBoundedRange Unbounded
= new RightBoundedRange(SemVersion.Max, true);
= new RightBoundedRange(null, false);

public RightBoundedRange(SemVersion version, bool inclusive)
public RightBoundedRange(SemVersion? version, bool inclusive)
{
DebugChecks.IsNotNull(version, nameof(version));
#if DEBUG
// dotcover disable
if (version is null && inclusive)
throw new ArgumentException("DEBUG: Cannot be inclusive of end without end value.",
nameof(inclusive));
// dotcover enable
#endif
DebugChecks.NoMetadata(version, nameof(version));

Version = version;
Inclusive = inclusive;
}

public SemVersion Version { get; }
public SemVersion? Version { get; }

[MemberNotNullWhen(true, "Version")]
public bool Inclusive { get; }

/// <summary>
Expand All @@ -37,31 +47,21 @@ public RightBoundedRange(SemVersion version, bool inclusive)
/// A non-inclusive bound of X.Y.Z-0 doesn't actually include any prerelease versions.
/// </remarks>
public bool IncludesPrerelease
=> Version.IsPrerelease && !(!Inclusive && Version.PrereleaseIsZero);
=> Version?.IsPrerelease == true && !(!Inclusive && Version.PrereleaseIsZero);

public bool Contains(SemVersion version)
{
DebugChecks.IsNotNull(version, nameof(version));
if (Version is null) return true;
var comparison = SemVersion.ComparePrecedence(version, Version);
return Inclusive ? comparison <= 0 : comparison < 0;
}

public RightBoundedRange Min(RightBoundedRange other)
{
var comparison = SemVersion.ComparePrecedence(Version, other.Version);
if (comparison == 0)
// If the versions are equal, then non-inclusive will be min
return new RightBoundedRange(Version, Inclusive && other.Inclusive);
return comparison < 0 ? this : other;
}
=> CompareTo(other) <= 0 ? this : other;

public RightBoundedRange Max(RightBoundedRange other)
{
var comparison = SemVersion.ComparePrecedence(Version, other.Version);
if (comparison == 0)
// If the versions are equal, then inclusive will be max
return new RightBoundedRange(Version, Inclusive || other.Inclusive);
return comparison < 0 ? other : this;
}
public RightBoundedRange Max(RightBoundedRange other)
=> CompareTo(other) >= 0 ? this : other;

#region Equality
public bool Equals(RightBoundedRange other)
Expand All @@ -82,11 +82,18 @@ public override int GetHashCode()

public int CompareTo(RightBoundedRange other)
{
var comparison = PrecedenceComparer.Instance.Compare(Version, other.Version);
if (comparison != 0) return comparison;
return Inclusive.CompareTo(other.Inclusive);
switch (Version, other.Version)
{
case (null,null): return 0;
case (null, _): return 1;
case (_, null): return -1;
default:
var comparison = PrecedenceComparer.Instance.Compare(Version!, other.Version!);
if (comparison != 0) return comparison;
return Inclusive.CompareTo(other.Inclusive);
}
}

public override string ToString() => (Inclusive ? "<=" : "<") + Version;
public override string ToString() => (Inclusive ? "<=" : "<") + (Version?.ToString() ?? "null");
}
}
3 changes: 1 addition & 2 deletions Semver/SemVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public sealed class SemVersion : IEquatable<SemVersion>, ISerializable
{
internal static readonly SemVersion Min = new SemVersion(0, 0, 0, new[] { new PrereleaseIdentifier(0) });
internal static readonly SemVersion MinRelease = new SemVersion(0, 0, 0);
internal static readonly SemVersion Max = new SemVersion(int.MaxValue, int.MaxValue, int.MaxValue);

internal const string InvalidSemVersionStylesMessage = "An invalid SemVersionStyles value was used.";
private const string InvalidMajorVersionMessage = "Major version must be greater than or equal to zero.";
Expand Down Expand Up @@ -1075,7 +1074,7 @@ public bool PrecedenceEquals(SemVersion? other)
public static bool PrecedenceEquals(SemVersion? left, SemVersion? right)
=> PrecedenceComparer.Compare(left!, right!) == 0;

internal bool MajorMinorPatchEquals(SemVersion? other)
internal bool MajorMinorPatchEquals([NotNullWhen(true)] SemVersion? other)
{
if (other is null) return false;

Expand Down
Loading

0 comments on commit 52cbb15

Please sign in to comment.