add OSPlatform.macOS, switch to OrdinalIgnoreCase for OSPlatform comparisons (#39209)
authorAdam Sitnik <adam.sitnik@gmail.com>
Tue, 14 Jul 2020 17:06:23 +0000 (19:06 +0200)
committerGitHub <noreply@github.com>
Tue, 14 Jul 2020 17:06:23 +0000 (19:06 +0200)
* add OSPlatform.macOS, hide OSX

* use OrdinalIgnoreCase for platform name comparisons

* RuntimeInformation.IsOSPlatform(OSPlatform.macOS) must return true on OSX

* add new test cases for IsOSPlatformEarlierThan and IsOSPlatformOrLater

* cache the IsCurrent information

* apply code review suggestion

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
* apply code review suggestion

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs
src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/OSPlatform.cs
src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Browser.cs
src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Unix.cs
src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.Windows.cs
src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs
src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckPlatformTests.cs
src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/PlatformVersionTests.cs

index e9c675b61f2e895c5ee5cd88cad551ac8a60929d..46d2dd5159e22f07beb32f3112ffc387f90e2f68 100644 (file)
@@ -23,6 +23,8 @@ namespace System.Runtime.InteropServices
         public static System.Runtime.InteropServices.OSPlatform FreeBSD { get { throw null; } }
         public static System.Runtime.InteropServices.OSPlatform iOS { get { throw null; } }
         public static System.Runtime.InteropServices.OSPlatform Linux { get { throw null; } }
+        public static System.Runtime.InteropServices.OSPlatform macOS { get { throw null; } }
+        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
         public static System.Runtime.InteropServices.OSPlatform OSX { get { throw null; } }
         public static System.Runtime.InteropServices.OSPlatform tvOS { get { throw null; } }
         public static System.Runtime.InteropServices.OSPlatform watchOS { get { throw null; } }
index 39f956e164bd03474adf93ba6b70dcaecd2e7298..18e45643d216f4b66e63a198629aa4f6f8a7af87 100644 (file)
@@ -15,6 +15,9 @@ namespace System.Runtime.InteropServices
 
         public static OSPlatform Linux { get; } = new OSPlatform("LINUX");
 
+        public static OSPlatform macOS { get; } = new OSPlatform("MACOS");
+
+        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] // superseded by macOS
         public static OSPlatform OSX { get; } = new OSPlatform("OSX");
 
         public static OSPlatform iOS { get; } = new OSPlatform("IOS");
@@ -25,14 +28,21 @@ namespace System.Runtime.InteropServices
 
         public static OSPlatform Windows { get; } = new OSPlatform("WINDOWS");
 
+        internal bool IsCurrent { get; } // this information is cached because it's frequently used
+
         private OSPlatform(string osPlatform)
         {
             if (osPlatform == null) throw new ArgumentNullException(nameof(osPlatform));
             if (osPlatform.Length == 0) throw new ArgumentException(SR.Argument_EmptyValue, nameof(osPlatform));
 
             _osPlatform = osPlatform;
+            IsCurrent = RuntimeInformation.IsCurrentOSPlatform(osPlatform);
         }
 
