File: Completion\ArgumentProviders\ContextVariableArgumentProviderTests.cs
Web Access
Project: src\src\EditorFeatures\CSharpTest\Microsoft.CodeAnalysis.CSharp.EditorFeatures.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.EditorFeatures.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;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Completion.Providers;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.ArgumentProviders;
 
[Trait(Traits.Feature, Traits.Features.Completion)]
public class ContextVariableArgumentProviderTests : AbstractCSharpArgumentProviderTests
{
    internal override Type GetArgumentProviderType()
        => typeof(ContextVariableArgumentProvider);
 
    [Theory]
    [InlineData("string")]
    [InlineData("bool")]
    [InlineData("int?")]
    public async Task TestLocalVariable(string type)
    {
        var markup = $@"
class C
{{
    void Method()
    {{
        {type} arg = default;
        this.Target($$);
    }}
 
    void Target({type} arg)
    {{
    }}
}}
";
 
        await VerifyDefaultValueAsync(markup, "arg");
        await VerifyDefaultValueAsync(markup, expectedDefaultValue: null, previousDefaultValue: "prior");
    }
 
    [Theory, CombinatorialData]
    public async Task TestOutVariable(
        [CombinatorialValues("string", "bool", "int?")] string type,
        [CombinatorialValues("out", "ref", "in")] string modifier)
    {
        var markup = $@"
class C
{{
    void Method()
    {{
        {type} arg;
        this.Target($$);
    }}
 
    void Target({modifier} {type} arg)
    {{
    }}
}}
";
 
        var generatedModifier = modifier switch
        {
            "in" => "",
            _ => $"{modifier} ",
        };
 
        await VerifyDefaultValueAsync(markup, $"{generatedModifier}arg");
        await VerifyDefaultValueAsync(markup, expectedDefaultValue: null, previousDefaultValue: "prior");
    }
 
    [Theory]
    [InlineData("string")]
    [InlineData("bool")]
    [InlineData("int?")]
    public async Task TestParameter(string type)
    {
        var markup = $@"
class C
{{
    void Method({type} arg)
    {{
        this.Target($$);
    }}
 
    void Target({type} arg)
    {{
    }}
}}
";
 
        await VerifyDefaultValueAsync(markup, "arg");
        await VerifyDefaultValueAsync(markup, expectedDefaultValue: null, previousDefaultValue: "prior");
    }
 
    [Theory]
    [InlineData("string", "string")]
    [InlineData("string", "IEnumerable<char>")]
    [InlineData("bool", "bool")]
    [InlineData("int?", "int?")]
    [InlineData("int", "int?")]
    public async Task TestInstanceVariable(string fieldType, string parameterType)
    {
        var markup = $@"
using System.Collections.Generic;
class C
{{
    {fieldType} arg;
 
    void Method()
    {{
        this.Target($$);
    }}
 
    void Target({parameterType} arg)
    {{
    }}
}}
";
 
        await VerifyDefaultValueAsync(markup, "arg");
        await VerifyDefaultValueAsync(markup, expectedDefaultValue: null, previousDefaultValue: "prior");
    }
 
    [Theory]
    [InlineData("C")]
    [InlineData("B")]
    [InlineData("I")]
    public async Task TestThisInstance(string parameterType)
    {
        var markup = $@"
using System.Collections.Generic;
interface I {{ }}
 
class B {{ }}
 
class C : B, I
{{
    void Method()
    {{
        this.Target($$);
    }}
 
    void Target({parameterType} arg)
    {{
    }}
}}
";
 
        await VerifyDefaultValueAsync(markup, "this");
        await VerifyDefaultValueAsync(markup, expectedDefaultValue: null, previousDefaultValue: "prior");
    }
 
    [Theory]
    [InlineData("object")]
    [InlineData("string")]
    public async Task TestThisInstanceNotProvided1(string parameterType)
    {
        var markup = $@"
using System.Collections.Generic;
interface I {{ }}
 
class B {{ }}
 
class C : B, I
{{
    void Method()
    {{
        this.Target($$);
    }}
 
    void Target({parameterType} arg)
    {{
    }}
}}
";
 
        await VerifyDefaultValueAsync(markup, null);
    }
 
    [Fact]
    public async Task TestThisInstanceNotProvided2()
    {
        var markup = $@"
using System.Collections.Generic;
 
class C
{{
    static void Method()
    {{
        Target($$);
    }}
 
    static void Target(C arg)
    {{
    }}
}}
";
 
        await VerifyDefaultValueAsync(markup, null);
    }
 
    // Note: The current implementation checks for exact type match for primitive types. If this changes, some of
    // these tests may need to be updated to account for the new behavior.
    [Theory]
    [InlineData("object", "string")]
    [InlineData("string", "object")]
    [InlineData("bool", "bool?")]
    [InlineData("bool", "int")]
    [InlineData("int", "object")]
    public async Task TestMismatchType(string parameterType, string valueType)
    {
        var markup = $@"
class C
{{
    void Method({valueType} arg)
    {{
        this.Target($$);
    }}
 
    void Target({parameterType} arg)
    {{
    }}
}}
";
 
        await VerifyDefaultValueAsync(markup, null);
    }
}