|
// 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.Completion;
using Microsoft.CodeAnalysis.CSharp.Completion.Providers;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionProviders;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionSetSources;
[Trait(Traits.Feature, Traits.Features.Completion)]
public class NamedParameterCompletionProviderTests : AbstractCSharpCompletionProviderTests
{
internal override Type GetCompletionProviderType()
=> typeof(NamedParameterCompletionProvider);
[Fact]
public async Task SendEnterThroughToEditorTest()
{
const string markup = """
class Goo
{
public Goo(int a = 42)
{ }
void Bar()
{
var b = new Goo($$
}
}
""";
await VerifySendEnterThroughToEnterAsync(markup, "a:", sendThroughEnterOption: EnterKeyRule.Never, expected: false);
await VerifySendEnterThroughToEnterAsync(markup, "a:", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: true);
await VerifySendEnterThroughToEnterAsync(markup, "a:", sendThroughEnterOption: EnterKeyRule.Always, expected: true);
}
[Fact]
public async Task CommitCharacterTest()
{
const string markup = """
class Goo
{
public Goo(int a = 42)
{ }
void Bar()
{
var b = new Goo($$
}
}
""";
await VerifyCommonCommitCharactersAsync(markup, textTypedSoFar: "");
}
[Fact]
public async Task InObjectCreation()
{
var markup = """
class Goo
{
public Goo(int a = 42)
{ }
void Bar()
{
var b = new Goo($$
}
}
""";
await VerifyItemExistsAsync(markup, "a", displayTextSuffix: ":");
}
[Fact]
public async Task InBaseConstructor()
{
var markup = """
class Goo
{
public Goo(int a = 42)
{ }
}
class DogBed : Goo
{
public DogBed(int b) : base($$
}
""";
await VerifyItemExistsAsync(markup, "a", displayTextSuffix: ":");
}
[Fact]
public async Task InvocationExpression()
{
var markup = """
class Goo
{
void Bar(int a)
{
Bar($$
}
}
""";
await VerifyItemExistsAsync(markup, "a", displayTextSuffix: ":");
}
[Fact]
public async Task InvocationExpressionAfterComma()
{
var markup = """
class Goo
{
void Bar(int a, string b)
{
Bar(b:"", $$
}
}
""";
await VerifyItemExistsAsync(markup, "a", displayTextSuffix: ":");
}
[Fact]
public async Task ElementAccessExpression()
{
var markup = """
class SampleCollection<T>
{
private T[] arr = new T[100];
public T this[int i]
{
get
{
return arr[i];
}
set
{
arr[i] = value;
}
}
}
class Program
{
static void Main(string[] args)
{
SampleCollection<string> stringCollection = new SampleCollection<string>();
stringCollection[$$
}
}
""";
await VerifyItemExistsAsync(markup, "i", displayTextSuffix: ":");
}
[Fact]
public async Task PartialMethods()
{
var markup = """
partial class PartialClass
{
static partial void Goo(int declaring);
static partial void Goo(int implementing)
{
}
static void Caller()
{
Goo($$
}
}
""";
await VerifyItemExistsAsync(markup, "declaring", displayTextSuffix: ":");
await VerifyItemIsAbsentAsync(markup, "implementing", displayTextSuffix: ":");
}
[Fact]
public async Task ExtendedPartialMethods()
{
var markup = """
partial class PartialClass
{
public static partial void Goo(int declaring);
public static partial void Goo(int implementing)
{
}
static void Caller()
{
Goo($$
}
}
""";
await VerifyItemExistsAsync(markup, "declaring", displayTextSuffix: ":");
await VerifyItemIsAbsentAsync(markup, "implementing", displayTextSuffix: ":");
}
[Fact]
public async Task NotAfterColon()
{
var markup = """
class Goo
{
void Bar(int a, string b)
{
Bar(a:$$
}
}
""";
await VerifyNoItemsExistAsync(markup);
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544292")]
public async Task NotInCollectionInitializers()
{
var markup = """
using System.Collections.Generic;
class Goo
{
void Bar(List<int> integers)
{
Bar(integers: new List<int> { 10, 11,$$ 12 });
}
}
""";
await VerifyNoItemsExistAsync(markup);
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544191")]
public async Task FilteringOverloadsByCallSite()
{
var markup = """
class Class1
{
void Test()
{
Goo(boolean:true, $$)
}
void Goo(string str = "hello", char character = 'a')
{ }
void Goo(string str = "hello", bool boolean = false)
{ }
}
""";
await VerifyItemExistsAsync(markup, "str", displayTextSuffix: ":");
await VerifyItemIsAbsentAsync(markup, "character", displayTextSuffix: ":");
}
[Fact]
public async Task DoNotFilterYet()
{
var markup = """
class Class1
{
void Test()
{
Goo(str:"", $$)
}
void Goo(string str = "hello", char character = 'a')
{ }
void Goo(string str = "hello", bool boolean = false)
{ }
}
""";
await VerifyItemExistsAsync(markup, "boolean", displayTextSuffix: ":");
await VerifyItemExistsAsync(markup, "character", displayTextSuffix: ":");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544191")]
public async Task FilteringOverloadsByCallSiteComplex()
{
var markup = """
class Goo
{
void Test()
{
Bar m = new Bar();
Method(obj:m, $$
}
void Method(Bar obj, int num = 23, string str = "")
{
}
void Method(double dbl = double.MinValue, string str = "")
{
}
void Method(int num = 1, bool b = false, string str = "")
{
}
void Method(Bar obj, bool b = false, string str = "")
{
}
}
class Bar { }
""";
await VerifyItemExistsAsync(markup, "str", displayTextSuffix: ":");
await VerifyItemExistsAsync(markup, "num", displayTextSuffix: ":");
await VerifyItemExistsAsync(markup, "b", displayTextSuffix: ":");
await VerifyItemIsAbsentAsync(markup, "dbl", displayTextSuffix: ":");
}
[Fact]
public async Task MethodOverloads()
{
var markup = """
class Goo
{
void Test()
{
object m = null;
Method(m, $$
}
void Method(object obj, int num = 23, string str = "")
{
}
void Method(int num = 1, bool b = false, string str = "")
{
}
void Method(object obj, bool b = false, string str = "")
{
}
}
""";
await VerifyItemExistsAsync(markup, "str", displayTextSuffix: ":");
await VerifyItemExistsAsync(markup, "num", displayTextSuffix: ":");
await VerifyItemExistsAsync(markup, "b", displayTextSuffix: ":");
}
[Fact]
public async Task ExistingNamedParamsAreFilteredOut()
{
var markup = """
class Goo
{
void Test()
{
object m = null;
Method(obj: m, str: "", $$);
}
void Method(object obj, int num = 23, string str = "")
{
}
void Method(double dbl = double.MinValue, string str = "")
{
}
void Method(int num = 1, bool b = false, string str = "")
{
}
void Method(object obj, bool b = false, string str = "")
{
}
}
""";
await VerifyItemExistsAsync(markup, "num", displayTextSuffix: ":");
await VerifyItemExistsAsync(markup, "b", displayTextSuffix: ":");
await VerifyItemIsAbsentAsync(markup, "obj", displayTextSuffix: ":");
await VerifyItemIsAbsentAsync(markup, "str", displayTextSuffix: ":");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529369")]
public async Task VerbatimIdentifierNotAKeyword()
{
var markup = """
class Program
{
void Goo(int @integer)
{
Goo(@i$$
}
}
""";
await VerifyItemExistsAsync(markup, "integer", displayTextSuffix: ":");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544209")]
public async Task DescriptionStringInMethodOverloads()
{
var markup = """
class Class1
{
void Test()
{
Goo(boolean: true, $$)
}
void Goo(string obj = "hello")
{ }
void Goo(bool boolean = false, Class1 obj = default(Class1))
{ }
}
""";
await VerifyItemExistsAsync(markup, "obj", displayTextSuffix: ":",
expectedDescriptionOrNull: $"({FeaturesResources.parameter}) Class1 obj = default(Class1)");
}
[Fact]
public async Task InDelegates()
{
var markup = """
public delegate void Del(string message);
class Program
{
public static void DelegateMethod(string message)
{
System.Console.WriteLine(message);
}
static void Main(string[] args)
{
Del handler = DelegateMethod;
handler($$
}
}
""";
await VerifyItemExistsAsync(markup, "message", displayTextSuffix: ":");
}
[Fact]
public async Task InDelegateInvokeSyntax()
{
var markup = """
public delegate void Del(string message);
class Program
{
public static void DelegateMethod(string message)
{
System.Console.WriteLine(message);
}
static void Main(string[] args)
{
Del handler = DelegateMethod;
handler.Invoke($$
}
}
""";
await VerifyItemExistsAsync(markup, "message", displayTextSuffix: ":");
}
[Fact]
public async Task NotInComment()
{
var markup = """
public class Test
{
static void Main()
{
M(x: 0, //Hit ctrl-space at the end of this comment $$
y: 1);
}
static void M(int x, int y) { }
}
""";
await VerifyNoItemsExistAsync(markup);
}
[Fact]
public async Task CommitWithColonWordFullyTyped()
{
var markup = """
class Program
{
static void Main(string[] args)
{
Main(args$$)
}
}
""";
var expected = """
class Program
{
static void Main(string[] args)
{
Main(args:)
}
}
""";
await VerifyProviderCommitAsync(markup, "args:", expected, ':');
}
[Fact]
public async Task CommitWithColonWordPartiallyTyped()
{
var markup = """
class Program
{
static void Main(string[] args)
{
Main(arg$$)
}
}
""";
var expected = """
class Program
{
static void Main(string[] args)
{
Main(args:)
}
}
""";
await VerifyProviderCommitAsync(markup, "args:", expected, ':');
}
}
|