+        /// <summary>
+        /// Creates a new OSPlatform instance.
+        /// </summary>
+        /// <remarks>If you plan to call this method frequently, please consider caching its result.</remarks>
         public static OSPlatform Create(string osPlatform)
         {
             return new OSPlatform(osPlatform);
@@ -45,17 +55,17 @@ namespace System.Runtime.InteropServices
 
         internal bool Equals(string? other)
         {
-            return string.Equals(_osPlatform, other, StringComparison.Ordinal);
+            return string.Equals(_osPlatform, other, StringComparison.OrdinalIgnoreCase);
         }
 
         public override bool Equals(object? obj)
         {
-            return obj is OSPlatform && Equals((OSPlatform)obj);
+            return obj is OSPlatform osPlatform && Equals(osPlatform);
         }
 
         public override int GetHashCode()
         {
-            return _osPlatform == null ? 0 : _osPlatform.GetHashCode();
+            return _osPlatform == null ? 0 : _osPlatform.GetHashCode(StringComparison.OrdinalIgnoreCase);
         }
 
         public override string ToString()
index 769d4ae38f30f9de86e7861e5d8ea33c0a34420e..838aa49c2e76ec10df4ed5beae996705279828bc 100644 (file)
@@ -5,7 +5,7 @@ namespace System.Runtime.InteropServices
 {
     public static partial class RuntimeInformation
     {
-        public static bool IsOSPlatform(OSPlatform osPlatform) => osPlatform.Equals(OSPlatform.Browser);
+        internal static bool IsCurrentOSPlatform(string osPlatform) => osPlatform.Equals("BROWSER", StringComparison.OrdinalIgnoreCase);
 
         public static string OSDescription => "Browser";
 
index c930aac925406339681ab3cd63bc89e0b67d1b70..ea7db57e016f815dca77a2d6971539e7b6bf2ce0 100644 (file)
@@ -14,10 +14,12 @@ namespace System.Runtime.InteropServices
         private static Architecture? s_osArch;
         private static Architecture? s_processArch;
 
-        public static bool IsOSPlatform(OSPlatform osPlatform)
+        internal static bool IsCurrentOSPlatform(string osPlatform)
         {
             string name = s_osPlatformName ??= Interop.Sys.GetUnixName();
-            return osPlatform.Equals(name);
+
+            return osPlatform.Equals(name, StringComparison.OrdinalIgnoreCase)
+                || (name == "OSX" && osPlatform.Equals("MACOS", StringComparison.OrdinalIgnoreCase)); // GetUnixName returns OSX on macOS
         }
 
         public static string OSDescription => s_osDescription ??= Interop.Sys.GetUnixVersion();
index 0ccc9deb93004744b128e03b77252a9228e67bff..7c71cc972aad5d9f396f8956061c1dbd57bec2f8 100644 (file)
@@ -13,10 +13,7 @@ namespace System.Runtime.InteropServices
         private static Architecture? s_osArch;
         private static Architecture? s_processArch;
 
-        public static bool IsOSPlatform(OSPlatform osPlatform)
-        {
-            return OSPlatform.Windows == osPlatform;
-        }
+        internal static bool IsCurrentOSPlatform(string osPlatform) => osPlatform.Equals("WINDOWS", StringComparison.OrdinalIgnoreCase);
 
         public static string OSDescription
         {
index 8e43d13ec4638904460ca9b892f8f141a403040f..95b1b62b4cdbe779f46018359f4e81da184f576d 100644 (file)
@@ -48,5 +48,10 @@ namespace System.Runtime.InteropServices
         /// </remarks>
         public static string RuntimeIdentifier =>
             s_runtimeIdentifier ??= AppContext.GetData("RUNTIME_IDENTIFIER") as string ?? "unknown";
+
+        /// <summary>
+        /// Indicates whether the current application is running on the specified platform.
+        /// </summary>
+        public static bool IsOSPlatform(OSPlatform osPlatform) => osPlatform.IsCurrent;
     }
 }
index 1264c5c0d850ad7d8abb8c55f6a21ccfdcb9e5d9..e40f9f8b310afe70c2a259a3a4eb8451d735f960 100644 (file)
@@ -1,7 +1,6 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Runtime.InteropServices;
 using Xunit;
 
 namespace System.Runtime.InteropServices.RuntimeInformationTests
@@ -13,10 +12,10 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
         {
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("LINUX")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("linux")));
 
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("DARWIN")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
-            Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("linux")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
@@ -31,9 +30,9 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
         public void CheckNetBSD()
         {
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
 
-            Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
-            Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("DARWIN")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("LINUX")));
@@ -51,12 +50,16 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
         {
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("OSX")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("osx")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("MACOS")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("macOS")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("macos")));
 
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
-            Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("osx")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("mac")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("DARWIN")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("MACOSX")));
@@ -70,6 +73,8 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
         {
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.iOS));
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("iOS")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")));
 
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
@@ -89,6 +94,8 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
         {
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.tvOS));
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("tvOS")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("tvos")));
 
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
@@ -108,6 +115,7 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
         {
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("android")));
 
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
@@ -127,6 +135,7 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
         {
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Browser));
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("browser")));
 
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
@@ -146,13 +155,14 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
         {
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
             Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("WINDOWS")));
