Skip to content

Commit

Permalink
Introduction of read-only struct TargetFramework
Browse files Browse the repository at this point in the history
It represents the and its domain concerns. Can be extended later.
  • Loading branch information
Corniel committed Feb 18, 2024
1 parent 35f12d2 commit 0080c28
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/Buildalyzer/TargetFramework.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#nullable enable

using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;

namespace Buildalyzer;

/// <summary>Represents the target framework.</summary>
public readonly struct TargetFramework : IEquatable<TargetFramework>
{
/// <summary>No target framework.</summary>
public static TargetFramework None { get; }

private TargetFramework(string name) => _name = name;

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly string? _name;

/// <summary>Indicates that the target framework is .NET (classic) framework version.</summary>
/// <remarks>
/// Because the .NET Core/.NET 5 TFMs are better defined, we just check if this is one of them and then negate.
/// </remarks>
public bool IsNetFramework
=> _name is { Length: >= 2 }
&& !IsNetCoreApp
&& !IsNetStandard
&& !IsNet;

public bool IsNetCoreApp
=> _name is { Length: 14 }
&& _name.StartsWith("netcoreapp");

public bool IsNetStandard
=> _name is { Length: 14 }
&& _name.StartsWith("netstandard");

public bool IsNet
=> _name is { Length: 14 }
&& _name.StartsWith("net")
&& int.TryParse(_name[3..3], out int version)
&& version >= 5;

/// <inheritdoc />
[Pure]
public override bool Equals([NotNullWhen(true)] object? obj)
=> obj is TargetFramework other
&& Equals(other);

/// <inheritdoc />
[Pure]
public bool Equals(TargetFramework other) => _name == other._name;

/// <inheritdoc />
[Pure]
public override int GetHashCode() => HashCode.Combine(_name);

/// <inheritdoc />
[Pure]
public override string ToString() => _name ?? string.Empty;

[Pure]
public static TargetFramework Parse(string? s)
=> s is { Length: > 0 }
? new TargetFramework(s.ToLowerInvariant())
: None;
}
105 changes: 105 additions & 0 deletions tests/Buildalyzer.Tests/TargetFrameworkFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using NUnit.Framework;
using Shouldly;

namespace Buildalyzer.Tests;

/// <remarks>
/// From https://docs.microsoft.com/en-us/dotnet/standard/frameworks.
/// </remarks>
[TestFixture]
public class TargetFrameworkFixture
{
[TestCase("netstandard1.0")]
[TestCase("netstandard1.1")]
[TestCase("netstandard1.2")]
[TestCase("netstandard1.3")]
[TestCase("netstandard1.4")]
[TestCase("netstandard1.5")]
[TestCase("netstandard1.6")]
[TestCase("netstandard2.0")]
[TestCase("netstandard2.1")]
public void NetStandard(string s)
{
var tfm = TargetFramework.Parse(s);

Check failure on line 23 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)

Check failure on line 23 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (macos-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)
tfm.IsNetFramework.ShouldBeFalse();
tfm.IsNetStandard.ShouldBeTrue();
}

[TestCase("netcoreapp1.0")]
[TestCase("netcoreapp1.1")]
[TestCase("netcoreapp2.0")]
[TestCase("netcoreapp2.1")]
[TestCase("netcoreapp2.2")]
[TestCase("netcoreapp3.0")]
[TestCase("netcoreapp3.1")]
public void NetCoreApp(string s)
{
var tfm = TargetFramework.Parse(s);

Check failure on line 37 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)

Check failure on line 37 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (macos-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)
tfm.IsNetFramework.ShouldBeFalse();
tfm.IsNetCoreApp.ShouldBeTrue();
}

[TestCase("net5")] // This isn't an official TFM but we'll check it anyway
[TestCase("net5.0")]
[TestCase("net5.0-android")]
[TestCase("net5.0-ios")]
[TestCase("net5.0-macos")]
[TestCase("net5.0-tvos")]
[TestCase("net5.0-watchos")]
[TestCase("net5.0-windows")]
[TestCase("net6")] // This isn't an official TFM but we'll check it anyway
[TestCase("net6.0")]
[TestCase("net6.0-android")]
[TestCase("net6.0-ios")]
[TestCase("net6.0-macos")]
[TestCase("net6.0-tvos")]
[TestCase("net6.0-watchos")]
[TestCase("net6.0-windows")]
public void Net(string s)
{
var tfm = TargetFramework.Parse(s);

Check failure on line 60 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)

Check failure on line 60 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (macos-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)
tfm.IsNetFramework.ShouldBeFalse();
tfm.IsNet.ShouldBeTrue();
}

[TestCase("net11")]
[TestCase("net20")]
[TestCase("net35")]
[TestCase("net40")]
[TestCase("net403")]
[TestCase("net45")]
[TestCase("net451")]
[TestCase("net452")]
[TestCase("net46")]
[TestCase("net461")]
[TestCase("net462")]
[TestCase("net47")]
[TestCase("net471")]
[TestCase("net472")]
[TestCase("net48")]
public void DotNetFramework(string s)
{
var tfm = TargetFramework.Parse(s);

Check failure on line 82 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)

Check failure on line 82 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (macos-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)
tfm.IsNetFramework.ShouldBeTrue();
}

[TestCase("netcore")]
[TestCase("netcore45")]
[TestCase("netcore451")]
[TestCase("netmf")]
[TestCase("sl4")]
[TestCase("sl5")]
[TestCase("wp")]
[TestCase("wp7")]
[TestCase("wp75")]
[TestCase("wp8")]
[TestCase("wp81")]
[TestCase("wpa81")]
[TestCase("uap")]
[TestCase("uap10.0")]
public void Exotic(string s)
{
var tfm = TargetFramework.Parse(s);

Check failure on line 102 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)

Check failure on line 102 in tests/Buildalyzer.Tests/TargetFrameworkFixture.cs

View workflow job for this annotation

GitHub Actions / Build (macos-latest)

Use explicit type instead of 'var'. (http://pihrt.net/roslynator/analyzer?id=RCS1012)
tfm.IsNetFramework.ShouldBeTrue();
}
}

0 comments on commit 0080c28

Please sign in to comment.