File: UseNameofInAttribute\UseNameofInAttributeTests.cs
Web Access
Project: src\src\Features\CSharpTest\Microsoft.CodeAnalysis.CSharp.Features.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Features.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeFixes.UseNameofInAttribute;
using Microsoft.CodeAnalysis.CSharp.UseNameofInAttribute;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Testing;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseNameofInAttribute;
 
using VerifyCS = CSharpCodeFixVerifier<
    CSharpUseNameofInAttributeDiagnosticAnalyzer,
    CSharpUseNameofInAttributeCodeFixProvider>;
 
public class UseNameofInAttributeTests
{
    [Fact]
    public async Task TestOnMethod()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNull([|"input"|])]
                    string? M(string? input) => input;
                }
                """,
            FixedCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNull(nameof(input))]
                    string? M(string? input) => input;
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestWithInterpolation()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNull([|$"input"|])]
                    string? M(string? input) => input;
                }
                """,
            FixedCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNull(nameof(input))]
                    string? M(string? input) => input;
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestTrivia()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNull(/*before*/[|"input"|]/*after*/)]
                    string? M(string? input) => input;
                }
                """,
            FixedCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNull(/*before*/nameof(input)/*after*/)]
                    string? M(string? input) => input;
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestFullAttributeName()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNullAttribute([|"input"|])]
                    string? M(string? input) => input;
                }
                """,
            FixedCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNullAttribute(nameof(input))]
                    string? M(string? input) => input;
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNamedArg()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNullAttribute(parameterName: [|"input"|])]
                    string? M(string? input) => input;
                }
                """,
            FixedCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    [return: NotNullIfNotNullAttribute(parameterName: nameof(input))]
                    string? M(string? input) => input;
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task NotBeforeCSharp11()
    {
        var code = """
            using System.Diagnostics.CodeAnalysis;
            #nullable enable
            class C
            {
                [return: NotNullIfNotNull("input")]
                string? M(string? input) => input;
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task NotOnIncorrectAttributeName()
    {
        var code = """
            using System.Diagnostics.CodeAnalysis;
            #nullable enable
            class C
            {
                [return: {|CS0246:{|CS0246:NotNullIfNotNull1|}|}("input")]
                string? M(string? input) => input;
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNotWhenMissingArguments()
    {
        var code = """
            using System.Diagnostics.CodeAnalysis;
            #nullable enable
            class C
            {
                [return: {|CS7036:NotNullIfNotNull|}]
                string? M(string? input) => input;
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task NotOnIncorrectReferencedName()
    {
        var code = """
            using System.Diagnostics.CodeAnalysis;
            #nullable enable
            class C
            {
                [return: NotNullIfNotNull("input1")]
                string? M(string? input) => input;
            }
            """;
 
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestOnParameter()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    void M([NotNullIfNotNull([|"input"|])] string? input) { }
                }
                """,
            FixedCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    void M([NotNullIfNotNull(nameof(input))] string? input) { }
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestForProperty()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    string? Prop { get; set; }
 
                    [MemberNotNullWhen(true, [|"Prop"|])]
                    bool IsInitialized
                    {
                        get
                        {
                            Prop = "";
                            return true;
                        }
                    }
                }
                """,
            FixedCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    string? Prop { get; set; }
                
                    [MemberNotNullWhen(true, nameof(Prop))]
                    bool IsInitialized
                    {
                        get
                        {
                            Prop = "";
                            return true;
                        }
                    }
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestMultipleArguments()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    string? Prop1 { get; set; }
                    string? Prop2 { get; set; }
 
                    [MemberNotNull([|"Prop1"|], [|"Prop2"|])]
                    bool IsInitialized
                    {
                        get
                        {
                            Prop1 = "";
                            Prop2 = "";
                            return true;
                        }
                    }
                }
                """,
            FixedCode = """
                using System.Diagnostics.CodeAnalysis;
                #nullable enable
                class C
                {
                    string? Prop1 { get; set; }
                    string? Prop2 { get; set; }
                
                    [MemberNotNull(nameof(Prop1), nameof(Prop2))]
                    bool IsInitialized
                    {
                        get
                        {
                            Prop1 = "";
                            Prop2 = "";
                            return true;
                        }
                    }
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestCallerArgumentExpression1()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Runtime.CompilerServices;
                #nullable enable
                class C
                {
                    void M(string s1, [CallerArgumentExpression([|"s1"|])] string? s2 = null) { }
                }
                """,
            FixedCode = """
                using System.Runtime.CompilerServices;
                #nullable enable
                class C
                {
                    void M(string s1, [CallerArgumentExpression(nameof(s1))] string? s2 = null) { }
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestCallerArgumentExpression2()
    {
        await new VerifyCS.Test
        {
            TestCode = """
                using System.Runtime.CompilerServices;
                #nullable enable
                class C
                {
                    void M(string s1, [CallerArgumentExpressionAttribute([|"s1"|])] string? s2 = null) { }
                }
                """,
            FixedCode = """
                using System.Runtime.CompilerServices;
                #nullable enable
                class C
                {
                    void M(string s1, [CallerArgumentExpressionAttribute(nameof(s1))] string? s2 = null) { }
                }
                """,
            LanguageVersion = LanguageVersion.CSharp11,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
        }.RunAsync();
    }
}