+            Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("windows")));
 
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
-            Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("windows")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("Windows NT")));
+            Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("win")));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
             Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
@@ -213,5 +223,17 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
             Assert.Equal(0, defaultObj.GetHashCode());
             Assert.Equal(defaultObj.GetHashCode(), conObj.GetHashCode());
         }
+
+        [Fact]
+        public void StringComparisonOrdinalIgnoreCaseIsUsed()
+        {
+            Assert.Equal(OSPlatform.Create("A"), OSPlatform.Create("a"));
+            Assert.Equal(OSPlatform.Create("A"), OSPlatform.Create("A"));
+            Assert.Equal(OSPlatform.Create("a"), OSPlatform.Create("a"));
+
+            Assert.Equal(OSPlatform.Create("A").GetHashCode(), OSPlatform.Create("a").GetHashCode());
+            Assert.Equal(OSPlatform.Create("A").GetHashCode(), OSPlatform.Create("A").GetHashCode());
+            Assert.Equal(OSPlatform.Create("a").GetHashCode(), OSPlatform.Create("a").GetHashCode());
+        }
     }
 }
index c00ace31490338eea64b2ec8ced121e6c68f1710..b612d2e065bcbadeca857713fdb5890bb2a272a3 100644 (file)
@@ -14,6 +14,11 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
             yield return new object[] { OSPlatform.Linux };
             yield return new object[] { OSPlatform.OSX };
             yield return new object[] { OSPlatform.Browser };
+            yield return new object[] { OSPlatform.macOS };
+            yield return new object[] { OSPlatform.iOS };
+            yield return new object[] { OSPlatform.tvOS };
+            yield return new object[] { OSPlatform.watchOS };
+            yield return new object[] { OSPlatform.Android };
         }
 
         [Fact]
@@ -49,6 +54,8 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
             Version current = Environment.OSVersion.Version;
 
             Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{current}"));
+            Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToLower()}{current}"));
+            Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToUpper()}{current}"));
 
             Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, current.Major));
 
@@ -78,6 +85,8 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
 
             Version newer = new Version(currentVersion.Major + 1, 0);
             Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{newer}"));
+            Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToLower()}{newer}"));
+            Assert.False(RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToUpper()}{newer}"));
             Assert.False(RuntimeInformation.IsOSPlatformOrLater(osPlatform, newer.Major));
 
             newer = new Version(currentVersion.Major, currentVersion.Minor + 1);
@@ -104,6 +113,8 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
 
             Version older = new Version(current.Major - 1, 0);
             Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform}{older}"));
+            Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToLower()}{older}"));
+            Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater($"{osPlatform.ToString().ToUpper()}{older}"));
             Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformOrLater(osPlatform, older.Major));
 
             if (current.Minor > 0)
@@ -160,6 +171,8 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
             Version current = Environment.OSVersion.Version;
 
             Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{current}"));
+            Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToLower()}{current}"));
+            Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToUpper()}{current}"));
 
             Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, current.Major));
 
@@ -190,6 +203,8 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
 
             Version newer = new Version(current.Major + 1, 0);
             Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{newer}"));
+            Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToLower()}{newer}"));
+            Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToUpper()}{newer}"));
             Assert.Equal(isCurrentPlatfom, RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, newer.Major));
 
             newer = new Version(current.Major, current.Minor + 1);
@@ -215,6 +230,8 @@ namespace System.Runtime.InteropServices.RuntimeInformationTests
 
             Version older = new Version(current.Major - 1, 0);
             Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform}{older}"));
+            Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToLower()}{older}"));
+            Assert.False(RuntimeInformation.IsOSPlatformEarlierThan($"{osPlatform.ToString().ToUpper()}{older}"));
             Assert.False(RuntimeInformation.IsOSPlatformEarlierThan(osPlatform, older.Major));
 
             if (current.Minor > 0)