From bfdb454ce83d8a4dd0c4336a1171df29279b6e8b Mon Sep 17 00:00:00 2001
From: sfoslund <sfoslund@microsoft.com>
Date: Wed, 22 Jan 2020 13:48:29 -0800
Subject: [PATCH 1/3] Adding test coverage and fix for bundle comparison issue

---
 .../Shared/BundleInfo/Bundle.cs               |  8 ++---
 .../Shared/VSVersioning/VSVersionTests.cs     | 33 +++++++++++++++++++
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/src/dotnet-core-uninstall/Shared/BundleInfo/Bundle.cs b/src/dotnet-core-uninstall/Shared/BundleInfo/Bundle.cs
index b65eeabf..c2394dfd 100644
--- a/src/dotnet-core-uninstall/Shared/BundleInfo/Bundle.cs
+++ b/src/dotnet-core-uninstall/Shared/BundleInfo/Bundle.cs
@@ -53,7 +53,7 @@ public override string ToString()
         }
     }
 
-    internal class Bundle<TBundleVersion> : Bundle, IComparable, IComparable<Bundle<TBundleVersion>>, IEquatable<Bundle<TBundleVersion>>
+    internal class Bundle<TBundleVersion> : Bundle, IComparable, IComparable<Bundle>, IEquatable<Bundle<TBundleVersion>>
         where TBundleVersion: BundleVersion, IComparable<TBundleVersion>
     {
         public new TBundleVersion Version => base.Version as TBundleVersion;
@@ -64,10 +64,10 @@ public Bundle(TBundleVersion version, BundleArch arch, string uninstallCommand,
 
         public int CompareTo(object obj)
         {
-            return CompareTo(obj as Bundle<TBundleVersion>);
+            return CompareTo(obj as Bundle);
         }
 
-        public int CompareTo(Bundle<TBundleVersion> other)
+        public int CompareTo(Bundle other)
         {
             if (other == null)
             {
@@ -76,7 +76,7 @@ public int CompareTo(Bundle<TBundleVersion> other)
 
             return Version.Equals(other.Version) ?
                 Arch - other.Arch :
-                Version.CompareTo(other.Version);
+                Version.SemVer.CompareTo(other.Version.SemVer);
         }
 
         public static IEnumerable<Bundle<TBundleVersion>> FilterWithSameBundleType(IEnumerable<Bundle> bundles)
diff --git a/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs b/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs
index 0a0bea2e..7125c465 100644
--- a/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs
+++ b/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs
@@ -259,5 +259,38 @@ private string[] ExpandExpectationShortHand(string[] input)
 
             return output;
         }
+
+        [Fact]
+        internal void TestUninstallableStringsCorrectManySDKs()
+        {
+            var bundles = new List<Bundle>
+            {
+                new Bundle<SdkVersion>(new SdkVersion("3.0.100-preview-0"), BundleArch.X64, string.Empty, "3.0.100"),
+                new Bundle<RuntimeVersion>(new RuntimeVersion("2.0.0"), BundleArch.X64, string.Empty, "2.0.0"),
+            };
+
+            for (int i = 0; i < 5; i++)
+            {
+                bundles.Add(new Bundle<SdkVersion>(new SdkVersion("2.0." + i), BundleArch.X64, string.Empty, "2.0." + i));
+                bundles.Add(new Bundle<SdkVersion>(new SdkVersion("2.0." + i + "-preview-0"), BundleArch.X64, string.Empty, "2.0." + i + "-preview-0"));
+                bundles.Add(new Bundle<SdkVersion>(new SdkVersion("2.0." + i + "-preview-1"), BundleArch.X64, string.Empty, "2.0." + i + "-preview-1"));
+            }
+
+            var strings = VisualStudioSafeVersionsExtractor.GetReasonRequiredStrings(bundles);
+            strings.Count.Should().Be(bundles.Count);
+
+            var expectedProtected = new string[]{ "3.0.100", "2.0.4" };
+            var expectedUninstallable = bundles.Select(bundle => bundle.DisplayName)
+                .Except(expectedProtected);
+
+            strings.Where(pair => pair.Key.Version is SdkVersion)
+                .Where(pair => string.IsNullOrEmpty(pair.Value))
+                .Select(pair => pair.Key.DisplayName)
+                .Should().BeEquivalentTo(expectedUninstallable);
+            
+            strings.Where(pair => !string.IsNullOrEmpty(pair.Value))
+                .Select(pair => pair.Key.DisplayName)
+                .Should().BeEquivalentTo(expectedProtected);
+        }
     }
 }

From 0f8d01e17d70695334ef308a7c65846c07836cfe Mon Sep 17 00:00:00 2001
From: sfoslund <sfoslund@microsoft.com>
Date: Wed, 22 Jan 2020 14:13:27 -0800
Subject: [PATCH 2/3] Fixing and adding test coverage for preview issue between
 requirement divisions

---
 .../BundleInfo/Versioning/BundleVersion.cs    |  5 ++++
 .../VisualStudioSafeVersionsExtractor.cs      |  3 +-
 .../Shared/VSVersioning/VSVersionTests.cs     | 28 +++++++++++++++++--
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/dotnet-core-uninstall/Shared/BundleInfo/Versioning/BundleVersion.cs b/src/dotnet-core-uninstall/Shared/BundleInfo/Versioning/BundleVersion.cs
index 4cb6bd5b..cb86990f 100644
--- a/src/dotnet-core-uninstall/Shared/BundleInfo/Versioning/BundleVersion.cs
+++ b/src/dotnet-core-uninstall/Shared/BundleInfo/Versioning/BundleVersion.cs
@@ -93,5 +93,10 @@ public override int GetHashCode()
         }
 
         public abstract Bundle ToBundle(BundleArch arch, string uninstallCommand, string displayName);
+
+        public SemanticVersion GetVersionWithoutTags()
+        {
+            return new SemanticVersion(this.Major, this.Minor, this.SemVer.Patch);
+        }
     }
 }
diff --git a/src/dotnet-core-uninstall/Shared/VSVersioning/VisualStudioSafeVersionsExtractor.cs b/src/dotnet-core-uninstall/Shared/VSVersioning/VisualStudioSafeVersionsExtractor.cs
index 488388ef..7a9c0d45 100644
--- a/src/dotnet-core-uninstall/Shared/VSVersioning/VisualStudioSafeVersionsExtractor.cs
+++ b/src/dotnet-core-uninstall/Shared/VSVersioning/VisualStudioSafeVersionsExtractor.cs
@@ -30,7 +30,8 @@ private static (IDictionary<IEnumerable<Bundle>, string>, IEnumerable<Bundle>) A
             var dividedBundles = new Dictionary<IEnumerable<Bundle>, string>();
             foreach (var (division, explaination) in WindowsVersionDivisionsToExplaination)
             {
-                var bundlesInRange = bundleList.Where(bundle => bundle.Version is SdkVersion && division.Item1 <= bundle.Version.SemVer && bundle.Version.SemVer < division.Item2);
+                var bundlesInRange = bundleList.Where(bundle => bundle.Version is SdkVersion && 
+                                                      division.Item1 <= bundle.Version.GetVersionWithoutTags() && bundle.Version.GetVersionWithoutTags() < division.Item2);
                 bundleList = bundleList.Except(bundlesInRange);
                 if (bundlesInRange.Count() > 0)
                 {
diff --git a/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs b/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs
index 7125c465..12370f6b 100644
--- a/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs
+++ b/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs
@@ -280,15 +280,37 @@ internal void TestUninstallableStringsCorrectManySDKs()
             strings.Count.Should().Be(bundles.Count);
 
             var expectedProtected = new string[]{ "3.0.100", "2.0.4" };
+            AssertRequirementStringsCorrect(bundles, strings, expectedProtected);
+        }
+
+        [Fact]
+        internal void TestUninstallableStringsCorrectAcrossRequirementDivisions()
+        {
+            var bundles = new List<Bundle>
+            {
+                new Bundle<SdkVersion>(new SdkVersion("2.0.0"), BundleArch.X64, string.Empty, "2.0.0"),
+                new Bundle<SdkVersion>(new SdkVersion("2.0.0-preview-0"), BundleArch.X64, string.Empty, "2.0.0-preview-0"),
+                new Bundle<SdkVersion>(new SdkVersion("2.0.0-preview-1"), BundleArch.X64, string.Empty, "2.0.0-preview-1")
+            };
+
+            var strings = VisualStudioSafeVersionsExtractor.GetReasonRequiredStrings(bundles);
+            var expectedProtected = new string[] { "2.0.0" };
+            AssertRequirementStringsCorrect(bundles, strings, expectedProtected);
+        }
+
+        private void AssertRequirementStringsCorrect(List<Bundle> bundles, Dictionary<Bundle, string> bundleStringPairs, string[] expectedProtected)
+        {
+            bundleStringPairs.Count.Should().Be(bundles.Count);
+
             var expectedUninstallable = bundles.Select(bundle => bundle.DisplayName)
                 .Except(expectedProtected);
 
-            strings.Where(pair => pair.Key.Version is SdkVersion)
+            bundleStringPairs.Where(pair => pair.Key.Version is SdkVersion)
                 .Where(pair => string.IsNullOrEmpty(pair.Value))
                 .Select(pair => pair.Key.DisplayName)
                 .Should().BeEquivalentTo(expectedUninstallable);
-            
-            strings.Where(pair => !string.IsNullOrEmpty(pair.Value))
+
+            bundleStringPairs.Where(pair => !string.IsNullOrEmpty(pair.Value))
                 .Select(pair => pair.Key.DisplayName)
                 .Should().BeEquivalentTo(expectedProtected);
         }

From e0f466c1996dc12899d21877e1ac537af3047a4b Mon Sep 17 00:00:00 2001
From: sfoslund <sfoslund@microsoft.com>
Date: Wed, 22 Jan 2020 14:36:24 -0800
Subject: [PATCH 3/3] Adding windows only tags to new windows only tests

---
 .../Shared/VSVersioning/VSVersionTests.cs                     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs b/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs
index 12370f6b..ceb8bf15 100644
--- a/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs
+++ b/test/dotnet-core-uninstall.Tests/Shared/VSVersioning/VSVersionTests.cs
@@ -260,7 +260,7 @@ private string[] ExpandExpectationShortHand(string[] input)
             return output;
         }
 
-        [Fact]
+        [WindowsOnlyFact]
         internal void TestUninstallableStringsCorrectManySDKs()
         {
             var bundles = new List<Bundle>
@@ -283,7 +283,7 @@ internal void TestUninstallableStringsCorrectManySDKs()
             AssertRequirementStringsCorrect(bundles, strings, expectedProtected);
         }
 
-        [Fact]
+        [WindowsOnlyFact]
         internal void TestUninstallableStringsCorrectAcrossRequirementDivisions()
         {
             var bundles = new List<Bundle>