diff --git a/Directory.Packages.props b/Directory.Packages.props index 1bf3754091..32e7eca252 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -46,6 +46,7 @@ + @@ -70,4 +71,4 @@ - + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers/MSTest.Analyzers.csproj b/src/Analyzers/MSTest.Analyzers/MSTest.Analyzers.csproj index 1c374e14e7..967d56d384 100644 --- a/src/Analyzers/MSTest.Analyzers/MSTest.Analyzers.csproj +++ b/src/Analyzers/MSTest.Analyzers/MSTest.Analyzers.csproj @@ -12,7 +12,6 @@ - @@ -23,6 +22,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Analyzers/MSTest.Analyzers/PublicAPI.Shipped.txt b/src/Analyzers/MSTest.Analyzers/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..ab058de62d --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt b/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..26bed6ed4c --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt @@ -0,0 +1,114 @@ +#nullable enable +Analyzer.Utilities.WellKnownTypeProvider +Analyzer.Utilities.WellKnownTypeProvider.Compilation.get -> Microsoft.CodeAnalysis.Compilation! +Analyzer.Utilities.WellKnownTypeProvider.GetOrCreateTypeByMetadataName(string! fullTypeName) -> Microsoft.CodeAnalysis.INamedTypeSymbol? +Analyzer.Utilities.WellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(string! fullTypeName, out Microsoft.CodeAnalysis.INamedTypeSymbol? namedTypeSymbol) -> bool +MSTest.Analyzers.AssemblyCleanupShouldBeValidAnalyzer +MSTest.Analyzers.AssemblyCleanupShouldBeValidAnalyzer.AssemblyCleanupShouldBeValidAnalyzer() -> void +MSTest.Analyzers.AssemblyInitializeShouldBeValidAnalyzer +MSTest.Analyzers.AssemblyInitializeShouldBeValidAnalyzer.AssemblyInitializeShouldBeValidAnalyzer() -> void +MSTest.Analyzers.AssertionArgsShouldAvoidConditionalAccessAnalyzer +MSTest.Analyzers.AssertionArgsShouldAvoidConditionalAccessAnalyzer.AssertionArgsShouldAvoidConditionalAccessAnalyzer() -> void +MSTest.Analyzers.AssertionArgsShouldBePassedInCorrectOrderAnalyzer +MSTest.Analyzers.AssertionArgsShouldBePassedInCorrectOrderAnalyzer.AssertionArgsShouldBePassedInCorrectOrderAnalyzer() -> void +MSTest.Analyzers.AvoidExpectedExceptionAttributeAnalyzer +MSTest.Analyzers.AvoidExpectedExceptionAttributeAnalyzer.AvoidExpectedExceptionAttributeAnalyzer() -> void +MSTest.Analyzers.ClassCleanupShouldBeValidAnalyzer +MSTest.Analyzers.ClassCleanupShouldBeValidAnalyzer.ClassCleanupShouldBeValidAnalyzer() -> void +MSTest.Analyzers.ClassInitializeShouldBeValidAnalyzer +MSTest.Analyzers.ClassInitializeShouldBeValidAnalyzer.ClassInitializeShouldBeValidAnalyzer() -> void +MSTest.Analyzers.DataRowShouldBeValidAnalyzer +MSTest.Analyzers.DataRowShouldBeValidAnalyzer.DataRowShouldBeValidAnalyzer() -> void +MSTest.Analyzers.DoNotNegateBooleanAssertionAnalyzer +MSTest.Analyzers.DoNotNegateBooleanAssertionAnalyzer.DoNotNegateBooleanAssertionAnalyzer() -> void +MSTest.Analyzers.DoNotStoreStaticTestContextAnalyzer +MSTest.Analyzers.DoNotStoreStaticTestContextAnalyzer.DoNotStoreStaticTestContextAnalyzer() -> void +MSTest.Analyzers.PreferAssertFailOverAlwaysFalseConditionsAnalyzer +MSTest.Analyzers.PreferAssertFailOverAlwaysFalseConditionsAnalyzer.PreferAssertFailOverAlwaysFalseConditionsAnalyzer() -> void +MSTest.Analyzers.PreferConstructorOverTestInitializeAnalyzer +MSTest.Analyzers.PreferConstructorOverTestInitializeAnalyzer.PreferConstructorOverTestInitializeAnalyzer() -> void +MSTest.Analyzers.PreferDisposeOverTestCleanupAnalyzer +MSTest.Analyzers.PreferDisposeOverTestCleanupAnalyzer.PreferDisposeOverTestCleanupAnalyzer() -> void +MSTest.Analyzers.PreferTestCleanupOverDisposeAnalyzer +MSTest.Analyzers.PreferTestCleanupOverDisposeAnalyzer.PreferTestCleanupOverDisposeAnalyzer() -> void +MSTest.Analyzers.PreferTestInitializeOverConstructorAnalyzer +MSTest.Analyzers.PreferTestInitializeOverConstructorAnalyzer.PreferTestInitializeOverConstructorAnalyzer() -> void +MSTest.Analyzers.PublicTypeShouldBeTestClassAnalyzer +MSTest.Analyzers.PublicTypeShouldBeTestClassAnalyzer.PublicTypeShouldBeTestClassAnalyzer() -> void +MSTest.Analyzers.TestClassShouldBeValidAnalyzer +MSTest.Analyzers.TestClassShouldBeValidAnalyzer.TestClassShouldBeValidAnalyzer() -> void +MSTest.Analyzers.TestClassShouldHaveTestMethodAnalyzer +MSTest.Analyzers.TestClassShouldHaveTestMethodAnalyzer.TestClassShouldHaveTestMethodAnalyzer() -> void +MSTest.Analyzers.TestCleanupShouldBeValidAnalyzer +MSTest.Analyzers.TestCleanupShouldBeValidAnalyzer.TestCleanupShouldBeValidAnalyzer() -> void +MSTest.Analyzers.TestContextShouldBeValidAnalyzer +MSTest.Analyzers.TestContextShouldBeValidAnalyzer.TestContextShouldBeValidAnalyzer() -> void +MSTest.Analyzers.TestInitializeShouldBeValidAnalyzer +MSTest.Analyzers.TestInitializeShouldBeValidAnalyzer.TestInitializeShouldBeValidAnalyzer() -> void +MSTest.Analyzers.TestMethodShouldBeValidAnalyzer +MSTest.Analyzers.TestMethodShouldBeValidAnalyzer.TestMethodShouldBeValidAnalyzer() -> void +MSTest.Analyzers.TestMethodShouldNotBeIgnoredAnalyzer +MSTest.Analyzers.TestMethodShouldNotBeIgnoredAnalyzer.TestMethodShouldNotBeIgnoredAnalyzer() -> void +MSTest.Analyzers.UseAsyncSuffixTestFixtureMethodSuppressor +MSTest.Analyzers.UseAsyncSuffixTestFixtureMethodSuppressor.UseAsyncSuffixTestFixtureMethodSuppressor() -> void +MSTest.Analyzers.UseAsyncSuffixTestMethodSuppressor +MSTest.Analyzers.UseAsyncSuffixTestMethodSuppressor.UseAsyncSuffixTestMethodSuppressor() -> void +MSTest.Analyzers.UseAttributeOnTestMethodAnalyzer +MSTest.Analyzers.UseAttributeOnTestMethodAnalyzer.UseAttributeOnTestMethodAnalyzer() -> void +MSTest.Analyzers.UseParallelizeAttributeAnalyzer +MSTest.Analyzers.UseParallelizeAttributeAnalyzer.UseParallelizeAttributeAnalyzer() -> void +override MSTest.Analyzers.AssemblyCleanupShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.AssemblyCleanupShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.AssemblyInitializeShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.AssemblyInitializeShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.AssertionArgsShouldAvoidConditionalAccessAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.AssertionArgsShouldAvoidConditionalAccessAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.AssertionArgsShouldBePassedInCorrectOrderAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.AssertionArgsShouldBePassedInCorrectOrderAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.AvoidExpectedExceptionAttributeAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.AvoidExpectedExceptionAttributeAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.ClassCleanupShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.ClassCleanupShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.ClassInitializeShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.ClassInitializeShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.DataRowShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.DataRowShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.DoNotNegateBooleanAssertionAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.DoNotNegateBooleanAssertionAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.DoNotStoreStaticTestContextAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.DoNotStoreStaticTestContextAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.PreferAssertFailOverAlwaysFalseConditionsAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.PreferAssertFailOverAlwaysFalseConditionsAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.PreferConstructorOverTestInitializeAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.PreferConstructorOverTestInitializeAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.PreferDisposeOverTestCleanupAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.PreferDisposeOverTestCleanupAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.PreferTestCleanupOverDisposeAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.PreferTestCleanupOverDisposeAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.PreferTestInitializeOverConstructorAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.PreferTestInitializeOverConstructorAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.PublicTypeShouldBeTestClassAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.PublicTypeShouldBeTestClassAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.TestClassShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.TestClassShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.TestClassShouldHaveTestMethodAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.TestClassShouldHaveTestMethodAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.TestCleanupShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.TestCleanupShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.TestContextShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.TestContextShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.TestInitializeShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.TestInitializeShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.TestMethodShouldBeValidAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.TestMethodShouldBeValidAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.TestMethodShouldNotBeIgnoredAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.TestMethodShouldNotBeIgnoredAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.UseAsyncSuffixTestFixtureMethodSuppressor.ReportSuppressions(Microsoft.CodeAnalysis.Diagnostics.SuppressionAnalysisContext context) -> void +override MSTest.Analyzers.UseAsyncSuffixTestFixtureMethodSuppressor.SupportedSuppressions.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.UseAsyncSuffixTestMethodSuppressor.ReportSuppressions(Microsoft.CodeAnalysis.Diagnostics.SuppressionAnalysisContext context) -> void +override MSTest.Analyzers.UseAsyncSuffixTestMethodSuppressor.SupportedSuppressions.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.UseAttributeOnTestMethodAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.UseAttributeOnTestMethodAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +override MSTest.Analyzers.UseParallelizeAttributeAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.UseParallelizeAttributeAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray +static Analyzer.Utilities.WellKnownTypeProvider.GetOrCreate(Microsoft.CodeAnalysis.Compilation! compilation) -> Analyzer.Utilities.WellKnownTypeProvider! diff --git a/src/Platform/Microsoft.Testing.Platform/GlobalSuppressions.cs b/src/Platform/Microsoft.Testing.Platform/GlobalSuppressions.cs new file mode 100644 index 0000000000..88264da4f7 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Diagnostics.CodeAnalysis; + +// We usually do not want to suppress issues through GlobalSuppressions file but in this case we have to do it because +// we are not able to suppress the issue differently. +[assembly: SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "Source-generated file that cannot match analyzers requirements", Scope = "member", Target = "~M:System.Reflection.NullabilityInfoContext.CheckParameterMetadataType(System.Reflection.ParameterInfo,System.Reflection.NullabilityInfo)")] diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/HashCode.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/HashCode.cs new file mode 100644 index 0000000000..b90376e9ac --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/HashCode.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#if !NETCOREAPP +namespace System; + +// https://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-overriding-gethashcode/263416#263416 +internal struct HashCode +{ + private int _hash; + + public HashCode() + { + _hash = 17; + } + + public void Add(string value) + { + // Overflow is fine, just wrap + unchecked + { + _hash = (_hash * 23) + (value?.GetHashCode() ?? 0); + } + } + + public void Add(bool value) + { + // Overflow is fine, just wrap + unchecked + { + _hash = (_hash * 23) + value.GetHashCode(); + } + } + + public void Add(int value) + { + // Overflow is fine, just wrap + unchecked + { + _hash = (_hash * 23) + value.GetHashCode(); + } + } + + public readonly int ToHashCode() + => _hash; +} +#endif diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/StringBuilderExtensions.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/StringBuilderExtensions.cs new file mode 100644 index 0000000000..115d107015 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/StringBuilderExtensions.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#if !NETCOREAPP +namespace System.Text; + +internal static class StringBuilderExtensions +{ + public static StringBuilder Append(this StringBuilder builder, IFormatProvider? _, string value) + => builder.Append(value); + + public static StringBuilder AppendLine(this StringBuilder builder, IFormatProvider? _, string value) + => builder.AppendLine(value); +} +#endif diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/SystemPolyfills.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/SystemPolyfills.cs deleted file mode 100644 index b91c8babdb..0000000000 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/SystemPolyfills.cs +++ /dev/null @@ -1,569 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma warning disable SA1201 // Elements should appear in the correct order -#pragma warning disable SA1313 // Parameter names should begin with lower-case letter -#pragma warning disable SA1403 // File may only contain a single namespace -#pragma warning disable SA1502 // Element should not be on a single line -#pragma warning disable SA1623 // Property summary documentation should match accessors -#pragma warning disable SA1642 // Constructor summary documentation should begin with standard text -#pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved - -#if !NETCOREAPP -using System.ComponentModel; -#if !NET462 -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; - -using Microsoft.Testing.Platform; -#endif - -namespace System.Runtime.CompilerServices -{ - [EditorBrowsable(EditorBrowsableState.Never)] - internal class IsExternalInit { } - - [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] - internal sealed class CallerArgumentExpressionAttribute : Attribute - { - public CallerArgumentExpressionAttribute(string parameterName) - { - ParameterName = parameterName; - } - - public string ParameterName { get; } - } -} - -namespace System -{ - // https://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-overriding-gethashcode/263416#263416 - internal struct HashCode - { - private int _hash; - - public HashCode() - { - _hash = 17; - } - - public void Add(string value) - { - // Overflow is fine, just wrap - unchecked - { - _hash = (_hash * 23) + (value?.GetHashCode() ?? 0); - } - } - - public void Add(bool value) - { - // Overflow is fine, just wrap - unchecked - { - _hash = (_hash * 23) + value.GetHashCode(); - } - } - - public void Add(int value) - { - // Overflow is fine, just wrap - unchecked - { - _hash = (_hash * 23) + value.GetHashCode(); - } - } - - public readonly int ToHashCode() - => _hash; - } - -#if !NET462 - /// Represent a type can be used to index a collection either from the start or the end. - /// - /// Index is used by the C# compiler to support the new index syntax. - /// - /// int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ; - /// int lastElement = someArray[^1]; // lastElement = 5 - /// - /// - [SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Matches implementation from dotnet/runtime")] - [SuppressMessage("Usage", "CA2231:Overload operator equals on overriding value type Equals", Justification = "Matches implementation from dotnet/runtime")] - internal readonly struct Index : IEquatable - { - private readonly int _value; - - /// Initializes a new instance of the struct.Construct an Index using a value and indicating if the index is from the start or from the end. - /// The index value. it has to be zero or positive number. - /// Indicating if the index is from the start or from the end. - /// - /// If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Index(int value, bool fromEnd = false) - { - if (value < 0) - { - throw new ArgumentOutOfRangeException(nameof(value), value, "Non-negative number required."); - } - - _value = fromEnd ? ~value : value; - } - - // The following private constructors mainly created for perf reason to avoid the checks - private Index(int value) - { - _value = value; - } - - /// Gets create an Index pointing at first element. - public static Index Start => new(0); - - /// Gets create an Index pointing at beyond last element. - public static Index End => new(~0); - - /// Create an Index from the start at the position indicated by the value. - /// The index value from the start. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Index FromStart(int value) - => value < 0 - ? throw new ArgumentOutOfRangeException(nameof(value), value, "Non-negative number required.") - : new Index(value); - - /// Create an Index from the end at the position indicated by the value. - /// The index value from the end. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Index FromEnd(int value) - => value < 0 - ? throw new ArgumentOutOfRangeException(nameof(value), value, "Non-negative number required.") - : new Index(~value); - - /// Gets the index value. - public int Value => _value < 0 ? ~_value : _value; - - /// Gets a value indicating whether indicates whether the index is from the start or the end. - public bool IsFromEnd => _value < 0; - - /// Calculate the offset from the start using the giving collection length. - /// The length of the collection that the Index will be used with. length has to be a positive value. - /// - /// For performance reason, we don't validate the input length parameter and the returned offset value against negative values. - /// we don't validate either the returned offset is greater than the input length. - /// It is expected Index will be used with collections which always have non negative length/count. If the returned offset is negative and - /// then used to index a collection will get out of range exception which will be same affect as the validation. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int GetOffset(int length) - { - int offset = _value; - if (IsFromEnd) - { - // offset = length - (~value) - // offset = length + (~(~value) + 1) - // offset = length + value + 1 - offset += length + 1; - } - - return offset; - } - - /// Indicates whether the current Index object is equal to another object of the same type. - /// An object to compare with this object. - public override bool Equals(object? obj) => obj is Index index && _value == index._value; - - /// Indicates whether the current Index object is equal to another Index object. - /// An object to compare with this object. - public bool Equals(Index other) => _value == other._value; - - /// Returns the hash code for this instance. - public override int GetHashCode() => _value; - - /// Converts integer number to an Index. - [SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Matches implementation from dotnet/runtime")] - public static implicit operator Index(int value) => FromStart(value); - - /// Converts the value of the current Index object to its equivalent string representation. - [SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "Matches implementation from dotnet/runtime")] - public override string ToString() - => IsFromEnd - ? '^' + Value.ToString() - : ((uint)Value).ToString(); - } - - /// Represent a range has start and end indexes. - /// - /// Range is used by the C# compiler to support the range syntax. - /// - /// int[] someArray = new int[5] { 1, 2, 3, 4, 5 }; - /// int[] subArray1 = someArray[0..2]; // { 1, 2 } - /// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 } - /// - /// - [SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Matches implementation from dotnet/runtime")] - [SuppressMessage("Usage", "CA2231:Overload operator equals on overriding value type Equals", Justification = "Matches implementation from dotnet/runtime")] - internal readonly struct Range : IEquatable - { - /// Gets represent the inclusive start index of the Range. - public Index Start { get; } - - /// Gets represent the exclusive end index of the Range. - public Index End { get; } - - /// Initializes a new instance of the struct.Construct a Range object using the start and end indexes. - /// Represent the inclusive start index of the range. - /// Represent the exclusive end index of the range. - public Range(Index start, Index end) - { - Start = start; - End = end; - } - - /// Indicates whether the current Range object is equal to another object of the same type. - /// An object to compare with this object. - public override bool Equals(object? obj) => - obj is Range r && - r.Start.Equals(Start) && - r.End.Equals(End); - - /// Indicates whether the current Range object is equal to another Range object. - /// An object to compare with this object. - public bool Equals(Range other) => other.Start.Equals(Start) && other.End.Equals(End); - - /// Returns the hash code for this instance. - public override int GetHashCode() - => RoslynHashCode.Combine(Start.GetHashCode(), End.GetHashCode()); - - /// Converts the value of the current Range object to its equivalent string representation. - public override string ToString() - => $"{Start}..{End}"; - - /// Create a Range object starting from start index to the end of the collection. - public static Range StartAt(Index start) => new(start, Index.End); - - /// Create a Range object starting from first element in the collection to the end Index. - public static Range EndAt(Index end) => new(Index.Start, end); - - /// Gets create a Range object starting from first element to the end. - public static Range All => new(Index.Start, Index.End); - - /// Calculate the start offset and length of range object using a collection length. - /// The length of the collection that the range will be used with. length has to be a positive value. - /// - /// For performance reason, we don't validate the input length parameter against negative values. - /// It is expected Range will be used with collections which always have non negative length/count. - /// We validate the range is inside the length scope though. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public (int Offset, int Length) GetOffsetAndLength(int length) - { - int start; - Index startIndex = Start; - start = startIndex.IsFromEnd - ? length - startIndex.Value - : startIndex.Value; - - int end; - Index endIndex = End; - end = endIndex.IsFromEnd - ? length - endIndex.Value - : endIndex.Value; - - return (uint)end > (uint)length || (uint)start > (uint)end - ? throw new ArgumentOutOfRangeException(nameof(length)) - : (start, end - start); - } - } -#endif -} - -// This was copied from https://github.com/dotnet/coreclr/blob/60f1e6265bd1039f023a82e0643b524d6aaf7845/src/System.Private.CoreLib/shared/System/Diagnostics/CodeAnalysis/NullableAttributes.cs -// and updated to have the scope of the attributes be internal. -namespace System.Diagnostics.CodeAnalysis -{ - /// Specifies that null is allowed as an input even if the corresponding type disallows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] - internal sealed class AllowNullAttribute : Attribute { } -#pragma warning restore SA1502 // Element should not be on a single line - - /// Specifies that null is disallowed as an input even if the corresponding type allows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] - internal sealed class DisallowNullAttribute : Attribute - { - } - - /// Specifies that an output may be null even if the corresponding type disallows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] - internal sealed class MaybeNullAttribute : Attribute - { - } - - /// Specifies that an output will not be null even if the corresponding type allows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] - internal sealed class NotNullAttribute : Attribute - { - } - - /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] - internal sealed class MaybeNullWhenAttribute : Attribute - { - /// Initializes a new instance of the class.Initializes the attribute with the specified return value condition. - /// - /// The return value condition. If the method returns this value, the associated parameter may be null. - /// - public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - - /// Gets a value indicating whether gets the return value condition. - public bool ReturnValue { get; } - } - - /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] - internal sealed class NotNullWhenAttribute : Attribute - { - /// Initializes a new instance of the class.Initializes the attribute with the specified return value condition. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - - /// Gets a value indicating whether gets the return value condition. - public bool ReturnValue { get; } - } - - /// Specifies that the output will be non-null if the named parameter is non-null. - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] - internal sealed class NotNullIfNotNullAttribute : Attribute - { - /// Initializes a new instance of the class.Initializes the attribute with the associated parameter name. - /// - /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. - /// - public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; - - /// Gets the associated parameter name. - public string ParameterName { get; } - } - - /// Applied to a method that will never return under any circumstance. - [AttributeUsage(AttributeTargets.Method, Inherited = false)] - internal sealed class DoesNotReturnAttribute : Attribute - { - } - - /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] - internal sealed class DoesNotReturnIfAttribute : Attribute - { - /// Initializes a new instance of the class.Initializes the attribute with the specified parameter value. - /// - /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to - /// the associated parameter matches this value. - /// - public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; - - /// Gets a value indicating whether gets the condition parameter value. - public bool ParameterValue { get; } - } - - /// Specifies that the method or property will ensure that the listed field and property members have not-null values. - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] - internal sealed class MemberNotNullAttribute : Attribute - { - /// Initializes a new instance of the class.Initializes the attribute with a field or property member. - /// - /// The field or property member that is promised to be not-null. - /// - public MemberNotNullAttribute(string member) => Members = [member]; - - /// Initializes a new instance of the class.Initializes the attribute with the list of field and property members. - /// - /// The list of field and property members that are promised to be not-null. - /// - public MemberNotNullAttribute(params string[] members) => Members = members; - - /// Gets field or property member names. - public string[] Members { get; } - } - - /// Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition. - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] - internal sealed class MemberNotNullWhenAttribute : Attribute - { - /// Initializes a new instance of the class.Initializes the attribute with the specified return value condition and a field or property member. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - /// - /// The field or property member that is promised to be not-null. - /// - public MemberNotNullWhenAttribute(bool returnValue, string member) - { - ReturnValue = returnValue; - Members = [member]; - } - - /// Initializes a new instance of the class.Initializes the attribute with the specified return value condition and list of field and property members. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - /// - /// The list of field and property members that are promised to be not-null. - /// - public MemberNotNullWhenAttribute(bool returnValue, params string[] members) - { - ReturnValue = returnValue; - Members = members; - } - - /// Gets a value indicating whether gets the return value condition. - public bool ReturnValue { get; } - - /// Gets field or property member names. - public string[] Members { get; } - } -} - -namespace System.Text -{ - internal static class StringBuilderExtensions - { - public static StringBuilder Append(this StringBuilder builder, IFormatProvider? _, string value) - => builder.Append(value); - - public static StringBuilder AppendLine(this StringBuilder builder, IFormatProvider? _, string value) - => builder.AppendLine(value); - } -} - -#endif - -#if NETCOREAPP3_1 -namespace System.Diagnostics.CodeAnalysis -{ - /// Specifies that the method or property will ensure that the listed field and property members have not-null values. - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] - internal sealed class MemberNotNullAttribute : Attribute - { - /// Initializes the attribute with a field or property member. - /// - /// The field or property member that is promised to be not-null. - /// - public MemberNotNullAttribute(string member) => Members = [member]; - - /// Initializes the attribute with the list of field and property members. - /// - /// The list of field and property members that are promised to be not-null. - /// - public MemberNotNullAttribute(params string[] members) => Members = members; - - /// Gets field or property member names. - public string[] Members { get; } - } - - /// Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition. - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] - internal sealed class MemberNotNullWhenAttribute : Attribute - { - /// Initializes the attribute with the specified return value condition and a field or property member. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - /// - /// The field or property member that is promised to be not-null. - /// - public MemberNotNullWhenAttribute(bool returnValue, string member) - { - ReturnValue = returnValue; - Members = [member]; - } - - /// Initializes the attribute with the specified return value condition and list of field and property members. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - /// - /// The list of field and property members that are promised to be not-null. - /// - public MemberNotNullWhenAttribute(bool returnValue, params string[] members) - { - ReturnValue = returnValue; - Members = members; - } - - /// Gets the return value condition. - public bool ReturnValue { get; } - - /// Gets field or property member names. - public string[] Members { get; } - } -} -#endif - -#if !NET7_0_OR_GREATER -namespace System.Diagnostics.CodeAnalysis -{ - /// - /// Specifies that this constructor sets all required members for the current type, - /// and callers do not need to set any required members themselves. - /// - [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] - internal sealed class SetsRequiredMembersAttribute : Attribute - { - } -} - -#pragma warning disable SA1403 // File may only contain a single namespace -namespace System.Runtime.CompilerServices -{ - /// - /// Indicates that compiler support for a particular feature is required for the location where this attribute is applied. - /// - [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] - internal sealed class CompilerFeatureRequiredAttribute : Attribute - { - /// - /// The used for the ref structs C# feature. - /// - public const string RefStructs = nameof(RefStructs); - - /// - /// The used for the required members C# feature. - /// - public const string RequiredMembers = nameof(RequiredMembers); - - /// - /// Initializes a new instance of the class. - /// - /// The name of the feature to indicate. - public CompilerFeatureRequiredAttribute(string featureName) - { - FeatureName = featureName; - } - - /// - /// Gets the name of the compiler feature. - /// - public string FeatureName { get; } - - /// - /// Gets or sets a value indicating whether if true, the compiler can choose to allow access to the location where this attribute is applied if it does not understand . - /// - public bool IsOptional { get; set; } - } - - /// - /// Specifies that a type has required members or that a member is required. - /// - [AttributeUsage( - AttributeTargets.Class | - AttributeTargets.Struct | - AttributeTargets.Field | - AttributeTargets.Property, - AllowMultiple = false, - Inherited = false)] - internal sealed class RequiredMemberAttribute : Attribute - { - } -} -#endif diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/TaskExtensions.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/TaskExtensions.cs index d4f2e2cf2d..7104a74229 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/TaskExtensions.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/TaskExtensions.cs @@ -128,7 +128,7 @@ public static async Task TimeoutAfterAsync(this Task task, TimeSpan timeout, boo CancellationTokenSource cts = new(); if (task == await Task.WhenAny(task, Task.Delay(timeout, cts.Token)).ConfigureAwait(false)) { - cts.Cancel(); + await cts.CancelAsync(); await task.ConfigureAwait(false); } else @@ -178,7 +178,7 @@ public static async Task TimeoutAfterAsync(this Task task, TimeSpan timeout, Can var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, cts.Token); if (task == await Task.WhenAny(task, Task.Delay(timeout, linkedTokenSource.Token)).ConfigureAwait(false)) { - cts.Cancel(); + await cts.CancelAsync(); await task.ConfigureAwait(false); } else diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs index 9b12baa521..6669c8413e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs @@ -204,11 +204,7 @@ private async Task HandleMessagesAsync() if (!_serverClosingTokenSource.IsCancellationRequested) { await _logger.LogInformationAsync("Server requested to shutdown"); -#if NET8_0_OR_GREATER await _serverClosingTokenSource.CancelAsync(); -#else - _serverClosingTokenSource.Cancel(); -#endif } // Signal the exit call @@ -217,11 +213,7 @@ private async Task HandleMessagesAsync() // If there're no in-flight request we can close the server if (_clientToServerRequests.IsEmpty) { -#if NET8_0_OR_GREATER await _stopMessageHandler.CancelAsync(); -#else - _stopMessageHandler.Cancel(); -#endif } continue; diff --git a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj index 558920a6d6..c6283275b1 100644 --- a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj +++ b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj @@ -1,4 +1,4 @@ - + $(MicrosoftTestingTargetFrameworks);netstandard2.0 @@ -105,6 +105,10 @@ This package provides the core platform and the .NET implementation of the proto + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/TestFramework/TestFramework/TestFramework.csproj b/src/TestFramework/TestFramework/TestFramework.csproj index f5b195e0d9..9ec18d6e17 100644 --- a/src/TestFramework/TestFramework/TestFramework.csproj +++ b/src/TestFramework/TestFramework/TestFramework.csproj @@ -19,7 +19,13 @@ - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/CountDownEventTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/CountDownEventTests.cs index 279e07645a..d793aae047 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/CountDownEventTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/CountDownEventTests.cs @@ -43,11 +43,7 @@ public async Task CountDownEvent_WaitAsyncCancelled_Succeeded() CountdownEvent countdownEvent = new(1); CancellationTokenSource cts = new(); var waiter = Task.Run(() => countdownEvent.WaitAsync(cts.Token)); -#if NET8_0_OR_GREATER await cts.CancelAsync(); -#else - cts.Cancel(); -#endif await Assert.ThrowsAsync(async () => await waiter); }