diff --git a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md index 6eea619003..2bbee99456 100644 --- a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md +++ b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md @@ -1,2 +1,7 @@ -; Unshipped analyzer release +; Unshipped analyzer release ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +MSTEST0038 | `Usage` | Warning | AvoidAssertAreSameWithValueTypesAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0038) diff --git a/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs new file mode 100644 index 0000000000..fc6a8b0fec --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs @@ -0,0 +1,78 @@ +// 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.Collections.Immutable; + +using Analyzer.Utilities.Extensions; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; + +using MSTest.Analyzers.Helpers; +using MSTest.Analyzers.RoslynAnalyzerHelpers; + +namespace MSTest.Analyzers; + +/// +/// MSTEST0025: . +/// +[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] +public sealed class AvoidAssertAreSameWithValueTypesAnalyzer : DiagnosticAnalyzer +{ + private static readonly LocalizableResourceString Title = new(nameof(Resources.AvoidAssertAreSameWithValueTypesTitle), Resources.ResourceManager, typeof(Resources)); + private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.AvoidAssertAreSameWithValueTypesMessageFormat), Resources.ResourceManager, typeof(Resources)); + private static readonly LocalizableResourceString Description = new(nameof(Resources.AvoidAssertAreSameWithValueTypesDescription), Resources.ResourceManager, typeof(Resources)); + + internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create( + DiagnosticIds.AvoidAssertAreSameWithValueTypesRuleId, + Title, + MessageFormat, + Description, + Category.Usage, + DiagnosticSeverity.Warning, + isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics { get; } + = ImmutableArray.Create(Rule); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + + context.RegisterCompilationStartAction(context => + { + Compilation compilation = context.Compilation; + INamedTypeSymbol? assertSymbol = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingAssert); + if (assertSymbol is not null) + { + context.RegisterOperationAction(context => AnalyzeOperation(context, assertSymbol), OperationKind.Invocation); + } + }); + } + + private static void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol assertSymbol) + { + var operation = (IInvocationOperation)context.Operation; + IMethodSymbol targetMethod = operation.TargetMethod; + if (targetMethod.Name != "AreSame" || + !assertSymbol.Equals(operation.TargetMethod.ContainingType, SymbolEqualityComparer.Default)) + { + return; + } + + IArgumentOperation? argExpected = operation.Arguments.FirstOrDefault(arg => arg.Parameter?.Ordinal == 0); + IArgumentOperation? argActual = operation.Arguments.FirstOrDefault(arg => arg.Parameter?.Ordinal == 1); + if (argExpected is null || argActual is null) + { + return; + } + + if (argExpected.Value.WalkDownConversion().Type?.IsValueType == true || + argActual.Value.WalkDownConversion().Type?.IsValueType == true) + { + context.ReportDiagnostic(operation.CreateDiagnostic(Rule)); + } + } +} diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs b/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs index 79c269bbe8..7c92ad22ca 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs @@ -42,4 +42,5 @@ internal static class DiagnosticIds public const string UseDeploymentItemWithTestMethodOrTestClassRuleId = "MSTEST0035"; public const string DoNotUseShadowingRuleId = "MSTEST0036"; public const string UseProperAssertMethodsRuleId = "MSTEST0037"; + public const string AvoidAssertAreSameWithValueTypesRuleId = "MSTEST0038"; } diff --git a/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt b/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt index 7dc5c58110..3f880fefe8 100644 --- a/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt +++ b/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt @@ -1 +1,5 @@ #nullable enable +MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer +MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer.AvoidAssertAreSameWithValueTypesAnalyzer() -> void +override MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index 7ebb84e567..8b7c3bc0da 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -180,6 +180,33 @@ internal static string AssertionArgsShouldBePassedInCorrectOrderTitle { } } + /// + /// Looks up a localized string similar to Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens.. + /// + internal static string AvoidAssertAreSameWithValueTypesDescription { + get { + return ResourceManager.GetString("AvoidAssertAreSameWithValueTypesDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. + /// + internal static string AvoidAssertAreSameWithValueTypesMessageFormat { + get { + return ResourceManager.GetString("AvoidAssertAreSameWithValueTypesMessageFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Don't use 'Assert.AreSame' with value types. + /// + internal static string AvoidAssertAreSameWithValueTypesTitle { + get { + return ResourceManager.GetString("AvoidAssertAreSameWithValueTypesTitle", resourceCulture); + } + } + /// /// Looks up a localized string similar to Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption.. /// diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index 064eb11cd9..93e6d7f3da 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -543,4 +543,13 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - + + Don't use 'Assert.AreSame' with value types + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index c79e88f0d6..ff9ecc6199 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -117,6 +117,21 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: Argumenty kontrolního výrazu musí být předány ve správném pořadí + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. Preferujte Assert.ThrowsException nebo Assert.ThrowsExceptionAsync před [ExpectedException], protože zajišťuje, že očekávanou výjimku vyvolá pouze očekávané volání. Rozhraní API assert také poskytují větší flexibilitu a umožňují vyhodnocovat další vlastnosti výjimky. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 7aaa0f678d..65b7bfbfa8 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -117,6 +117,21 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte Assertionsargumente sollten in der richtigen Reihenfolge übergeben werden. + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. „Assert.ThrowsException“ oder „Assert.ThrowsExceptionAsync“ gegenüber „[ExpectedException]“ bevorzugen, da dadurch sichergestellt wird, dass nur der erwartete Aufruf die erwartete Ausnahme auslöst. Die Assert-APIs bieten außerdem mehr Flexibilität und ermöglichen es Ihnen, zusätzliche Eigenschaften der Ausführung zu bestätigen. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 6fbe5e76f5..3a4816eb2d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -117,6 +117,21 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: Los argumentos de aserción deben pasarse en el orden correcto + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. Preferir "Assert.ThrowsException" o "Assert.ThrowsExceptionAsync" en lugar de '[ExpectedException]' ya que garantiza que solo la llamada esperada inicia la excepción esperada. Las API de aserción también proporcionan más flexibilidad y le permiten declarar propiedades adicionales de la ejecución. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index d31fd65b76..33080fd26c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -117,6 +117,21 @@ Le type doit être une classe Les arguments d’assertion doivent être passés dans l’ordre approprié + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. Préférez « Assert.ThrowsException » ou « Assert.ThrowsExceptionAsync » à « [ExpectedException] », car cela assure que seul l’appel attendu lève l’exception attendue. Les API d’assertion offrent également plus de flexibilité et vous permettent de déclarer des propriétés supplémentaires de l’exception. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index ab85a55c21..0f9641b037 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -117,6 +117,21 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: Gli argomenti dell'asserzione devono essere passati nell'ordine corretto + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. Preferisci 'Assert.ThrowsException' o 'Assert.ThrowsExceptionAsync' a '[ExpectedException]', perché garantisce che solo la chiamata prevista lanci l'eccezione prevista. Le API di asserzione forniscono anche una maggiore flessibilità e consentono l’asserzione delle proprietà aggiuntive dell'eccezione. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 7b9f8b38db..9fa8d743f3 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -117,6 +117,21 @@ The type declaring these methods should also respect the following rules: アサーション引数は正しい順序で渡す必要があります + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. '[ExpectedException]' よりも 'Assert.ThrowsException' または 'Assert.ThrowsExceptionAsync' を優先します。これは、予期された呼び出しのみが予期された例外をスローするようにするためです。アサート API も柔軟性が高く、例外の追加プロパティをアサートできます。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index b191882072..a8a30b9585 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -117,6 +117,21 @@ The type declaring these methods should also respect the following rules: 어설션 인수는 올바른 순서로 전달되어야 합니다. + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. 예상되는 호출만 예상되는 예외를 throw하도록 보장하는 '[ExpectedException]'보다 'Assert.ThrowsException' 또는 'Assert.ThrowsExceptionAsync'를 사용하는 것이 좋습니다. 또한 Assert API는 더 많은 유연성을 제공하고 예외의 추가 속성을 어설션할 수 있도록 합니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 076f2f56d1..74fa2a5c3c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -117,6 +117,21 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu Argumenty asercji powinny być przekazywane w poprawnej kolejności + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. Preferuj element „Assert.ThrowsException” lub „Assert.ThrowsExceptionAsync” niż „[ExpectedException]”, ponieważ gwarantuje, że tylko oczekiwane wywołanie zgłosi oczekiwany wyjątek. Interfejsy API potwierdzenia zapewniają również większą elastyczność i pozwalają na potwierdzenie dodatkowych właściwości wyjątku. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 55e17fd899..f36a0df16e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -117,6 +117,21 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: Os argumentos de asserção devem ser passados na ordem correta + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. Prefira 'Assert.ThrowsException' ou 'Assert.ThrowsExceptionAsync' '[ExpectedException]', pois isso garante que somente a chamada esperada lance a exceção esperada. As APIs assert também fornecem mais flexibilidade e permitem declarar propriedades extras da exceção. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index ee59f488cf..4e2ecd64c2 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -118,6 +118,21 @@ The type declaring these methods should also respect the following rules: Аргументы проверочных утверждений должны передаваться в правильном порядке + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. Предпочитайте "Assert.ThrowsException" или "Assert.ThrowsExceptionAsync" вместо "[ExpectedException]", так как это гарантирует, что только ожидаемый вызов приводит к ожидаемому исключению. API-интерфейсы утверждения также обеспечивают дополнительную гибкость и позволяют утверждать дополнительные свойства исключения. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index 3791c4e8ad..ad8cc2217b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -117,6 +117,21 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: Onay deyimi bağımsız değişkenleri doğru sıralama düzeninde geçirilmelidir + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. Yalnızca beklenen çağrının beklenen özel durumu oluşturmasını sağladığı için '[ExpectedException]' yerine 'Assert.ThrowsException' veya 'Assert.ThrowsExceptionAsync' tercih edin. Onaylama API'leri de daha fazla esneklik sağlar ve özel durumun ek özelliklerini onaylamanıza izin verir. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index ad6f1bbac2..8f53c4498e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -117,6 +117,21 @@ The type declaring these methods should also respect the following rules: 应按正确的顺序传递断言参数 + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. 首选 "Assert.ThrowsException" 或 "Assert.ThrowsExceptionAsync" 而不是 "[ExpectedException]",因为它确保只有预期调用才会引发预期异常。断言 API 还提供更多的灵活性,并允许你断言异常的额外属性。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 954e70c12b..4dc0ee6183 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -117,6 +117,21 @@ The type declaring these methods should also respect the following rules: 應該以正確的順序傳遞判斷提示引數 + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + Prefer 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' over '[ExpectedException]' as it ensures that only the expected call throws the expected exception. The assert APIs also provide more flexibility and allow you to assert extra properties of the exeption. 偏好 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' 而非 '[ExpectedException]',因為它可確保只有預期的呼叫會擲出預期的例外狀況。判斷提示 API 也提供更多彈性,並允許您斷言例外狀況的額外屬性。 diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs new file mode 100644 index 0000000000..42c8306e5e --- /dev/null +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using VerifyCS = MSTest.Analyzers.Test.CSharpCodeFixVerifier< + MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace MSTest.Analyzers.UnitTests; + +[TestClass] +public sealed class AvoidAssertAreSameWithValueTypesAnalyzerTests +{ + [TestMethod] + public async Task UseAssertAreSameWithValueTypes_Diagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void TestMethod() + { + // Both are value types + [|Assert.AreSame(0, 0)|]; + [|Assert.AreSame(0, 0, "Message")|]; + [|Assert.AreSame(0, 0, "Message {0}", "Arg")|]; + [|Assert.AreSame(message: "Message", expected: 0, actual: 0)|]; + + [|Assert.AreSame(0, 0)|]; + [|Assert.AreSame(0, 0, "Message")|]; + [|Assert.AreSame(0, 0, "Message {0}", "Arg")|]; + [|Assert.AreSame(message: "Message", expected: 0, actual: 0)|]; + + // Expected is value type. This is always-failing assert. + [|Assert.AreSame("0", 0)|]; + [|Assert.AreSame("0", 0, "Message")|]; + [|Assert.AreSame("0", 0, "Message {0}", "Arg")|]; + [|Assert.AreSame(message: "Message", expected: "0", actual: 0)|]; + + // Actual is value type. This is always-failing assert. + [|Assert.AreSame(0, "0")|]; + [|Assert.AreSame(0, "0", "Message")|]; + [|Assert.AreSame(0, "0", "Message {0}", "Arg")|]; + [|Assert.AreSame(message: "Message", expected: 0, actual: "0")|]; + + // Both are reference types. No diagnostic. + Assert.AreSame("0", "0"); + Assert.AreSame("0", "0", "Message"); + Assert.AreSame("0", "0", "Message {0}", "Arg"); + Assert.AreSame(message: "Message", expected: "0", actual: "0"); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } +}