Skip to content

Commit

Permalink
Add support for platform versions
Browse files Browse the repository at this point in the history
  • Loading branch information
0xced committed Nov 29, 2024
1 parent 34c92ae commit 00b459f
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
49 changes: 48 additions & 1 deletion src/Xunit.SkippableFact/Sdk/TestMethodExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal static class TestMethodExtensions
AddPlatforms(platforms, testMethod.Method.GetCustomAttributes("System.Runtime.Versioning.SupportedOSPlatformAttribute"));
AddPlatforms(platforms, testMethod.Method.Type.GetCustomAttributes("System.Runtime.Versioning.SupportedOSPlatformAttribute"));

if (platforms.Count == 0 || platforms.Any(platform => RuntimeInformation.IsOSPlatform(OSPlatform.Create(platform))))
if (platforms.Count == 0 || platforms.Any(MatchesCurrentPlatform))
{
return null;
}
Expand All @@ -36,6 +36,53 @@ internal static class TestMethodExtensions
}

#if !NET462
private static bool MatchesCurrentPlatform(string platform)
{
int versionIndex = platform.IndexOfAny(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']);
bool matchesVersion;
if (versionIndex >= 0 && Version.TryParse(platform[versionIndex..], out Version version))
{
platform = platform[..versionIndex];
matchesVersion = MatchesCurrentVersion(version.Major, version.Minor, version.Build, version.Revision);
}
else
{
matchesVersion = true;
}

return matchesVersion && RuntimeInformation.IsOSPlatform(OSPlatform.Create(platform));
}

// Adapted from OperatingSystem.IsOSVersionAtLeast() which is private, see https://github.com/dotnet/runtime/blob/d6eb35426ebdb09ee5c754aa9afb9ad6e96a3dec/src/libraries/System.Private.CoreLib/src/System/OperatingSystem.cs#L326-L351
private static bool MatchesCurrentVersion(int major, int minor, int build, int revision)
{
Version current = Environment.OSVersion.Version;

if (current.Major != major)
{
return current.Major > major;
}

if (current.Minor != minor)
{
return current.Minor > minor;
}

// Unspecified build component is to be treated as zero
int currentBuild = current.Build < 0 ? 0 : current.Build;
build = build < 0 ? 0 : build;
if (currentBuild != build)
{
return currentBuild > build;
}

// Unspecified revision component is to be treated as zero
int currentRevision = current.Revision < 0 ? 0 : current.Revision;
revision = revision < 0 ? 0 : revision;

return currentRevision >= revision;
}

private static void AddPlatforms(HashSet<string> platforms, IEnumerable<IAttributeInfo> supportedPlatformAttributes)
{
foreach (IAttributeInfo supportedPlatformAttribute in supportedPlatformAttributes)
Expand Down
24 changes: 24 additions & 0 deletions test/Xunit.SkippableFact.Tests/SampleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,36 @@ public void MacOsOnly()
Assert.True(OperatingSystem.IsMacOS(), "This should only run on macOS");
}

[SkippableFact, SupportedOSPlatform("macOS10.6")]
public void MacOs10_6Minimum()
{
Assert.True(OperatingSystem.IsMacOSVersionAtLeast(10, 6), "This should only run on macOS 10.6 onwards");
}

[SkippableFact, SupportedOSPlatform("macOS77.7")]
public void MacOs77_7Minimum()
{
Assert.True(OperatingSystem.IsMacOSVersionAtLeast(77, 7), "This should only run on macOS 77.7 onwards");
}

[SkippableFact, SupportedOSPlatform("Windows")]
public void WindowsOnly()
{
Assert.True(OperatingSystem.IsWindows(), "This should only run on Windows");
}

[SkippableFact, SupportedOSPlatform("Windows10.0")]
public void Windows10Minimum()
{
Assert.True(OperatingSystem.IsWindowsVersionAtLeast(10), "This should only run on Windows 10.0 onwards");
}

[SkippableFact, SupportedOSPlatform("Windows77.7")]
public void Windows77_7Minimum()
{
Assert.True(OperatingSystem.IsWindowsVersionAtLeast(77, 7), "This should only run on Windows 77.7 onwards");
}

[SkippableFact, SupportedOSPlatform("Android"), SupportedOSPlatform("Browser")]
public void AndroidAndBrowserFact()
{
Expand Down

0 comments on commit 00b459f

Please sign in to comment.