From f14ccbdff0d367aee4839753af202813b0ba22db Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Wed, 22 Jan 2020 23:17:32 -0800 Subject: [PATCH 01/12] Add *-*, support for floating both stable and prereleases in the same version range --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 112 ++- .../NuGetVersionFloatBehavior.cs | 19 +- .../NuGet.Versioning/VersionRangeFactory.cs | 19 +- .../NuGet.Versioning/VersionRangeFormatter.cs | 1 - .../FloatingRangeTests.cs | 732 +++++++++++++++++- 5 files changed, 858 insertions(+), 25 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index 6c8763121b0..ac7469a296c 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -99,7 +99,31 @@ public bool Satisfies(NuGetVersion version) if (_minVersion != null) { // everything beyond this point requires a version - if (_floatBehavior == NuGetVersionFloatBehavior.Prerelease) + if (_floatBehavior == NuGetVersionFloatBehavior.PrereleaseRevision) + { + // allow the stable version to match + return _minVersion.Major == version.Major + && _minVersion.Minor == version.Minor + && _minVersion.Patch == version.Patch + && ((version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) + || !version.IsPrerelease); + } + else if (_floatBehavior == NuGetVersionFloatBehavior.PrereleasePatch) + { + // allow the stable version to match + return _minVersion.Major == version.Major + && _minVersion.Minor == version.Minor + && ((version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) + || !version.IsPrerelease); + } + else if (FloatBehavior == NuGetVersionFloatBehavior.PrereleaseMinor) + { + // allow the stable version to match + return _minVersion.Major == version.Major + && ((version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) + || !version.IsPrerelease); + } + else if (_floatBehavior == NuGetVersionFloatBehavior.Prerelease) { // allow the stable version to match return VersionComparer.Version.Equals(_minVersion, version) @@ -134,9 +158,7 @@ public bool Satisfies(NuGetVersion version) /// public static FloatRange Parse(string versionString) { - FloatRange range = null; - - TryParse(versionString, out range); + TryParse(versionString, out FloatRange range); return range; } @@ -150,23 +172,78 @@ public static bool TryParse(string versionString, out FloatRange range) if (versionString != null) { - var starPos = versionString.IndexOf('*'); - - var actualVersion = versionString; + var firstStarPosition = versionString.IndexOf('*'); + var lastStarPosition = versionString.LastIndexOf('*'); string releasePrefix = null; if (versionString.Length == 1 - && starPos == 0) + && firstStarPosition == 0) { range = new FloatRange(NuGetVersionFloatBehavior.Major, new NuGetVersion(new Version(0, 0))); } - // * must appear as the last char in the string. + else if (versionString.Length == 3 + && firstStarPosition == 0 && lastStarPosition == 2 && versionString[1] == '-') + { + range = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest, new NuGetVersion("0.0.0-0")); + } + else if (firstStarPosition != lastStarPosition && lastStarPosition != -1 && versionString.IndexOf('+') == -1) + { + var behavior = NuGetVersionFloatBehavior.None; + // 2 *s are only allowed in prerelease versions. + var dashPosition = versionString.IndexOf('-'); + string actualVersion = null; + + if (dashPosition != -1 && + lastStarPosition == versionString.Length - 1 && // Last star is at the end of the full string + firstStarPosition == (dashPosition-1) // First star is right before the first dash. + ) + { + // Get the stable part. + var stablePart = versionString.Substring(0, dashPosition - 1); // Get the part without the * + stablePart += "0"; + var versionParts = stablePart.Split('.').Length; + if (versionParts == 2) + { + behavior = NuGetVersionFloatBehavior.PrereleaseMinor; + } + else if (versionParts == 3) + { + behavior = NuGetVersionFloatBehavior.PrereleasePatch; + } + else if (versionParts == 4) + { + behavior = NuGetVersionFloatBehavior.PrereleaseRevision; + } + + var releaseVersion = versionString.Substring(dashPosition + 1); + releasePrefix = releaseVersion.Substring(0, releaseVersion.Length - 1); + var releasePart = releasePrefix; + // For numeric labels 0 is the lowest. For alpha-numeric - is the lowest. + if (releasePrefix.Length == 0 || releasePrefix.EndsWith(".")) + { + // 1.0.0-* scenario, an empty label is not a valid version. + releasePart += "0"; + } + else if (releasePrefix.EndsWith("-")) + { + // Append a dash to allow floating on the next character. + releasePart += "-"; + } + actualVersion = stablePart + "-" + releasePart; + } + + if (NuGetVersion.TryParse(actualVersion, out NuGetVersion version)) + { + range = new FloatRange(behavior, version, releasePrefix); + } + } + // A single * can only appear as the last char in the string. // * cannot appear in the metadata section after the + - else if (starPos == versionString.Length - 1 && versionString.IndexOf('+') == -1) + else if (lastStarPosition == versionString.Length - 1 && versionString.IndexOf('+') == -1) { var behavior = NuGetVersionFloatBehavior.None; - actualVersion = versionString.Substring(0, versionString.Length - 1); + var actualVersion = versionString.Substring(0, versionString.Length - 1); if (versionString.IndexOf('-') == -1) { @@ -214,7 +291,6 @@ public static bool TryParse(string versionString, out FloatRange range) NuGetVersion version = null; if (NuGetVersion.TryParse(actualVersion, out version)) { - // there is no float range for this version range = new FloatRange(behavior, version, releasePrefix); } } @@ -259,9 +335,17 @@ public override string ToString() case NuGetVersionFloatBehavior.Major: result = "*"; break; + case NuGetVersionFloatBehavior.PrereleaseRevision: + result = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}.*-{3}*", MinVersion.Major, MinVersion.Minor, MinVersion.Patch, _releasePrefix); + break; + case NuGetVersionFloatBehavior.PrereleasePatch: + result = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.*-{2}*", MinVersion.Major, MinVersion.Minor, _releasePrefix); + break; + case NuGetVersionFloatBehavior.PrereleaseMinor: + result = string.Format(CultureInfo.InvariantCulture, "{0}.*-{1}*", MinVersion.Major, _releasePrefix); + break; case NuGetVersionFloatBehavior.AbsoluteLatest: - // TODO: how should this be denoted? - result = string.Empty; + result = "*-*"; break; default: break; diff --git a/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs b/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs index 12527616d2d..4f12d945c47 100644 --- a/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs +++ b/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. namespace NuGet.Versioning @@ -41,6 +41,21 @@ public enum NuGetVersionFloatBehavior /// /// Float major and pre-release /// - AbsoluteLatest + AbsoluteLatest, + + /// + /// Float revision and pre-release x.y.z.*-* + /// + PrereleaseRevision, + + /// + /// Float patch and pre-release x.y.*-* + /// + PrereleasePatch, + + /// + /// Float minor and pre-release x.*-* + /// + PrereleaseMinor, } } diff --git a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs index c3117f92f6e..cb01737a78f 100644 --- a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs +++ b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs @@ -70,7 +70,7 @@ public static VersionRange Parse(string value, bool allowFloating) if (!TryParse(value, allowFloating, out versionInfo)) { throw new ArgumentException( - String.Format(CultureInfo.CurrentCulture, + string.Format(CultureInfo.CurrentCulture, Resources.Invalidvalue, value)); } @@ -101,7 +101,7 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v var charArray = trimmedValue.ToCharArray(); - // * is the only range below 3 chars + // * is the only 1 char range if (allowFloating && charArray.Length == 1 && charArray[0] == '*') @@ -116,6 +116,17 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v return false; } + // Special case *-* + if (allowFloating + && charArray.Length == 3 + && charArray[0] == '*' + && charArray[0] == '-' + && charArray[0] == '*') + { + versionRange = new VersionRange(new NuGetVersion(0, 0, 0, releaseLabel: "0"), true, null, true, FloatRange.Parse(trimmedValue), originalString: value); + return true; + } + string minVersionString = null; string maxVersionString = null; var isMinInclusive = false; @@ -195,7 +206,7 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v minVersionString = trimmedValue; } - if (!String.IsNullOrWhiteSpace(minVersionString)) + if (!string.IsNullOrWhiteSpace(minVersionString)) { // parse the min version string if (allowFloating && minVersionString.Contains("*")) @@ -224,7 +235,7 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v } // parse the max version string, the max cannot float - if (!String.IsNullOrWhiteSpace(maxVersionString)) + if (!string.IsNullOrWhiteSpace(maxVersionString)) { if (!NuGetVersion.TryParse(maxVersionString, out maxVersion)) { diff --git a/src/NuGet.Core/NuGet.Versioning/VersionRangeFormatter.cs b/src/NuGet.Core/NuGet.Versioning/VersionRangeFormatter.cs index 962bce978a4..aca6eb3006d 100644 --- a/src/NuGet.Core/NuGet.Versioning/VersionRangeFormatter.cs +++ b/src/NuGet.Core/NuGet.Versioning/VersionRangeFormatter.cs @@ -159,7 +159,6 @@ private string GetShortString(VersionRange range) /// private string GetNormalizedString(VersionRange range) { - // TODO: write out the float version var sb = new StringBuilder(); sb.Append(range.HasLowerBound && range.IsMinInclusive ? '[' : '('); diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs index c6ac470916c..096fc1eb580 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; @@ -8,6 +8,24 @@ namespace NuGet.Versioning.Test { public class FloatingRangeTests { + [Fact] + public void FloatRange_Float() + { + var range = new VersionRange(NuGetVersion.Parse("2.2.0"), true, null, false, new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest)); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0-pre"), + }; + + Assert.Equal(NuGetVersion.Parse("3.0.0-pre"), range.FindBestMatch(versions)); + } + + [Fact] public void FloatRange_OutsideOfRange() { @@ -328,17 +346,723 @@ public void FloatingRange_ToStringMinor() Assert.Equal("[1.*, )", range.ToNormalizedString()); } - [Fact] - public void FloatingRange_FloatMetadata_Invalid() + [Theory] + [InlineData("1.0.0+*")] + [InlineData("1.0.**")] + [InlineData("1.*.0")] + [InlineData("1.0.*-*bla")] + [InlineData("1.0.*-*bla+*")] + [InlineData("**")] + [InlineData("1.0.0-preview.*+blabla")] + [InlineData("1.0.*--")] + [InlineData("1.0.*-alpha*+")] + [InlineData("1.0.*-")] + public void FloatingRange_Parse_Invalid(string floatVersionString) { // Arrange FloatRange range; // Act - var valid = FloatRange.TryParse("1.0.0+*", out range); + var valid = FloatRange.TryParse(floatVersionString, out range); // Assert Assert.False(valid); } + + [Theory] + [InlineData("1.0.0-preview.*")] + [InlineData("1.0.*-bla*")] + [InlineData("1.0.*-*")] + [InlineData("1.0.*-preview.1.*")] + [InlineData("1.0.*-preview.1*")] + [InlineData("1.0.0--")] + [InlineData("1.0.0-bla*")] + [InlineData("1.0.*--*")] + [InlineData("1.0.0--*")] + public void FloatingRange_Parse_Valid(string floatVersionString) + { + // Arrange + FloatRange range; + + // Act + var valid = FloatRange.TryParse(floatVersionString, out range); + + // Assert + Assert.True(valid); + } + + [Fact] + public void FloatingRange_ToStringRevPrefix() + { + var range = VersionRange.Parse("1.1.1.*-*"); + + Assert.Equal("[1.1.1.*-*, )", range.ToNormalizedString()); + } + + [Fact] + public void FloatingRange_ToStringPatchPrefix() + { + var range = VersionRange.Parse("1.1.*-*"); + + Assert.Equal("[1.1.*-*, )", range.ToNormalizedString()); + } + + [Fact] + public void FloatingRange_ToStringMinorPrefix() + { + var range = VersionRange.Parse("1.*-*"); + + Assert.Equal("[1.*-*, )", range.ToNormalizedString()); + } + + [Fact] + public void FloatingRange_ToStringAbsoluteLatest() + { + var range = VersionRange.Parse("*-*"); + + Assert.Equal("[*-*, )", range.ToNormalizedString()); + Assert.Equal("0.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal("0.0.0-0", range.Float.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.Float.FloatBehavior); + } + + [Fact] + public void FloatingRange_FloatPrereleaseRev() + { + var range = FloatRange.Parse("1.0.0.*-*"); + + Assert.Equal("1.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleaseRevision, range.FloatBehavior); + } + + [Fact] + public void FloatingRange_FloatPrereleasePatch() + { + var range = FloatRange.Parse("1.0.*-*"); + + Assert.Equal("1.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleasePatch, range.FloatBehavior); + } + + [Fact] + public void FloatingRange_FloatPrereleaseMinor() + { + var range = FloatRange.Parse("1.*-*"); + + Assert.Equal("1.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMinor, range.FloatBehavior); + } + + [Fact] + public void FloatingRange_FloatAbsoluteLatest() + { + var range = FloatRange.Parse("*-*"); + + Assert.Equal("0.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.FloatBehavior); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.0.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_NotMatchingPrefix_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.0.*-beta*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange_Lower() + { + var range = VersionRange.Parse("[1.1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.8.0"), + NuGetVersion.Parse("0.9.0"), + NuGetVersion.Parse("1.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange_Higher() + { + var range = VersionRange.Parse("[1.1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_OnlyMatching() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.1-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_BestMatching() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_BestMatchingStable() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1.9"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1.9", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_BestMatchingFloating() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1.8"), + NuGetVersion.Parse("1.0.1.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_NotMatchingPrefix_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.*-beta*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_OutsideOfRange_Lower() + { + var range = VersionRange.Parse("[1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.8.0"), + NuGetVersion.Parse("0.9.0"), + NuGetVersion.Parse("1.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_OutsideOfRange_Higher() + { + var range = VersionRange.Parse("[1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_OnlyMatching() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_BestMatching() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_BestMatchingStable() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.0.9"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.9", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_BestMatchingPrerelease() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.8"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_NotMatchingPrefix_OutsideOfRange() + { + var range = VersionRange.Parse("[1.*-beta*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_OutsideOfRange_Lower() + { + var range = VersionRange.Parse("[1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.8.0"), + NuGetVersion.Parse("0.9.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_OutsideOfRange_Higher() + { + var range = VersionRange.Parse("[1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_OnlyMatching() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_BestMatching() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.1.0-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_BestMatchingStable() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_BestMatchingPrerelease() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("1.99.1-alpha1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.99.1-alpha1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseRevision_RangeOpen() + { + var range = VersionRange.Parse("[1.0.0.*-*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.0.1-alpha.1"), + NuGetVersion.Parse("1.0.1-alpha.1"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.0.0.1-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleasePatch_RangeOpen() + { + var range = VersionRange.Parse("[1.0.*-*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1-beta.2") + }; + + Assert.Equal("1.0.1-beta.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMinor_RangeOpen() + { + var range = VersionRange.Parse("[1.*-*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0-alpha.2"), + NuGetVersion.Parse("2.0.0-alpha.2"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.9.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMinor_IgnoresPartialPrereleaseMatches() + { + var range = VersionRange.Parse("[1.*-alpha*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0"), + NuGetVersion.Parse("1.20.0-alph.3"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.9.0", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMinor_NotMatching_SelectsFirstInRange() + { + var range = VersionRange.Parse("[1.*-alpha*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alph3.2"), + NuGetVersion.Parse("1.20.0-alph.3"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.20.0-alph.3", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1.1*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingRevision_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1.1*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPatch_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingMinor_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrerelease_WithExtraDashes() + { + var range = VersionRange.Parse("[1.0.0--*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.0.0--alpha"), + NuGetVersion.Parse("1.0.0--beta"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.0.0--beta", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_WithExtraDashes() + { + var range = VersionRange.Parse("[1.*--*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.0.0--alpha"), + NuGetVersion.Parse("1.0.0--beta"), + NuGetVersion.Parse("1.9.0--beta"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.9.0--beta", range.FindBestMatch(versions).ToNormalizedString()); + } } } From bedcaa63f3df9ffae0030c49a1e5908ff8226d89 Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Mon, 27 Jan 2020 21:24:34 -0800 Subject: [PATCH 02/12] fix bug --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 7 +---- .../FloatingRangeTests.cs | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index ac7469a296c..43bff6b1738 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -218,17 +218,12 @@ public static bool TryParse(string versionString, out FloatRange range) var releaseVersion = versionString.Substring(dashPosition + 1); releasePrefix = releaseVersion.Substring(0, releaseVersion.Length - 1); var releasePart = releasePrefix; - // For numeric labels 0 is the lowest. For alpha-numeric - is the lowest. if (releasePrefix.Length == 0 || releasePrefix.EndsWith(".")) { // 1.0.0-* scenario, an empty label is not a valid version. releasePart += "0"; } - else if (releasePrefix.EndsWith("-")) - { - // Append a dash to allow floating on the next character. - releasePart += "-"; - } + actualVersion = stablePart + "-" + releasePart; } diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs index 096fc1eb580..74a6907797a 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs @@ -1064,5 +1064,31 @@ public void FloatRange_FloatingPrereleaseMinor_WithExtraDashes() Assert.Equal("1.9.0--beta", range.FindBestMatch(versions).ToNormalizedString()); } + + + [Theory] + [InlineData("*", "0.0.0")] + [InlineData("*-*", "0.0.0-0")] + [InlineData("1.*", "1.0.0")] + [InlineData("1.1.*", "1.1.0")] + [InlineData("1.1.*-*", "1.1.0-0")] + [InlineData("1.1.1-*", "1.1.1-0")] + [InlineData("1.1.1-beta*", "1.1.1-beta")] + [InlineData("1.1.1-1*", "1.1.1-1")] + [InlineData("1.1.*-beta*", "1.1.0-beta")] + [InlineData("1.1.*-1*", "1.1.0-1")] + [InlineData("1.0.0-beta.1*", "1.0.0-beta.1")] + [InlineData("1.0.*-beta.1*", "1.0.0-beta.1")] + [InlineData("1.0.0-b-*", "1.0.0-b-")] + [InlineData("1.0.*-b-*", "1.0.0-b-")] + [InlineData("1.1.0-beta.*", "1.1.0-beta.0")] + [InlineData("1.1.*-beta.*", "1.1.0-beta.0")] + + public void FloatRange_ParsesCorrectMinVersion(string versionRange, string normalizedMinVersion) + { + var range = FloatRange.Parse(versionRange); + + Assert.Equal(normalizedMinVersion, range.MinVersion.ToNormalizedString()); + } } } From 4978d188ad17f4c2e31a612a9247abf2c9cc75fb Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Tue, 28 Jan 2020 23:08:28 -0800 Subject: [PATCH 03/12] fix prerelease major floating bug --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 36 +++-- .../NuGetVersionFloatBehavior.cs | 8 +- .../NuGet.Versioning/VersionRange.cs | 4 + .../NuGet.Versioning/VersionRangeFactory.cs | 2 +- .../FloatingRangeTests.cs | 144 ++++++++++++------ .../VersionRangeFloatParsingTests.cs | 51 ++++++- 6 files changed, 184 insertions(+), 61 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index 43bff6b1738..784902072fc 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -123,6 +123,12 @@ public bool Satisfies(NuGetVersion version) && ((version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) || !version.IsPrerelease); } + else if (FloatBehavior == NuGetVersionFloatBehavior.PrereleaseMajor) + { + // allow the stable version to match + return (version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) + || !version.IsPrerelease; + } else if (_floatBehavior == NuGetVersionFloatBehavior.Prerelease) { // allow the stable version to match @@ -184,7 +190,7 @@ public static bool TryParse(string versionString, out FloatRange range) else if (versionString.Length == 3 && firstStarPosition == 0 && lastStarPosition == 2 && versionString[1] == '-') { - range = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest, new NuGetVersion("0.0.0-0")); + range = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest, new NuGetVersion("0.0.0-0"), releasePrefix: string.Empty); } else if (firstStarPosition != lastStarPosition && lastStarPosition != -1 && versionString.IndexOf('+') == -1) { @@ -202,17 +208,22 @@ public static bool TryParse(string versionString, out FloatRange range) var stablePart = versionString.Substring(0, dashPosition - 1); // Get the part without the * stablePart += "0"; var versionParts = stablePart.Split('.').Length; - if (versionParts == 2) + switch (versionParts) { - behavior = NuGetVersionFloatBehavior.PrereleaseMinor; - } - else if (versionParts == 3) - { - behavior = NuGetVersionFloatBehavior.PrereleasePatch; - } - else if (versionParts == 4) - { - behavior = NuGetVersionFloatBehavior.PrereleaseRevision; + case 1: + behavior = NuGetVersionFloatBehavior.PrereleaseMajor; + break; + case 2: + behavior = NuGetVersionFloatBehavior.PrereleaseMinor; + break; + case 3: + behavior = NuGetVersionFloatBehavior.PrereleasePatch; + break; + case 4: + behavior = NuGetVersionFloatBehavior.PrereleaseRevision; + break; + default: + break; } var releaseVersion = versionString.Substring(dashPosition + 1); @@ -339,6 +350,9 @@ public override string ToString() case NuGetVersionFloatBehavior.PrereleaseMinor: result = string.Format(CultureInfo.InvariantCulture, "{0}.*-{1}*", MinVersion.Major, _releasePrefix); break; + case NuGetVersionFloatBehavior.PrereleaseMajor: + result = string.Format(CultureInfo.InvariantCulture, "*-{1}*", MinVersion.Major, _releasePrefix); + break; case NuGetVersionFloatBehavior.AbsoluteLatest: result = "*-*"; break; diff --git a/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs b/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs index 4f12d945c47..ce064d3b358 100644 --- a/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs +++ b/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs @@ -39,7 +39,7 @@ public enum NuGetVersionFloatBehavior Major, /// - /// Float major and pre-release + /// Float major and pre-release, *-* /// AbsoluteLatest, @@ -57,5 +57,11 @@ public enum NuGetVersionFloatBehavior /// Float minor and pre-release x.*-* /// PrereleaseMinor, + + /// + /// Float major and prerelease, but only with partial prerelease *-rc.*. + /// *-* is captured by + /// + PrereleaseMajor, } } diff --git a/src/NuGet.Core/NuGet.Versioning/VersionRange.cs b/src/NuGet.Core/NuGet.Versioning/VersionRange.cs index 18882a2a0df..703ffa93bbc 100644 --- a/src/NuGet.Core/NuGet.Versioning/VersionRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/VersionRange.cs @@ -209,6 +209,10 @@ public bool IsBetter(NuGetVersion current, NuGetVersion considering) if (!HasPrereleaseBounds && considering.IsPrerelease && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.Prerelease + && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.PrereleaseMajor + && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.PrereleaseMinor + && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.PrereleasePatch + && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.PrereleaseRevision && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.AbsoluteLatest) { return false; diff --git a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs index cb01737a78f..ed7d455041d 100644 --- a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs +++ b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs @@ -123,7 +123,7 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v && charArray[0] == '-' && charArray[0] == '*') { - versionRange = new VersionRange(new NuGetVersion(0, 0, 0, releaseLabel: "0"), true, null, true, FloatRange.Parse(trimmedValue), originalString: value); + versionRange = new VersionRange(new NuGetVersion("0.0.0-0"), true, null, true, FloatRange.Parse(trimmedValue), originalString: value); return true; } diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs index 74a6907797a..260d8db710c 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs @@ -8,24 +8,6 @@ namespace NuGet.Versioning.Test { public class FloatingRangeTests { - [Fact] - public void FloatRange_Float() - { - var range = new VersionRange(NuGetVersion.Parse("2.2.0"), true, null, false, new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest)); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0-pre"), - }; - - Assert.Equal(NuGetVersion.Parse("3.0.0-pre"), range.FindBestMatch(versions)); - } - - [Fact] public void FloatRange_OutsideOfRange() { @@ -274,7 +256,6 @@ public void FloatingRange_FloatPrereleaseBest() [Fact] public void FloatingRange_FloatPrereleaseNotFoundBest() { - // "1.0.0-*" var range = VersionRange.Parse("1.0.0-*"); var versions = new List() @@ -426,6 +407,17 @@ public void FloatingRange_ToStringAbsoluteLatest() Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.Float.FloatBehavior); } + [Fact] + public void FloatingRange_ToStringPrereleaseMajor() + { + var range = VersionRange.Parse("*-rc.*"); + + Assert.Equal("[*-rc.*, )", range.ToNormalizedString()); + Assert.Equal("0.0.0-rc.0", range.MinVersion.ToNormalizedString()); + Assert.Equal("0.0.0-rc.0", range.Float.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMajor, range.Float.FloatBehavior); + } + [Fact] public void FloatingRange_FloatPrereleaseRev() { @@ -453,6 +445,15 @@ public void FloatingRange_FloatPrereleaseMinor() Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMinor, range.FloatBehavior); } + [Fact] + public void FloatingRange_FloatMajorPrerelease() + { + var range = FloatRange.Parse("*-rc.*"); + + Assert.Equal("0.0.0-rc.0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMajor, range.FloatBehavior); + } + [Fact] public void FloatingRange_FloatAbsoluteLatest() { @@ -462,6 +463,34 @@ public void FloatingRange_FloatAbsoluteLatest() Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.FloatBehavior); } + [Theory] + [InlineData("*", "0.0.0")] + [InlineData("*-*", "0.0.0-0")] + [InlineData("1.*", "1.0.0")] + [InlineData("1.1.*", "1.1.0")] + [InlineData("1.1.*-*", "1.1.0-0")] + [InlineData("1.1.1-*", "1.1.1-0")] + [InlineData("1.1.1-beta*", "1.1.1-beta")] + [InlineData("1.1.1-1*", "1.1.1-1")] + [InlineData("1.1.*-beta*", "1.1.0-beta")] + [InlineData("1.1.*-1*", "1.1.0-1")] + [InlineData("1.0.0-beta.1*", "1.0.0-beta.1")] + [InlineData("1.0.*-beta.1*", "1.0.0-beta.1")] + [InlineData("1.0.0-b-*", "1.0.0-b-")] + [InlineData("1.0.*-b-*", "1.0.0-b-")] + [InlineData("1.1.0-beta.*", "1.1.0-beta.0")] + [InlineData("1.1.*-beta.*", "1.1.0-beta.0")] + [InlineData("*-beta.*", "0.0.0-beta.0")] + + public void FloatRange_ParsesCorrectMinVersion(string versionRange, string normalizedMinVersion) + { + var range = FloatRange.Parse(versionRange); + + Assert.Equal(normalizedMinVersion, range.MinVersion.ToNormalizedString()); + } + + /// TODO NK - From here on below, the tests can probably be moved to VersionRangeFloatParsing_FindsBestMatch + [Fact] public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange() { @@ -950,6 +979,57 @@ public void FloatRange_PrereleaseMinor_NotMatching_SelectsFirstInRange() Assert.Equal("1.20.0-alph.3", range.FindBestMatch(versions).ToNormalizedString()); } + [Fact] + public void FloatRange_PrereleaseMajor_IgnoresPartialPrereleaseMatches() + { + var range = VersionRange.Parse("[*-alpha*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0"), + NuGetVersion.Parse("1.20.0-alph.3"), + }; + + Assert.Equal("1.9.0", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMajor_NotMatching_SelectsFirstInRange() + { + var range = VersionRange.Parse("[*-rc*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0-beta"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0-alpha.2"), + NuGetVersion.Parse("2.0.0-alpha.2"), + }; + + Assert.Equal("0.1.0-beta", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMajor_BestMatching() + { + var range = VersionRange.Parse("*-rc*"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.0"), + NuGetVersion.Parse("1.2.0-rc.1"), + NuGetVersion.Parse("1.2.0-rc.2"), + NuGetVersion.Parse("1.2.0-rc1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.0.0-beta.1") + }; + + Assert.Equal("2.0.0", range.FindBestMatch(versions).ToNormalizedString()); + } + [Fact] public void FloatRange_FloatingPrereleaseRevision_WithPartialMatch() { @@ -1064,31 +1144,5 @@ public void FloatRange_FloatingPrereleaseMinor_WithExtraDashes() Assert.Equal("1.9.0--beta", range.FindBestMatch(versions).ToNormalizedString()); } - - - [Theory] - [InlineData("*", "0.0.0")] - [InlineData("*-*", "0.0.0-0")] - [InlineData("1.*", "1.0.0")] - [InlineData("1.1.*", "1.1.0")] - [InlineData("1.1.*-*", "1.1.0-0")] - [InlineData("1.1.1-*", "1.1.1-0")] - [InlineData("1.1.1-beta*", "1.1.1-beta")] - [InlineData("1.1.1-1*", "1.1.1-1")] - [InlineData("1.1.*-beta*", "1.1.0-beta")] - [InlineData("1.1.*-1*", "1.1.0-1")] - [InlineData("1.0.0-beta.1*", "1.0.0-beta.1")] - [InlineData("1.0.*-beta.1*", "1.0.0-beta.1")] - [InlineData("1.0.0-b-*", "1.0.0-b-")] - [InlineData("1.0.*-b-*", "1.0.0-b-")] - [InlineData("1.1.0-beta.*", "1.1.0-beta.0")] - [InlineData("1.1.*-beta.*", "1.1.0-beta.0")] - - public void FloatRange_ParsesCorrectMinVersion(string versionRange, string normalizedMinVersion) - { - var range = FloatRange.Parse(versionRange); - - Assert.Equal(normalizedMinVersion, range.MinVersion.ToNormalizedString()); - } } } diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeFloatParsingTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeFloatParsingTests.cs index 20a9b529db4..29ab2e76398 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeFloatParsingTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeFloatParsingTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Linq; using Xunit; namespace NuGet.Versioning.Test @@ -23,6 +22,11 @@ public void VersionRangeFloatParsing_Prerelease() [InlineData("1.0.0--*", "1.0.0--")] [InlineData("1.0.0-a-*", "1.0.0-a-")] [InlineData("1.0.0-a.*", "1.0.0-a.0")] + [InlineData("1.*-*", "1.0.0-0")] + [InlineData("1.0.*-0*", "1.0.0-0")] + [InlineData("1.0.*--*", "1.0.0--")] + [InlineData("1.0.*-a-*", "1.0.0-a-")] + [InlineData("1.0.*-a.*", "1.0.0-a.0")] public void VersionRangeFloatParsing_PrereleaseWithNumericOnlyLabelVerifyMinVersion(string rangeString, string expected) { var range = VersionRange.Parse(rangeString); @@ -46,6 +50,9 @@ public void VersionRangeFloatParsing_PrereleaseWithNumericOnlyLabelVerifySatisfi [InlineData("1.0.0-a*", "1.0.0-a.0")] [InlineData("1.0.0-a*", "1.0.0-a-0")] [InlineData("1.0.0-a*", "1.0.0-a")] + [InlineData("1.0.*-a*", "1.0.0-a")] + [InlineData("1.*-a*", "1.0.0-a")] + [InlineData("*-a*", "1.0.0-a")] public void VersionRangeFloatParsing_VerifySatisfiesForFloatingRange(string rangeString, string version) { var range = VersionRange.Parse(rangeString); @@ -59,6 +66,21 @@ public void VersionRangeFloatParsing_VerifySatisfiesForFloatingRange(string rang [InlineData("1.0.0-a-*", "a-", "a-")] [InlineData("1.0.0-a.*", "a.0", "a.")] [InlineData("1.0.0-0*", "0", "0")] + [InlineData("1.0.*-0*", "0", "0")] + [InlineData("1.*-0*", "0", "0")] + [InlineData("*-0*", "0", "0")] + [InlineData("1.0.*-*", "0", "")] + [InlineData("1.*-*", "0", "")] + [InlineData("*-*", "0", "")] + [InlineData("1.0.*-a*", "a", "a")] + [InlineData("1.*-a*", "a", "a")] + [InlineData("*-a*", "a", "a")] + [InlineData("1.0.*-a-*", "a-", "a-")] + [InlineData("1.*-a-*", "a-", "a-")] + [InlineData("*-a-*", "a-", "a-")] + [InlineData("1.0.*-a.*", "a.0", "a.")] + [InlineData("1.*-a.*", "a.0", "a.")] + [InlineData("*-a.*", "a.0", "a.")] public void VersionRangeFloatParsing_VerifyReleaseLabels(string rangeString, string versionLabel, string originalLabel) { var range = VersionRange.Parse(rangeString); @@ -164,8 +186,16 @@ public void VersionRangeFloatParsing_FloatPrereleasePrefixSemVerLabelMix() [InlineData("1.*.0-beta-*")] [InlineData("1.*.0-beta")] [InlineData("1.0.0.0.*")] - //[InlineData("1.0.0*")] [InlineData("=1.0.*")] + [InlineData("1.0.0+*")] + [InlineData("1.0.**")] + [InlineData("1.0.*-*bla")] + [InlineData("1.0.*-*bla+*")] + [InlineData("**")] + [InlineData("1.0.0-preview.*+blabla")] + [InlineData("1.0.*--")] + [InlineData("1.0.*-alpha*+")] + [InlineData("1.0.*-")] public void VersionRangeFloatParsing_Invalid(string rangeString) { VersionRange range = null; @@ -185,6 +215,14 @@ public void VersionRangeFloatParsing_Invalid(string rangeString) [InlineData("[1.0.0-beta.*, 2.0.0)")] [InlineData("1.0.0-beta.*")] [InlineData("1.0.0-beta-*")] + [InlineData("1.0.*-bla*")] + [InlineData("1.0.*-*")] + [InlineData("1.0.*-preview.1.*")] + [InlineData("1.0.*-preview.1*")] + [InlineData("1.0.0--")] + [InlineData("1.0.0-bla*")] + [InlineData("1.0.*--*")] + [InlineData("1.0.0--*")] public void VersionRangeFloatParsing_Valid(string rangeString) { VersionRange range = null; @@ -218,13 +256,20 @@ public void VersionRangeFloatParsing_CorrectFloatRange(string rangeString) Assert.Equal(rangeString, range.Float.ToString()); } - [Theory] [InlineData("1.0.0;2.0.0", "*", "2.0.0")] [InlineData("1.0.0;2.0.0", "0.*", "1.0.0")] [InlineData("1.0.0;2.0.0", "[*, )", "2.0.0")] [InlineData("1.0.0;2.0.0;3.0.0", "(1.0.*, )", "2.0.0")] [InlineData("1.0.0;2.0.0;3.0.0", "(1.0.*, 2.0.0)", null)] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "*", "2.0.0")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "1.*", "1.1.0")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "1.2.0-*", "1.2.0-rc.2")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "*-*", "3.0.0-beta.1")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "1.*-*", "1.2.0-rc.2")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "*-rc.*", "2.0.0")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;1.2.0-rc1;2.0.0;3.0.0-beta.1", "1.*-rc*", "1.2.0-rc1")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;1.2.0-rc1;1.10.0;2.0.0;3.0.0-beta.1", "1.1*-*", "1.10.0")] public void VersionRangeFloatParsing_FindsBestMatch(string availableVersions, string declaredRange, string expectedVersion) { var range = VersionRange.Parse(declaredRange); From 88fbb11c06588cdcce2c658f71cecfc14d064e53 Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Wed, 22 Jan 2020 23:17:32 -0800 Subject: [PATCH 04/12] Add *-*, support for floating both stable and prereleases in the same version range --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 112 ++- .../NuGetVersionFloatBehavior.cs | 19 +- .../NuGet.Versioning/VersionRangeFactory.cs | 19 +- .../NuGet.Versioning/VersionRangeFormatter.cs | 1 - .../FloatingRangeTests.cs | 732 +++++++++++++++++- 5 files changed, 858 insertions(+), 25 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index 6c8763121b0..ac7469a296c 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -99,7 +99,31 @@ public bool Satisfies(NuGetVersion version) if (_minVersion != null) { // everything beyond this point requires a version - if (_floatBehavior == NuGetVersionFloatBehavior.Prerelease) + if (_floatBehavior == NuGetVersionFloatBehavior.PrereleaseRevision) + { + // allow the stable version to match + return _minVersion.Major == version.Major + && _minVersion.Minor == version.Minor + && _minVersion.Patch == version.Patch + && ((version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) + || !version.IsPrerelease); + } + else if (_floatBehavior == NuGetVersionFloatBehavior.PrereleasePatch) + { + // allow the stable version to match + return _minVersion.Major == version.Major + && _minVersion.Minor == version.Minor + && ((version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) + || !version.IsPrerelease); + } + else if (FloatBehavior == NuGetVersionFloatBehavior.PrereleaseMinor) + { + // allow the stable version to match + return _minVersion.Major == version.Major + && ((version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) + || !version.IsPrerelease); + } + else if (_floatBehavior == NuGetVersionFloatBehavior.Prerelease) { // allow the stable version to match return VersionComparer.Version.Equals(_minVersion, version) @@ -134,9 +158,7 @@ public bool Satisfies(NuGetVersion version) /// public static FloatRange Parse(string versionString) { - FloatRange range = null; - - TryParse(versionString, out range); + TryParse(versionString, out FloatRange range); return range; } @@ -150,23 +172,78 @@ public static bool TryParse(string versionString, out FloatRange range) if (versionString != null) { - var starPos = versionString.IndexOf('*'); - - var actualVersion = versionString; + var firstStarPosition = versionString.IndexOf('*'); + var lastStarPosition = versionString.LastIndexOf('*'); string releasePrefix = null; if (versionString.Length == 1 - && starPos == 0) + && firstStarPosition == 0) { range = new FloatRange(NuGetVersionFloatBehavior.Major, new NuGetVersion(new Version(0, 0))); } - // * must appear as the last char in the string. + else if (versionString.Length == 3 + && firstStarPosition == 0 && lastStarPosition == 2 && versionString[1] == '-') + { + range = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest, new NuGetVersion("0.0.0-0")); + } + else if (firstStarPosition != lastStarPosition && lastStarPosition != -1 && versionString.IndexOf('+') == -1) + { + var behavior = NuGetVersionFloatBehavior.None; + // 2 *s are only allowed in prerelease versions. + var dashPosition = versionString.IndexOf('-'); + string actualVersion = null; + + if (dashPosition != -1 && + lastStarPosition == versionString.Length - 1 && // Last star is at the end of the full string + firstStarPosition == (dashPosition-1) // First star is right before the first dash. + ) + { + // Get the stable part. + var stablePart = versionString.Substring(0, dashPosition - 1); // Get the part without the * + stablePart += "0"; + var versionParts = stablePart.Split('.').Length; + if (versionParts == 2) + { + behavior = NuGetVersionFloatBehavior.PrereleaseMinor; + } + else if (versionParts == 3) + { + behavior = NuGetVersionFloatBehavior.PrereleasePatch; + } + else if (versionParts == 4) + { + behavior = NuGetVersionFloatBehavior.PrereleaseRevision; + } + + var releaseVersion = versionString.Substring(dashPosition + 1); + releasePrefix = releaseVersion.Substring(0, releaseVersion.Length - 1); + var releasePart = releasePrefix; + // For numeric labels 0 is the lowest. For alpha-numeric - is the lowest. + if (releasePrefix.Length == 0 || releasePrefix.EndsWith(".")) + { + // 1.0.0-* scenario, an empty label is not a valid version. + releasePart += "0"; + } + else if (releasePrefix.EndsWith("-")) + { + // Append a dash to allow floating on the next character. + releasePart += "-"; + } + actualVersion = stablePart + "-" + releasePart; + } + + if (NuGetVersion.TryParse(actualVersion, out NuGetVersion version)) + { + range = new FloatRange(behavior, version, releasePrefix); + } + } + // A single * can only appear as the last char in the string. // * cannot appear in the metadata section after the + - else if (starPos == versionString.Length - 1 && versionString.IndexOf('+') == -1) + else if (lastStarPosition == versionString.Length - 1 && versionString.IndexOf('+') == -1) { var behavior = NuGetVersionFloatBehavior.None; - actualVersion = versionString.Substring(0, versionString.Length - 1); + var actualVersion = versionString.Substring(0, versionString.Length - 1); if (versionString.IndexOf('-') == -1) { @@ -214,7 +291,6 @@ public static bool TryParse(string versionString, out FloatRange range) NuGetVersion version = null; if (NuGetVersion.TryParse(actualVersion, out version)) { - // there is no float range for this version range = new FloatRange(behavior, version, releasePrefix); } } @@ -259,9 +335,17 @@ public override string ToString() case NuGetVersionFloatBehavior.Major: result = "*"; break; + case NuGetVersionFloatBehavior.PrereleaseRevision: + result = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}.*-{3}*", MinVersion.Major, MinVersion.Minor, MinVersion.Patch, _releasePrefix); + break; + case NuGetVersionFloatBehavior.PrereleasePatch: + result = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.*-{2}*", MinVersion.Major, MinVersion.Minor, _releasePrefix); + break; + case NuGetVersionFloatBehavior.PrereleaseMinor: + result = string.Format(CultureInfo.InvariantCulture, "{0}.*-{1}*", MinVersion.Major, _releasePrefix); + break; case NuGetVersionFloatBehavior.AbsoluteLatest: - // TODO: how should this be denoted? - result = string.Empty; + result = "*-*"; break; default: break; diff --git a/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs b/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs index 12527616d2d..4f12d945c47 100644 --- a/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs +++ b/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. namespace NuGet.Versioning @@ -41,6 +41,21 @@ public enum NuGetVersionFloatBehavior /// /// Float major and pre-release /// - AbsoluteLatest + AbsoluteLatest, + + /// + /// Float revision and pre-release x.y.z.*-* + /// + PrereleaseRevision, + + /// + /// Float patch and pre-release x.y.*-* + /// + PrereleasePatch, + + /// + /// Float minor and pre-release x.*-* + /// + PrereleaseMinor, } } diff --git a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs index c3117f92f6e..cb01737a78f 100644 --- a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs +++ b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs @@ -70,7 +70,7 @@ public static VersionRange Parse(string value, bool allowFloating) if (!TryParse(value, allowFloating, out versionInfo)) { throw new ArgumentException( - String.Format(CultureInfo.CurrentCulture, + string.Format(CultureInfo.CurrentCulture, Resources.Invalidvalue, value)); } @@ -101,7 +101,7 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v var charArray = trimmedValue.ToCharArray(); - // * is the only range below 3 chars + // * is the only 1 char range if (allowFloating && charArray.Length == 1 && charArray[0] == '*') @@ -116,6 +116,17 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v return false; } + // Special case *-* + if (allowFloating + && charArray.Length == 3 + && charArray[0] == '*' + && charArray[0] == '-' + && charArray[0] == '*') + { + versionRange = new VersionRange(new NuGetVersion(0, 0, 0, releaseLabel: "0"), true, null, true, FloatRange.Parse(trimmedValue), originalString: value); + return true; + } + string minVersionString = null; string maxVersionString = null; var isMinInclusive = false; @@ -195,7 +206,7 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v minVersionString = trimmedValue; } - if (!String.IsNullOrWhiteSpace(minVersionString)) + if (!string.IsNullOrWhiteSpace(minVersionString)) { // parse the min version string if (allowFloating && minVersionString.Contains("*")) @@ -224,7 +235,7 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v } // parse the max version string, the max cannot float - if (!String.IsNullOrWhiteSpace(maxVersionString)) + if (!string.IsNullOrWhiteSpace(maxVersionString)) { if (!NuGetVersion.TryParse(maxVersionString, out maxVersion)) { diff --git a/src/NuGet.Core/NuGet.Versioning/VersionRangeFormatter.cs b/src/NuGet.Core/NuGet.Versioning/VersionRangeFormatter.cs index 962bce978a4..aca6eb3006d 100644 --- a/src/NuGet.Core/NuGet.Versioning/VersionRangeFormatter.cs +++ b/src/NuGet.Core/NuGet.Versioning/VersionRangeFormatter.cs @@ -159,7 +159,6 @@ private string GetShortString(VersionRange range) /// private string GetNormalizedString(VersionRange range) { - // TODO: write out the float version var sb = new StringBuilder(); sb.Append(range.HasLowerBound && range.IsMinInclusive ? '[' : '('); diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs index c6ac470916c..096fc1eb580 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; @@ -8,6 +8,24 @@ namespace NuGet.Versioning.Test { public class FloatingRangeTests { + [Fact] + public void FloatRange_Float() + { + var range = new VersionRange(NuGetVersion.Parse("2.2.0"), true, null, false, new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest)); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0-pre"), + }; + + Assert.Equal(NuGetVersion.Parse("3.0.0-pre"), range.FindBestMatch(versions)); + } + + [Fact] public void FloatRange_OutsideOfRange() { @@ -328,17 +346,723 @@ public void FloatingRange_ToStringMinor() Assert.Equal("[1.*, )", range.ToNormalizedString()); } - [Fact] - public void FloatingRange_FloatMetadata_Invalid() + [Theory] + [InlineData("1.0.0+*")] + [InlineData("1.0.**")] + [InlineData("1.*.0")] + [InlineData("1.0.*-*bla")] + [InlineData("1.0.*-*bla+*")] + [InlineData("**")] + [InlineData("1.0.0-preview.*+blabla")] + [InlineData("1.0.*--")] + [InlineData("1.0.*-alpha*+")] + [InlineData("1.0.*-")] + public void FloatingRange_Parse_Invalid(string floatVersionString) { // Arrange FloatRange range; // Act - var valid = FloatRange.TryParse("1.0.0+*", out range); + var valid = FloatRange.TryParse(floatVersionString, out range); // Assert Assert.False(valid); } + + [Theory] + [InlineData("1.0.0-preview.*")] + [InlineData("1.0.*-bla*")] + [InlineData("1.0.*-*")] + [InlineData("1.0.*-preview.1.*")] + [InlineData("1.0.*-preview.1*")] + [InlineData("1.0.0--")] + [InlineData("1.0.0-bla*")] + [InlineData("1.0.*--*")] + [InlineData("1.0.0--*")] + public void FloatingRange_Parse_Valid(string floatVersionString) + { + // Arrange + FloatRange range; + + // Act + var valid = FloatRange.TryParse(floatVersionString, out range); + + // Assert + Assert.True(valid); + } + + [Fact] + public void FloatingRange_ToStringRevPrefix() + { + var range = VersionRange.Parse("1.1.1.*-*"); + + Assert.Equal("[1.1.1.*-*, )", range.ToNormalizedString()); + } + + [Fact] + public void FloatingRange_ToStringPatchPrefix() + { + var range = VersionRange.Parse("1.1.*-*"); + + Assert.Equal("[1.1.*-*, )", range.ToNormalizedString()); + } + + [Fact] + public void FloatingRange_ToStringMinorPrefix() + { + var range = VersionRange.Parse("1.*-*"); + + Assert.Equal("[1.*-*, )", range.ToNormalizedString()); + } + + [Fact] + public void FloatingRange_ToStringAbsoluteLatest() + { + var range = VersionRange.Parse("*-*"); + + Assert.Equal("[*-*, )", range.ToNormalizedString()); + Assert.Equal("0.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal("0.0.0-0", range.Float.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.Float.FloatBehavior); + } + + [Fact] + public void FloatingRange_FloatPrereleaseRev() + { + var range = FloatRange.Parse("1.0.0.*-*"); + + Assert.Equal("1.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleaseRevision, range.FloatBehavior); + } + + [Fact] + public void FloatingRange_FloatPrereleasePatch() + { + var range = FloatRange.Parse("1.0.*-*"); + + Assert.Equal("1.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleasePatch, range.FloatBehavior); + } + + [Fact] + public void FloatingRange_FloatPrereleaseMinor() + { + var range = FloatRange.Parse("1.*-*"); + + Assert.Equal("1.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMinor, range.FloatBehavior); + } + + [Fact] + public void FloatingRange_FloatAbsoluteLatest() + { + var range = FloatRange.Parse("*-*"); + + Assert.Equal("0.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.FloatBehavior); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.0.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_NotMatchingPrefix_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.0.*-beta*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange_Lower() + { + var range = VersionRange.Parse("[1.1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.8.0"), + NuGetVersion.Parse("0.9.0"), + NuGetVersion.Parse("1.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange_Higher() + { + var range = VersionRange.Parse("[1.1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_OnlyMatching() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.1-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_BestMatching() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_BestMatchingStable() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1.9"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1.9", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_BestMatchingFloating() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1.8"), + NuGetVersion.Parse("1.0.1.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_NotMatchingPrefix_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.*-beta*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_OutsideOfRange_Lower() + { + var range = VersionRange.Parse("[1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.8.0"), + NuGetVersion.Parse("0.9.0"), + NuGetVersion.Parse("1.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_OutsideOfRange_Higher() + { + var range = VersionRange.Parse("[1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_OnlyMatching() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_BestMatching() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_BestMatchingStable() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.0.9"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.9", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_BestMatchingPrerelease() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.8"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_NotMatchingPrefix_OutsideOfRange() + { + var range = VersionRange.Parse("[1.*-beta*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_OutsideOfRange_Lower() + { + var range = VersionRange.Parse("[1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.8.0"), + NuGetVersion.Parse("0.9.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_OutsideOfRange_Higher() + { + var range = VersionRange.Parse("[1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_OnlyMatching() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_BestMatching() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.1.0-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_BestMatchingStable() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_BestMatchingPrerelease() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("1.99.1-alpha1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.99.1-alpha1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseRevision_RangeOpen() + { + var range = VersionRange.Parse("[1.0.0.*-*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.0.1-alpha.1"), + NuGetVersion.Parse("1.0.1-alpha.1"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.0.0.1-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleasePatch_RangeOpen() + { + var range = VersionRange.Parse("[1.0.*-*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1-beta.2") + }; + + Assert.Equal("1.0.1-beta.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMinor_RangeOpen() + { + var range = VersionRange.Parse("[1.*-*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0-alpha.2"), + NuGetVersion.Parse("2.0.0-alpha.2"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.9.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMinor_IgnoresPartialPrereleaseMatches() + { + var range = VersionRange.Parse("[1.*-alpha*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0"), + NuGetVersion.Parse("1.20.0-alph.3"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.9.0", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMinor_NotMatching_SelectsFirstInRange() + { + var range = VersionRange.Parse("[1.*-alpha*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alph3.2"), + NuGetVersion.Parse("1.20.0-alph.3"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.20.0-alph.3", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseRevision_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1.1*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingRevision_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1.1*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleasePatch_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPatch_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingMinor_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrerelease_WithExtraDashes() + { + var range = VersionRange.Parse("[1.0.0--*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.0.0--alpha"), + NuGetVersion.Parse("1.0.0--beta"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.0.0--beta", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_FloatingPrereleaseMinor_WithExtraDashes() + { + var range = VersionRange.Parse("[1.*--*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.0.0--alpha"), + NuGetVersion.Parse("1.0.0--beta"), + NuGetVersion.Parse("1.9.0--beta"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.9.0--beta", range.FindBestMatch(versions).ToNormalizedString()); + } } } From 8515672fbfc87231d21c435dc81e1f5f9e04e24e Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Mon, 27 Jan 2020 21:24:34 -0800 Subject: [PATCH 05/12] fix bug --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 7 +---- .../FloatingRangeTests.cs | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index ac7469a296c..43bff6b1738 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -218,17 +218,12 @@ public static bool TryParse(string versionString, out FloatRange range) var releaseVersion = versionString.Substring(dashPosition + 1); releasePrefix = releaseVersion.Substring(0, releaseVersion.Length - 1); var releasePart = releasePrefix; - // For numeric labels 0 is the lowest. For alpha-numeric - is the lowest. if (releasePrefix.Length == 0 || releasePrefix.EndsWith(".")) { // 1.0.0-* scenario, an empty label is not a valid version. releasePart += "0"; } - else if (releasePrefix.EndsWith("-")) - { - // Append a dash to allow floating on the next character. - releasePart += "-"; - } + actualVersion = stablePart + "-" + releasePart; } diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs index 096fc1eb580..74a6907797a 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs @@ -1064,5 +1064,31 @@ public void FloatRange_FloatingPrereleaseMinor_WithExtraDashes() Assert.Equal("1.9.0--beta", range.FindBestMatch(versions).ToNormalizedString()); } + + + [Theory] + [InlineData("*", "0.0.0")] + [InlineData("*-*", "0.0.0-0")] + [InlineData("1.*", "1.0.0")] + [InlineData("1.1.*", "1.1.0")] + [InlineData("1.1.*-*", "1.1.0-0")] + [InlineData("1.1.1-*", "1.1.1-0")] + [InlineData("1.1.1-beta*", "1.1.1-beta")] + [InlineData("1.1.1-1*", "1.1.1-1")] + [InlineData("1.1.*-beta*", "1.1.0-beta")] + [InlineData("1.1.*-1*", "1.1.0-1")] + [InlineData("1.0.0-beta.1*", "1.0.0-beta.1")] + [InlineData("1.0.*-beta.1*", "1.0.0-beta.1")] + [InlineData("1.0.0-b-*", "1.0.0-b-")] + [InlineData("1.0.*-b-*", "1.0.0-b-")] + [InlineData("1.1.0-beta.*", "1.1.0-beta.0")] + [InlineData("1.1.*-beta.*", "1.1.0-beta.0")] + + public void FloatRange_ParsesCorrectMinVersion(string versionRange, string normalizedMinVersion) + { + var range = FloatRange.Parse(versionRange); + + Assert.Equal(normalizedMinVersion, range.MinVersion.ToNormalizedString()); + } } } From b9882c781f8cc7217010299f312f5e5e3a74722a Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Tue, 28 Jan 2020 23:08:28 -0800 Subject: [PATCH 06/12] fix prerelease major floating bug --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 36 +++-- .../NuGetVersionFloatBehavior.cs | 8 +- .../NuGet.Versioning/VersionRange.cs | 4 + .../NuGet.Versioning/VersionRangeFactory.cs | 2 +- .../FloatingRangeTests.cs | 144 ++++++++++++------ .../VersionRangeFloatParsingTests.cs | 51 ++++++- 6 files changed, 184 insertions(+), 61 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index 43bff6b1738..784902072fc 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -123,6 +123,12 @@ public bool Satisfies(NuGetVersion version) && ((version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) || !version.IsPrerelease); } + else if (FloatBehavior == NuGetVersionFloatBehavior.PrereleaseMajor) + { + // allow the stable version to match + return (version.IsPrerelease && version.Release.StartsWith(_releasePrefix, StringComparison.OrdinalIgnoreCase)) + || !version.IsPrerelease; + } else if (_floatBehavior == NuGetVersionFloatBehavior.Prerelease) { // allow the stable version to match @@ -184,7 +190,7 @@ public static bool TryParse(string versionString, out FloatRange range) else if (versionString.Length == 3 && firstStarPosition == 0 && lastStarPosition == 2 && versionString[1] == '-') { - range = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest, new NuGetVersion("0.0.0-0")); + range = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest, new NuGetVersion("0.0.0-0"), releasePrefix: string.Empty); } else if (firstStarPosition != lastStarPosition && lastStarPosition != -1 && versionString.IndexOf('+') == -1) { @@ -202,17 +208,22 @@ public static bool TryParse(string versionString, out FloatRange range) var stablePart = versionString.Substring(0, dashPosition - 1); // Get the part without the * stablePart += "0"; var versionParts = stablePart.Split('.').Length; - if (versionParts == 2) + switch (versionParts) { - behavior = NuGetVersionFloatBehavior.PrereleaseMinor; - } - else if (versionParts == 3) - { - behavior = NuGetVersionFloatBehavior.PrereleasePatch; - } - else if (versionParts == 4) - { - behavior = NuGetVersionFloatBehavior.PrereleaseRevision; + case 1: + behavior = NuGetVersionFloatBehavior.PrereleaseMajor; + break; + case 2: + behavior = NuGetVersionFloatBehavior.PrereleaseMinor; + break; + case 3: + behavior = NuGetVersionFloatBehavior.PrereleasePatch; + break; + case 4: + behavior = NuGetVersionFloatBehavior.PrereleaseRevision; + break; + default: + break; } var releaseVersion = versionString.Substring(dashPosition + 1); @@ -339,6 +350,9 @@ public override string ToString() case NuGetVersionFloatBehavior.PrereleaseMinor: result = string.Format(CultureInfo.InvariantCulture, "{0}.*-{1}*", MinVersion.Major, _releasePrefix); break; + case NuGetVersionFloatBehavior.PrereleaseMajor: + result = string.Format(CultureInfo.InvariantCulture, "*-{1}*", MinVersion.Major, _releasePrefix); + break; case NuGetVersionFloatBehavior.AbsoluteLatest: result = "*-*"; break; diff --git a/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs b/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs index 4f12d945c47..ce064d3b358 100644 --- a/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs +++ b/src/NuGet.Core/NuGet.Versioning/NuGetVersionFloatBehavior.cs @@ -39,7 +39,7 @@ public enum NuGetVersionFloatBehavior Major, /// - /// Float major and pre-release + /// Float major and pre-release, *-* /// AbsoluteLatest, @@ -57,5 +57,11 @@ public enum NuGetVersionFloatBehavior /// Float minor and pre-release x.*-* /// PrereleaseMinor, + + /// + /// Float major and prerelease, but only with partial prerelease *-rc.*. + /// *-* is captured by + /// + PrereleaseMajor, } } diff --git a/src/NuGet.Core/NuGet.Versioning/VersionRange.cs b/src/NuGet.Core/NuGet.Versioning/VersionRange.cs index 18882a2a0df..703ffa93bbc 100644 --- a/src/NuGet.Core/NuGet.Versioning/VersionRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/VersionRange.cs @@ -209,6 +209,10 @@ public bool IsBetter(NuGetVersion current, NuGetVersion considering) if (!HasPrereleaseBounds && considering.IsPrerelease && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.Prerelease + && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.PrereleaseMajor + && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.PrereleaseMinor + && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.PrereleasePatch + && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.PrereleaseRevision && _floatRange?.FloatBehavior != NuGetVersionFloatBehavior.AbsoluteLatest) { return false; diff --git a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs index cb01737a78f..ed7d455041d 100644 --- a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs +++ b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs @@ -123,7 +123,7 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v && charArray[0] == '-' && charArray[0] == '*') { - versionRange = new VersionRange(new NuGetVersion(0, 0, 0, releaseLabel: "0"), true, null, true, FloatRange.Parse(trimmedValue), originalString: value); + versionRange = new VersionRange(new NuGetVersion("0.0.0-0"), true, null, true, FloatRange.Parse(trimmedValue), originalString: value); return true; } diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs index 74a6907797a..260d8db710c 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs @@ -8,24 +8,6 @@ namespace NuGet.Versioning.Test { public class FloatingRangeTests { - [Fact] - public void FloatRange_Float() - { - var range = new VersionRange(NuGetVersion.Parse("2.2.0"), true, null, false, new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest)); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0-pre"), - }; - - Assert.Equal(NuGetVersion.Parse("3.0.0-pre"), range.FindBestMatch(versions)); - } - - [Fact] public void FloatRange_OutsideOfRange() { @@ -274,7 +256,6 @@ public void FloatingRange_FloatPrereleaseBest() [Fact] public void FloatingRange_FloatPrereleaseNotFoundBest() { - // "1.0.0-*" var range = VersionRange.Parse("1.0.0-*"); var versions = new List() @@ -426,6 +407,17 @@ public void FloatingRange_ToStringAbsoluteLatest() Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.Float.FloatBehavior); } + [Fact] + public void FloatingRange_ToStringPrereleaseMajor() + { + var range = VersionRange.Parse("*-rc.*"); + + Assert.Equal("[*-rc.*, )", range.ToNormalizedString()); + Assert.Equal("0.0.0-rc.0", range.MinVersion.ToNormalizedString()); + Assert.Equal("0.0.0-rc.0", range.Float.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMajor, range.Float.FloatBehavior); + } + [Fact] public void FloatingRange_FloatPrereleaseRev() { @@ -453,6 +445,15 @@ public void FloatingRange_FloatPrereleaseMinor() Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMinor, range.FloatBehavior); } + [Fact] + public void FloatingRange_FloatMajorPrerelease() + { + var range = FloatRange.Parse("*-rc.*"); + + Assert.Equal("0.0.0-rc.0", range.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMajor, range.FloatBehavior); + } + [Fact] public void FloatingRange_FloatAbsoluteLatest() { @@ -462,6 +463,34 @@ public void FloatingRange_FloatAbsoluteLatest() Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.FloatBehavior); } + [Theory] + [InlineData("*", "0.0.0")] + [InlineData("*-*", "0.0.0-0")] + [InlineData("1.*", "1.0.0")] + [InlineData("1.1.*", "1.1.0")] + [InlineData("1.1.*-*", "1.1.0-0")] + [InlineData("1.1.1-*", "1.1.1-0")] + [InlineData("1.1.1-beta*", "1.1.1-beta")] + [InlineData("1.1.1-1*", "1.1.1-1")] + [InlineData("1.1.*-beta*", "1.1.0-beta")] + [InlineData("1.1.*-1*", "1.1.0-1")] + [InlineData("1.0.0-beta.1*", "1.0.0-beta.1")] + [InlineData("1.0.*-beta.1*", "1.0.0-beta.1")] + [InlineData("1.0.0-b-*", "1.0.0-b-")] + [InlineData("1.0.*-b-*", "1.0.0-b-")] + [InlineData("1.1.0-beta.*", "1.1.0-beta.0")] + [InlineData("1.1.*-beta.*", "1.1.0-beta.0")] + [InlineData("*-beta.*", "0.0.0-beta.0")] + + public void FloatRange_ParsesCorrectMinVersion(string versionRange, string normalizedMinVersion) + { + var range = FloatRange.Parse(versionRange); + + Assert.Equal(normalizedMinVersion, range.MinVersion.ToNormalizedString()); + } + + /// TODO NK - From here on below, the tests can probably be moved to VersionRangeFloatParsing_FindsBestMatch + [Fact] public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange() { @@ -950,6 +979,57 @@ public void FloatRange_PrereleaseMinor_NotMatching_SelectsFirstInRange() Assert.Equal("1.20.0-alph.3", range.FindBestMatch(versions).ToNormalizedString()); } + [Fact] + public void FloatRange_PrereleaseMajor_IgnoresPartialPrereleaseMatches() + { + var range = VersionRange.Parse("[*-alpha*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0"), + NuGetVersion.Parse("1.20.0-alph.3"), + }; + + Assert.Equal("1.9.0", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMajor_NotMatching_SelectsFirstInRange() + { + var range = VersionRange.Parse("[*-rc*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0-beta"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0-alpha.2"), + NuGetVersion.Parse("2.0.0-alpha.2"), + }; + + Assert.Equal("0.1.0-beta", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FloatRange_PrereleaseMajor_BestMatching() + { + var range = VersionRange.Parse("*-rc*"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.0"), + NuGetVersion.Parse("1.2.0-rc.1"), + NuGetVersion.Parse("1.2.0-rc.2"), + NuGetVersion.Parse("1.2.0-rc1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.0.0-beta.1") + }; + + Assert.Equal("2.0.0", range.FindBestMatch(versions).ToNormalizedString()); + } + [Fact] public void FloatRange_FloatingPrereleaseRevision_WithPartialMatch() { @@ -1064,31 +1144,5 @@ public void FloatRange_FloatingPrereleaseMinor_WithExtraDashes() Assert.Equal("1.9.0--beta", range.FindBestMatch(versions).ToNormalizedString()); } - - - [Theory] - [InlineData("*", "0.0.0")] - [InlineData("*-*", "0.0.0-0")] - [InlineData("1.*", "1.0.0")] - [InlineData("1.1.*", "1.1.0")] - [InlineData("1.1.*-*", "1.1.0-0")] - [InlineData("1.1.1-*", "1.1.1-0")] - [InlineData("1.1.1-beta*", "1.1.1-beta")] - [InlineData("1.1.1-1*", "1.1.1-1")] - [InlineData("1.1.*-beta*", "1.1.0-beta")] - [InlineData("1.1.*-1*", "1.1.0-1")] - [InlineData("1.0.0-beta.1*", "1.0.0-beta.1")] - [InlineData("1.0.*-beta.1*", "1.0.0-beta.1")] - [InlineData("1.0.0-b-*", "1.0.0-b-")] - [InlineData("1.0.*-b-*", "1.0.0-b-")] - [InlineData("1.1.0-beta.*", "1.1.0-beta.0")] - [InlineData("1.1.*-beta.*", "1.1.0-beta.0")] - - public void FloatRange_ParsesCorrectMinVersion(string versionRange, string normalizedMinVersion) - { - var range = FloatRange.Parse(versionRange); - - Assert.Equal(normalizedMinVersion, range.MinVersion.ToNormalizedString()); - } } } diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeFloatParsingTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeFloatParsingTests.cs index 20a9b529db4..29ab2e76398 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeFloatParsingTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeFloatParsingTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Linq; using Xunit; namespace NuGet.Versioning.Test @@ -23,6 +22,11 @@ public void VersionRangeFloatParsing_Prerelease() [InlineData("1.0.0--*", "1.0.0--")] [InlineData("1.0.0-a-*", "1.0.0-a-")] [InlineData("1.0.0-a.*", "1.0.0-a.0")] + [InlineData("1.*-*", "1.0.0-0")] + [InlineData("1.0.*-0*", "1.0.0-0")] + [InlineData("1.0.*--*", "1.0.0--")] + [InlineData("1.0.*-a-*", "1.0.0-a-")] + [InlineData("1.0.*-a.*", "1.0.0-a.0")] public void VersionRangeFloatParsing_PrereleaseWithNumericOnlyLabelVerifyMinVersion(string rangeString, string expected) { var range = VersionRange.Parse(rangeString); @@ -46,6 +50,9 @@ public void VersionRangeFloatParsing_PrereleaseWithNumericOnlyLabelVerifySatisfi [InlineData("1.0.0-a*", "1.0.0-a.0")] [InlineData("1.0.0-a*", "1.0.0-a-0")] [InlineData("1.0.0-a*", "1.0.0-a")] + [InlineData("1.0.*-a*", "1.0.0-a")] + [InlineData("1.*-a*", "1.0.0-a")] + [InlineData("*-a*", "1.0.0-a")] public void VersionRangeFloatParsing_VerifySatisfiesForFloatingRange(string rangeString, string version) { var range = VersionRange.Parse(rangeString); @@ -59,6 +66,21 @@ public void VersionRangeFloatParsing_VerifySatisfiesForFloatingRange(string rang [InlineData("1.0.0-a-*", "a-", "a-")] [InlineData("1.0.0-a.*", "a.0", "a.")] [InlineData("1.0.0-0*", "0", "0")] + [InlineData("1.0.*-0*", "0", "0")] + [InlineData("1.*-0*", "0", "0")] + [InlineData("*-0*", "0", "0")] + [InlineData("1.0.*-*", "0", "")] + [InlineData("1.*-*", "0", "")] + [InlineData("*-*", "0", "")] + [InlineData("1.0.*-a*", "a", "a")] + [InlineData("1.*-a*", "a", "a")] + [InlineData("*-a*", "a", "a")] + [InlineData("1.0.*-a-*", "a-", "a-")] + [InlineData("1.*-a-*", "a-", "a-")] + [InlineData("*-a-*", "a-", "a-")] + [InlineData("1.0.*-a.*", "a.0", "a.")] + [InlineData("1.*-a.*", "a.0", "a.")] + [InlineData("*-a.*", "a.0", "a.")] public void VersionRangeFloatParsing_VerifyReleaseLabels(string rangeString, string versionLabel, string originalLabel) { var range = VersionRange.Parse(rangeString); @@ -164,8 +186,16 @@ public void VersionRangeFloatParsing_FloatPrereleasePrefixSemVerLabelMix() [InlineData("1.*.0-beta-*")] [InlineData("1.*.0-beta")] [InlineData("1.0.0.0.*")] - //[InlineData("1.0.0*")] [InlineData("=1.0.*")] + [InlineData("1.0.0+*")] + [InlineData("1.0.**")] + [InlineData("1.0.*-*bla")] + [InlineData("1.0.*-*bla+*")] + [InlineData("**")] + [InlineData("1.0.0-preview.*+blabla")] + [InlineData("1.0.*--")] + [InlineData("1.0.*-alpha*+")] + [InlineData("1.0.*-")] public void VersionRangeFloatParsing_Invalid(string rangeString) { VersionRange range = null; @@ -185,6 +215,14 @@ public void VersionRangeFloatParsing_Invalid(string rangeString) [InlineData("[1.0.0-beta.*, 2.0.0)")] [InlineData("1.0.0-beta.*")] [InlineData("1.0.0-beta-*")] + [InlineData("1.0.*-bla*")] + [InlineData("1.0.*-*")] + [InlineData("1.0.*-preview.1.*")] + [InlineData("1.0.*-preview.1*")] + [InlineData("1.0.0--")] + [InlineData("1.0.0-bla*")] + [InlineData("1.0.*--*")] + [InlineData("1.0.0--*")] public void VersionRangeFloatParsing_Valid(string rangeString) { VersionRange range = null; @@ -218,13 +256,20 @@ public void VersionRangeFloatParsing_CorrectFloatRange(string rangeString) Assert.Equal(rangeString, range.Float.ToString()); } - [Theory] [InlineData("1.0.0;2.0.0", "*", "2.0.0")] [InlineData("1.0.0;2.0.0", "0.*", "1.0.0")] [InlineData("1.0.0;2.0.0", "[*, )", "2.0.0")] [InlineData("1.0.0;2.0.0;3.0.0", "(1.0.*, )", "2.0.0")] [InlineData("1.0.0;2.0.0;3.0.0", "(1.0.*, 2.0.0)", null)] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "*", "2.0.0")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "1.*", "1.1.0")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "1.2.0-*", "1.2.0-rc.2")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "*-*", "3.0.0-beta.1")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "1.*-*", "1.2.0-rc.2")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;2.0.0;3.0.0-beta.1", "*-rc.*", "2.0.0")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;1.2.0-rc1;2.0.0;3.0.0-beta.1", "1.*-rc*", "1.2.0-rc1")] + [InlineData("1.1.0;1.2.0-rc.1;1.2.0-rc.2;1.2.0-rc1;1.10.0;2.0.0;3.0.0-beta.1", "1.1*-*", "1.10.0")] public void VersionRangeFloatParsing_FindsBestMatch(string availableVersions, string declaredRange, string expectedVersion) { var range = VersionRange.Parse(declaredRange); From b781ad855f896e96ca564a933d9c1fffce473eb4 Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Fri, 6 Mar 2020 16:31:20 -0800 Subject: [PATCH 07/12] address feedback --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index 784902072fc..e358387343d 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -187,8 +187,7 @@ public static bool TryParse(string versionString, out FloatRange range) { range = new FloatRange(NuGetVersionFloatBehavior.Major, new NuGetVersion(new Version(0, 0))); } - else if (versionString.Length == 3 - && firstStarPosition == 0 && lastStarPosition == 2 && versionString[1] == '-') + else if (versionString.Equals("*-*")) { range = new FloatRange(NuGetVersionFloatBehavior.AbsoluteLatest, new NuGetVersion("0.0.0-0"), releasePrefix: string.Empty); } From fd033d77bc1ada9212a3df516cb4d78161bbbd40 Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Wed, 11 Mar 2020 15:59:05 -0700 Subject: [PATCH 08/12] remove dead code --- .../NuGet.Versioning/VersionRangeFactory.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs index ed7d455041d..0ddfb2b972e 100644 --- a/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs +++ b/src/NuGet.Core/NuGet.Versioning/VersionRangeFactory.cs @@ -116,17 +116,6 @@ public static bool TryParse(string value, bool allowFloating, out VersionRange v return false; } - // Special case *-* - if (allowFloating - && charArray.Length == 3 - && charArray[0] == '*' - && charArray[0] == '-' - && charArray[0] == '*') - { - versionRange = new VersionRange(new NuGetVersion("0.0.0-0"), true, null, true, FloatRange.Parse(trimmedValue), originalString: value); - return true; - } - string minVersionString = null; string maxVersionString = null; var isMinInclusive = false; From b0ca0ecfea26f6c4df4808b668689cbd348c4ea7 Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Wed, 11 Mar 2020 18:15:45 -0700 Subject: [PATCH 09/12] address feedback --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 2 +- .../FloatingRangeTests.cs | 49 +++++++++++++++++-- .../VersionRangeTests.cs | 10 ++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index e358387343d..939f53d6a28 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -176,7 +176,7 @@ public static bool TryParse(string versionString, out FloatRange range) { range = null; - if (versionString != null) + if (versionString != null && !string.IsNullOrWhiteSpace(versionString)) { var firstStarPosition = versionString.IndexOf('*'); var lastStarPosition = versionString.LastIndexOf('*'); diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs index 260d8db710c..7810651a884 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs @@ -338,7 +338,9 @@ public void FloatingRange_ToStringMinor() [InlineData("1.0.*--")] [InlineData("1.0.*-alpha*+")] [InlineData("1.0.*-")] - public void FloatingRange_Parse_Invalid(string floatVersionString) + [InlineData(null)] + [InlineData("")] + public void FloatingRange_TryParse_Invalid(string floatVersionString) { // Arrange FloatRange range; @@ -348,6 +350,7 @@ public void FloatingRange_Parse_Invalid(string floatVersionString) // Assert Assert.False(valid); + Assert.Null(range); } [Theory] @@ -361,6 +364,47 @@ public void FloatingRange_Parse_Invalid(string floatVersionString) [InlineData("1.0.*--*")] [InlineData("1.0.0--*")] public void FloatingRange_Parse_Valid(string floatVersionString) + { + // Arrange && Act + var range = FloatRange.Parse(floatVersionString); + + // Assert + Assert.NotNull(range); + } + + [Theory] + [InlineData("1.0.0+*")] + [InlineData("1.0.**")] + [InlineData("1.*.0")] + [InlineData("1.0.*-*bla")] + [InlineData("1.0.*-*bla+*")] + [InlineData("**")] + [InlineData("1.0.0-preview.*+blabla")] + [InlineData("1.0.*--")] + [InlineData("1.0.*-alpha*+")] + [InlineData("1.0.*-")] + [InlineData(null)] + [InlineData("")] + public void FloatingRange_Parse_Invalid(string floatVersionString) + { + // Arrange && Act + var range = FloatRange.Parse(floatVersionString); + + // Assert + Assert.Null(range); + } + + [Theory] + [InlineData("1.0.0-preview.*")] + [InlineData("1.0.*-bla*")] + [InlineData("1.0.*-*")] + [InlineData("1.0.*-preview.1.*")] + [InlineData("1.0.*-preview.1*")] + [InlineData("1.0.0--")] + [InlineData("1.0.0-bla*")] + [InlineData("1.0.*--*")] + [InlineData("1.0.0--*")] + public void FloatingRange_TryParse_Valid(string floatVersionString) { // Arrange FloatRange range; @@ -370,6 +414,7 @@ public void FloatingRange_Parse_Valid(string floatVersionString) // Assert Assert.True(valid); + Assert.NotNull(range); } [Fact] @@ -489,8 +534,6 @@ public void FloatRange_ParsesCorrectMinVersion(string versionRange, string norma Assert.Equal(normalizedMinVersion, range.MinVersion.ToNormalizedString()); } - /// TODO NK - From here on below, the tests can probably be moved to VersionRangeFloatParsing_FindsBestMatch - [Fact] public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange() { diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeTests.cs index 3e18940e43e..cdc0d863bbc 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeTests.cs @@ -432,6 +432,16 @@ public void ParseVersionRangeWithNullThrows() ExceptionAssert.ThrowsArgNull(() => VersionRange.Parse(null), "value"); } + [Theory] + [InlineData("")] + [InlineData(" ")] + public void ParseVersionRangeWithBadVersionThrows(string version) + { + // Act & Assert + var exception = Assert.Throws(() => VersionRange.Parse(version)); + Assert.Equal($"'{version}' is not a valid version string.", exception.Message); + } + [Fact] public void ParseVersionRangeSimpleVersionNoBrackets() { From 8ae51ae18707a4bee4f08c507e0ee1b14d37a4cb Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Wed, 11 Mar 2020 23:13:43 -0700 Subject: [PATCH 10/12] Shift around the test names --- .../FloatingRangeTests.cs | 700 ----------------- .../VersionRangeTests.cs | 705 +++++++++++++++++- 2 files changed, 703 insertions(+), 702 deletions(-) diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs index 7810651a884..0a4074a437c 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs @@ -417,52 +417,6 @@ public void FloatingRange_TryParse_Valid(string floatVersionString) Assert.NotNull(range); } - [Fact] - public void FloatingRange_ToStringRevPrefix() - { - var range = VersionRange.Parse("1.1.1.*-*"); - - Assert.Equal("[1.1.1.*-*, )", range.ToNormalizedString()); - } - - [Fact] - public void FloatingRange_ToStringPatchPrefix() - { - var range = VersionRange.Parse("1.1.*-*"); - - Assert.Equal("[1.1.*-*, )", range.ToNormalizedString()); - } - - [Fact] - public void FloatingRange_ToStringMinorPrefix() - { - var range = VersionRange.Parse("1.*-*"); - - Assert.Equal("[1.*-*, )", range.ToNormalizedString()); - } - - [Fact] - public void FloatingRange_ToStringAbsoluteLatest() - { - var range = VersionRange.Parse("*-*"); - - Assert.Equal("[*-*, )", range.ToNormalizedString()); - Assert.Equal("0.0.0-0", range.MinVersion.ToNormalizedString()); - Assert.Equal("0.0.0-0", range.Float.MinVersion.ToNormalizedString()); - Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.Float.FloatBehavior); - } - - [Fact] - public void FloatingRange_ToStringPrereleaseMajor() - { - var range = VersionRange.Parse("*-rc.*"); - - Assert.Equal("[*-rc.*, )", range.ToNormalizedString()); - Assert.Equal("0.0.0-rc.0", range.MinVersion.ToNormalizedString()); - Assert.Equal("0.0.0-rc.0", range.Float.MinVersion.ToNormalizedString()); - Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMajor, range.Float.FloatBehavior); - } - [Fact] public void FloatingRange_FloatPrereleaseRev() { @@ -533,659 +487,5 @@ public void FloatRange_ParsesCorrectMinVersion(string versionRange, string norma Assert.Equal(normalizedMinVersion, range.MinVersion.ToNormalizedString()); } - - [Fact] - public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange() - { - var range = VersionRange.Parse("[1.0.0.*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleaseRevision_NotMatchingPrefix_OutsideOfRange() - { - var range = VersionRange.Parse("[1.0.0.*-beta*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange_Lower() - { - var range = VersionRange.Parse("[1.1.1.*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("0.8.0"), - NuGetVersion.Parse("0.9.0"), - NuGetVersion.Parse("1.0.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleaseRevision_OutsideOfRange_Higher() - { - var range = VersionRange.Parse("[1.1.1.*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleaseRevision_OnlyMatching() - { - var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.1-alpha.2"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.0.1-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseRevision_BestMatching() - { - var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.1.9-alpha.1"), - NuGetVersion.Parse("1.1.0-alpha.1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.0.1.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseRevision_BestMatchingStable() - { - var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.1.9"), - NuGetVersion.Parse("1.0.9-alpha.1"), - NuGetVersion.Parse("1.1.0-alpha.1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.0.1.9", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseRevision_BestMatchingFloating() - { - var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.1.8"), - NuGetVersion.Parse("1.0.1.9-alpha.1"), - NuGetVersion.Parse("1.1.0-alpha.1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.0.1.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleasePatch_OutsideOfRange() - { - var range = VersionRange.Parse("[1.0.*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleasePatch_NotMatchingPrefix_OutsideOfRange() - { - var range = VersionRange.Parse("[1.0.*-beta*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleasePatch_OutsideOfRange_Lower() - { - var range = VersionRange.Parse("[1.1.*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("0.8.0"), - NuGetVersion.Parse("0.9.0"), - NuGetVersion.Parse("1.0.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleasePatch_OutsideOfRange_Higher() - { - var range = VersionRange.Parse("[1.1.*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleasePatch_OnlyMatching() - { - var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.0.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleasePatch_BestMatching() - { - var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.9-alpha.1"), - NuGetVersion.Parse("1.1.0-alpha.1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.0.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleasePatch_BestMatchingStable() - { - var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.9-alpha.1"), - NuGetVersion.Parse("1.0.9"), - NuGetVersion.Parse("1.1.0-alpha.1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.0.9", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleasePatch_BestMatchingPrerelease() - { - var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.8"), - NuGetVersion.Parse("1.0.9-alpha.1"), - NuGetVersion.Parse("1.1.0-alpha.1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.0.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseMinor_NotMatchingPrefix_OutsideOfRange() - { - var range = VersionRange.Parse("[1.*-beta*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleaseMinor_OutsideOfRange_Lower() - { - var range = VersionRange.Parse("[1.*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("0.8.0"), - NuGetVersion.Parse("0.9.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleaseMinor_OutsideOfRange_Higher() - { - var range = VersionRange.Parse("[1.*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Null(range.FindBestMatch(versions)); - } - - [Fact] - public void FloatRange_FloatingPrereleaseMinor_OnlyMatching() - { - var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.0.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseMinor_BestMatching() - { - var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.9-alpha.1"), - NuGetVersion.Parse("1.1.0-alpha.1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.1.0-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseMinor_BestMatchingStable() - { - var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.9-alpha.1"), - NuGetVersion.Parse("1.1.0-alpha.1"), - NuGetVersion.Parse("1.10.1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseMinor_BestMatchingPrerelease() - { - var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.9-alpha.1"), - NuGetVersion.Parse("1.1.0-alpha.1"), - NuGetVersion.Parse("1.10.1"), - NuGetVersion.Parse("1.99.1-alpha1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("2.2.0"), - NuGetVersion.Parse("3.0.0"), - }; - - Assert.Equal("1.99.1-alpha1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_PrereleaseRevision_RangeOpen() - { - var range = VersionRange.Parse("[1.0.0.*-*, )"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("0.2.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.0.1-alpha.1"), - NuGetVersion.Parse("1.0.1-alpha.1"), - NuGetVersion.Parse("101.0.0") - }; - - Assert.Equal("1.0.0.1-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_PrereleasePatch_RangeOpen() - { - var range = VersionRange.Parse("[1.0.*-*, )"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("0.2.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.0.1-beta.2") - }; - - Assert.Equal("1.0.1-beta.2", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_PrereleaseMinor_RangeOpen() - { - var range = VersionRange.Parse("[1.*-*, )"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("0.2.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.9.0-alpha.2"), - NuGetVersion.Parse("2.0.0-alpha.2"), - NuGetVersion.Parse("101.0.0") - }; - - Assert.Equal("1.9.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_PrereleaseMinor_IgnoresPartialPrereleaseMatches() - { - var range = VersionRange.Parse("[1.*-alpha*, )"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("0.2.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.9.0"), - NuGetVersion.Parse("1.20.0-alph.3"), - NuGetVersion.Parse("101.0.0") - }; - - Assert.Equal("1.9.0", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_PrereleaseMinor_NotMatching_SelectsFirstInRange() - { - var range = VersionRange.Parse("[1.*-alpha*, )"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("0.2.0"), - NuGetVersion.Parse("1.0.0-alph3.2"), - NuGetVersion.Parse("1.20.0-alph.3"), - NuGetVersion.Parse("101.0.0") - }; - - Assert.Equal("1.20.0-alph.3", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_PrereleaseMajor_IgnoresPartialPrereleaseMatches() - { - var range = VersionRange.Parse("[*-alpha*, )"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0"), - NuGetVersion.Parse("0.2.0"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.9.0"), - NuGetVersion.Parse("1.20.0-alph.3"), - }; - - Assert.Equal("1.9.0", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_PrereleaseMajor_NotMatching_SelectsFirstInRange() - { - var range = VersionRange.Parse("[*-rc*, )"); - - var versions = new List() - { - NuGetVersion.Parse("0.1.0-beta"), - NuGetVersion.Parse("1.0.0-alpha.2"), - NuGetVersion.Parse("1.9.0-alpha.2"), - NuGetVersion.Parse("2.0.0-alpha.2"), - }; - - Assert.Equal("0.1.0-beta", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_PrereleaseMajor_BestMatching() - { - var range = VersionRange.Parse("*-rc*"); - - var versions = new List() - { - NuGetVersion.Parse("1.1.0"), - NuGetVersion.Parse("1.2.0-rc.1"), - NuGetVersion.Parse("1.2.0-rc.2"), - NuGetVersion.Parse("1.2.0-rc1"), - NuGetVersion.Parse("2.0.0"), - NuGetVersion.Parse("3.0.0-beta.1") - }; - - Assert.Equal("2.0.0", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseRevision_WithPartialMatch() - { - var range = VersionRange.Parse("[1.1.1.1*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("1.1.1.10"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Equal("1.1.1.10", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingRevision_WithPartialMatch() - { - var range = VersionRange.Parse("[1.1.1.1*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("1.1.1.10"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Equal("1.1.1.10", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleasePatch_WithPartialMatch() - { - var range = VersionRange.Parse("[1.1.1*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("1.1.10"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Equal("1.1.10", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPatch_WithPartialMatch() - { - var range = VersionRange.Parse("[1.1.1*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("1.1.10"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Equal("1.1.10", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseMinor_WithPartialMatch() - { - var range = VersionRange.Parse("[1.1*-*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("1.10.1"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingMinor_WithPartialMatch() - { - var range = VersionRange.Parse("[1.1*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("1.10.1"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrerelease_WithExtraDashes() - { - var range = VersionRange.Parse("[1.0.0--*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("1.0.0--alpha"), - NuGetVersion.Parse("1.0.0--beta"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Equal("1.0.0--beta", range.FindBestMatch(versions).ToNormalizedString()); - } - - [Fact] - public void FloatRange_FloatingPrereleaseMinor_WithExtraDashes() - { - var range = VersionRange.Parse("[1.*--*, 2.0.0)"); - - var versions = new List() - { - NuGetVersion.Parse("1.0.0--alpha"), - NuGetVersion.Parse("1.0.0--beta"), - NuGetVersion.Parse("1.9.0--beta"), - NuGetVersion.Parse("3.1.0"), - }; - - Assert.Equal("1.9.0--beta", range.FindBestMatch(versions).ToNormalizedString()); - } } } diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeTests.cs index cdc0d863bbc..12b5c11fed1 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionRangeTests.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Globalization; using Xunit; @@ -729,7 +730,7 @@ public void StringFormatNullProvider(string range) { // Arrange var versionRange = VersionRange.Parse(range); - var actual = String.Format("{0}", versionRange); + var actual = string.Format("{0}", versionRange); var expected = versionRange.ToString(); // Assert @@ -759,7 +760,7 @@ public void StringFormatNullProvider2(string range) { // Arrange var versionRange = VersionRange.Parse(range); - var actual = String.Format(CultureInfo.InvariantCulture, "{0}", versionRange); + var actual = string.Format(CultureInfo.InvariantCulture, "{0}", versionRange); var expected = versionRange.ToString(); // Assert @@ -802,5 +803,705 @@ public void VersionRange_Equals(string versionString1, string versionString2, bo Assert.Equal(isEquals, range1.Equals(range2)); } + + [Fact] + public void VersionRange_ToStringRevPrefix() + { + var range = VersionRange.Parse("1.1.1.*-*"); + + Assert.Equal("[1.1.1.*-*, )", range.ToNormalizedString()); + } + + [Fact] + public void VersionRange_ToStringPatchPrefix() + { + var range = VersionRange.Parse("1.1.*-*"); + + Assert.Equal("[1.1.*-*, )", range.ToNormalizedString()); + } + + [Fact] + public void VersionRange_ToStringMinorPrefix() + { + var range = VersionRange.Parse("1.*-*"); + + Assert.Equal("[1.*-*, )", range.ToNormalizedString()); + } + + [Fact] + public void VersionRange_ToStringAbsoluteLatest() + { + var range = VersionRange.Parse("*-*"); + + Assert.Equal("[*-*, )", range.ToNormalizedString()); + Assert.Equal("0.0.0-0", range.MinVersion.ToNormalizedString()); + Assert.Equal("0.0.0-0", range.Float.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.AbsoluteLatest, range.Float.FloatBehavior); + } + + [Fact] + public void VersionRange_ToStringPrereleaseMajor() + { + var range = VersionRange.Parse("*-rc.*"); + + Assert.Equal("[*-rc.*, )", range.ToNormalizedString()); + Assert.Equal("0.0.0-rc.0", range.MinVersion.ToNormalizedString()); + Assert.Equal("0.0.0-rc.0", range.Float.MinVersion.ToNormalizedString()); + Assert.Equal(NuGetVersionFloatBehavior.PrereleaseMajor, range.Float.FloatBehavior); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseRevision_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.0.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseRevision_NotMatchingPrefix_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.0.*-beta*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseRevision_OutsideOfRange_Lower() + { + var range = VersionRange.Parse("[1.1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.8.0"), + NuGetVersion.Parse("0.9.0"), + NuGetVersion.Parse("1.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseRevision_OutsideOfRange_Higher() + { + var range = VersionRange.Parse("[1.1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseRevision_OnlyMatching() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.1-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseRevision_BestMatching() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseRevision_BestMatchingStable() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1.9"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1.9", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseRevision_BestMatchingFloating() + { + var range = VersionRange.Parse("[1.0.1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1.8"), + NuGetVersion.Parse("1.0.1.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.1.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleasePatch_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleasePatch_NotMatchingPrefix_OutsideOfRange() + { + var range = VersionRange.Parse("[1.0.*-beta*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleasePatch_OutsideOfRange_Lower() + { + var range = VersionRange.Parse("[1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.8.0"), + NuGetVersion.Parse("0.9.0"), + NuGetVersion.Parse("1.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleasePatch_OutsideOfRange_Higher() + { + var range = VersionRange.Parse("[1.1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleasePatch_OnlyMatching() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleasePatch_BestMatching() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleasePatch_BestMatchingStable() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.0.9"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.9", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleasePatch_BestMatchingPrerelease() + { + var range = VersionRange.Parse("[1.0.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.8"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.9-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseMinor_NotMatchingPrefix_OutsideOfRange() + { + var range = VersionRange.Parse("[1.*-beta*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseMinor_OutsideOfRange_Lower() + { + var range = VersionRange.Parse("[1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.8.0"), + NuGetVersion.Parse("0.9.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseMinor_OutsideOfRange_Higher() + { + var range = VersionRange.Parse("[1.*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Null(range.FindBestMatch(versions)); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseMinor_OnlyMatching() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.0.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseMinor_BestMatching() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.1.0-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseMinor_BestMatchingStable() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseMinor_BestMatchingPrerelease() + { + var range = VersionRange.Parse("[1.*-alpha*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.9-alpha.1"), + NuGetVersion.Parse("1.1.0-alpha.1"), + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("1.99.1-alpha1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("2.2.0"), + NuGetVersion.Parse("3.0.0"), + }; + + Assert.Equal("1.99.1-alpha1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_PrereleaseRevision_RangeOpen() + { + var range = VersionRange.Parse("[1.0.0.*-*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.0.1-alpha.1"), + NuGetVersion.Parse("1.0.1-alpha.1"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.0.0.1-alpha.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_PrereleasePatch_RangeOpen() + { + var range = VersionRange.Parse("[1.0.*-*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.0.1-beta.2") + }; + + Assert.Equal("1.0.1-beta.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_PrereleaseMinor_RangeOpen() + { + var range = VersionRange.Parse("[1.*-*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0-alpha.2"), + NuGetVersion.Parse("2.0.0-alpha.2"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.9.0-alpha.2", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_PrereleaseMinor_IgnoresPartialPrereleaseMatches() + { + var range = VersionRange.Parse("[1.*-alpha*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0"), + NuGetVersion.Parse("1.20.0-alph.3"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.9.0", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_PrereleaseMinor_NotMatching_SelectsFirstInRange() + { + var range = VersionRange.Parse("[1.*-alpha*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alph3.2"), + NuGetVersion.Parse("1.20.0-alph.3"), + NuGetVersion.Parse("101.0.0") + }; + + Assert.Equal("1.20.0-alph.3", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_PrereleaseMajor_IgnoresPartialPrereleaseMatches() + { + var range = VersionRange.Parse("[*-alpha*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0"), + NuGetVersion.Parse("0.2.0"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0"), + NuGetVersion.Parse("1.20.0-alph.3"), + }; + + Assert.Equal("1.9.0", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_PrereleaseMajor_NotMatching_SelectsFirstInRange() + { + var range = VersionRange.Parse("[*-rc*, )"); + + var versions = new List() + { + NuGetVersion.Parse("0.1.0-beta"), + NuGetVersion.Parse("1.0.0-alpha.2"), + NuGetVersion.Parse("1.9.0-alpha.2"), + NuGetVersion.Parse("2.0.0-alpha.2"), + }; + + Assert.Equal("0.1.0-beta", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_PrereleaseMajor_BestMatching() + { + var range = VersionRange.Parse("*-rc*"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.0"), + NuGetVersion.Parse("1.2.0-rc.1"), + NuGetVersion.Parse("1.2.0-rc.2"), + NuGetVersion.Parse("1.2.0-rc1"), + NuGetVersion.Parse("2.0.0"), + NuGetVersion.Parse("3.0.0-beta.1") + }; + + Assert.Equal("2.0.0", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseRevision_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1.1*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingRevision_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1.1*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleasePatch_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPatch_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1.1*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.1.10"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.1.10", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseMinor_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1*-*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingMinor_WithPartialMatch() + { + var range = VersionRange.Parse("[1.1*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.10.1"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.10.1", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrerelease_WithExtraDashes() + { + var range = VersionRange.Parse("[1.0.0--*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.0.0--alpha"), + NuGetVersion.Parse("1.0.0--beta"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.0.0--beta", range.FindBestMatch(versions).ToNormalizedString()); + } + + [Fact] + public void FindBestMatch_FloatingPrereleaseMinor_WithExtraDashes() + { + var range = VersionRange.Parse("[1.*--*, 2.0.0)"); + + var versions = new List() + { + NuGetVersion.Parse("1.0.0--alpha"), + NuGetVersion.Parse("1.0.0--beta"), + NuGetVersion.Parse("1.9.0--beta"), + NuGetVersion.Parse("3.1.0"), + }; + + Assert.Equal("1.9.0--beta", range.FindBestMatch(versions).ToNormalizedString()); + } } } From 71c24605ac94915b1ef05a9d2ef4dc646d810be2 Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Mon, 16 Mar 2020 12:06:19 -0700 Subject: [PATCH 11/12] address feedback --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 20 +++++++++++++++++-- .../FloatingRangeTests.cs | 1 - 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index 939f53d6a28..67d24232c6c 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -206,7 +206,7 @@ public static bool TryParse(string versionString, out FloatRange range) // Get the stable part. var stablePart = versionString.Substring(0, dashPosition - 1); // Get the part without the * stablePart += "0"; - var versionParts = stablePart.Split('.').Length; + var versionParts = CountOccurrences(stablePart, '.'); switch (versionParts) { case 1: @@ -255,7 +255,7 @@ public static bool TryParse(string versionString, out FloatRange range) // replace the * with a 0 actualVersion += "0"; - var versionParts = actualVersion.Split('.').Length; + var versionParts = CountOccurrences(actualVersion, '.'); if (versionParts == 2) { @@ -314,6 +314,22 @@ public static bool TryParse(string versionString, out FloatRange range) return range != null; } + private static int CountOccurrences(string line, char ch) + { + var count = 0; + if (line != null) + { + for (var i = 0; i < line.Length; i++) + { + if (line[i] == ch) + { + count++; + } + } + } + return count; + } + /// /// Create a floating version string in the format: 1.0.0-alpha-* /// diff --git a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs index 0a4074a437c..c2b7afb7b82 100644 --- a/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Versioning.Test/FloatingRangeTests.cs @@ -480,7 +480,6 @@ public void FloatingRange_FloatAbsoluteLatest() [InlineData("1.1.0-beta.*", "1.1.0-beta.0")] [InlineData("1.1.*-beta.*", "1.1.0-beta.0")] [InlineData("*-beta.*", "0.0.0-beta.0")] - public void FloatRange_ParsesCorrectMinVersion(string versionRange, string normalizedMinVersion) { var range = FloatRange.Parse(versionRange); From 10e2b09d2a9050d4e1147a7b8fa2e66d8c4a431a Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Mon, 16 Mar 2020 18:11:35 -0700 Subject: [PATCH 12/12] fix off by 1 error --- src/NuGet.Core/NuGet.Versioning/FloatRange.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs index 67d24232c6c..3ccae205eb4 100644 --- a/src/NuGet.Core/NuGet.Versioning/FloatRange.cs +++ b/src/NuGet.Core/NuGet.Versioning/FloatRange.cs @@ -206,7 +206,7 @@ public static bool TryParse(string versionString, out FloatRange range) // Get the stable part. var stablePart = versionString.Substring(0, dashPosition - 1); // Get the part without the * stablePart += "0"; - var versionParts = CountOccurrences(stablePart, '.'); + var versionParts = CalculateVersionParts(stablePart); switch (versionParts) { case 1: @@ -255,7 +255,7 @@ public static bool TryParse(string versionString, out FloatRange range) // replace the * with a 0 actualVersion += "0"; - var versionParts = CountOccurrences(actualVersion, '.'); + var versionParts = CalculateVersionParts(actualVersion); if (versionParts == 2) { @@ -314,14 +314,14 @@ public static bool TryParse(string versionString, out FloatRange range) return range != null; } - private static int CountOccurrences(string line, char ch) + private static int CalculateVersionParts(string line) { - var count = 0; + var count = 1; if (line != null) { for (var i = 0; i < line.Length; i++) { - if (line[i] == ch) + if (line[i] == '.') { count++; }