提交 e8aa1669 编写于 作者: I Ivan Basov

more unit tests

上级 0891da2b
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ChangeSignature;
using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities.ChangeSignature;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature
{
public partial class ChangeSignatureTests : AbstractChangeSignatureTests
{
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_ToImplementedMethod()
{
var markup = @"
interface I
{
void M(int x, string y);
}
class C : I
{
$$public void M(int x, string y)
{ }
}";
var permutation = new[] {
new AddedParameterOrExistingIndex(1),
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345")),
new AddedParameterOrExistingIndex(0)
};
var updatedCode = @"
interface I
{
void M(string y, int newIntegerParameter, int x);
}
class C : I
{
public void M(string y, int newIntegerParameter, int x)
{ }
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_ToImplementedMethod_WithTuples()
{
var markup = @"
interface I
{
void M((int, int) x, (string a, string b) y);
}
class C : I
{
$$public void M((int, int) x, (string a, string b) y)
{ }
}";
var permutation = new[] {
new AddedParameterOrExistingIndex(1),
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345")),
new AddedParameterOrExistingIndex(0)
};
var updatedCode = @"
interface I
{
void M((string a, string b) y, int newIntegerParameter, (int, int) x);
}
class C : I
{
public void M((string a, string b) y, int newIntegerParameter, (int, int) x)
{ }
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_ToImplementingMethod()
{
var markup = @"
interface I
{
$$void M(int x, string y);
}
class C : I
{
public void M(int x, string y)
{ }
}";
var permutation = new[] {
new AddedParameterOrExistingIndex(1),
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345")),
new AddedParameterOrExistingIndex(0)
};
var updatedCode = @"
interface I
{
void M(string y, int newIntegerParameter, int x);
}
class C : I
{
public void M(string y, int newIntegerParameter, int x)
{ }
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_ToOverriddenMethod()
{
var markup = @"
class B
{
public virtual void M(int x, string y)
{ }
}
class D : B
{
$$public override void M(int x, string y)
{ }
}";
var permutation = new[] {
new AddedParameterOrExistingIndex(1),
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345")),
new AddedParameterOrExistingIndex(0)
};
var updatedCode = @"
class B
{
public virtual void M(string y, int newIntegerParameter, int x)
{ }
}
class D : B
{
public override void M(string y, int newIntegerParameter, int x)
{ }
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_ToOverridingMethod()
{
var markup = @"
class B
{
$$public virtual void M(int x, string y)
{ }
}
class D : B
{
public override void M(int x, string y)
{ }
}";
var permutation = new[] {
new AddedParameterOrExistingIndex(1),
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345")),
new AddedParameterOrExistingIndex(0)
};
var updatedCode = @"
class B
{
public virtual void M(string y, int newIntegerParameter, int x)
{ }
}
class D : B
{
public override void M(string y, int newIntegerParameter, int x)
{ }
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_ToOverriddenMethod_Transitive()
{
var markup = @"
class B
{
public virtual void M(int x, string y)
{ }
}
class D : B
{
public override void M(int x, string y)
{ }
}
class D2 : D
{
$$public override void M(int x, string y)
{ }
}";
var permutation = new[] {
new AddedParameterOrExistingIndex(1),
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345")),
new AddedParameterOrExistingIndex(0)
};
var updatedCode = @"
class B
{
public virtual void M(string y, int newIntegerParameter, int x)
{ }
}
class D : B
{
public override void M(string y, int newIntegerParameter, int x)
{ }
}
class D2 : D
{
public override void M(string y, int newIntegerParameter, int x)
{ }
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_ToOverridingMethod_Transitive()
{
var markup = @"
class B
{
$$public virtual void M(int x, string y)
{ }
}
class D : B
{
public override void M(int x, string y)
{ }
}
class D2 : D
{
public override void M(int x, string y)
{ }
}";
var permutation = new[] {
new AddedParameterOrExistingIndex(1),
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345")),
new AddedParameterOrExistingIndex(0)
};
var updatedCode = @"
class B
{
public virtual void M(string y, int newIntegerParameter, int x)
{ }
}
class D : B
{
public override void M(string y, int newIntegerParameter, int x)
{ }
}
class D2 : D
{
public override void M(string y, int newIntegerParameter, int x)
{ }
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_ToMethods_Complex()
{
//// B I I2
//// \ / \ /
//// D (I3)
//// / \ \
//// $$D2 D3 C
var markup = @"
class B { public virtual void M(int x, string y) { } }
class D : B, I { public override void M(int x, string y) { } }
class D2 : D { public override void $$M(int x, string y) { } }
class D3 : D { public override void M(int x, string y) { } }
interface I { void M(int x, string y); }
interface I2 { void M(int x, string y); }
interface I3 : I, I2 { }
class C : I3 { public void M(int x, string y) { } }";
var permutation = new[] {
new AddedParameterOrExistingIndex(1),
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345")),
new AddedParameterOrExistingIndex(0)
};
var updatedCode = @"
class B { public virtual void M(string y, int newIntegerParameter, int x) { } }
class D : B, I { public override void M(string y, int newIntegerParameter, int x) { } }
class D2 : D { public override void M(string y, int newIntegerParameter, int x) { } }
class D3 : D { public override void M(string y, int newIntegerParameter, int x) { } }
interface I { void M(string y, int newIntegerParameter, int x); }
interface I2 { void M(string y, int newIntegerParameter, int x); }
interface I3 : I, I2 { }
class C : I3 { public void M(string y, int newIntegerParameter, int x) { } }";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
[WpfFact(Skip = "TODO"), Trait(Traits.Feature, Traits.Features.ChangeSignature)]
public async Task AddParameter_Cascade_ToMethods_WithDifferentParameterNames()
{
var markup = @"
public class B
{
/// <param name=""x""></param>
/// <param name=""y""></param>
public virtual int M(int x, string y)
{
return 1;
}
}
public class D : B
{
/// <param name=""a""></param>
/// <param name=""b""></param>
public override int M(int a, string b)
{
return 1;
}
}
public class D2 : D
{
/// <param name=""y""></param>
/// <param name=""x""></param>
public override int $$M(int y, string x)
{
M(1, ""Two"");
((D)this).M(1, ""Two"");
((B)this).M(1, ""Two"");
M(1, x: ""Two"");
((D)this).M(1, b: ""Two"");
((B)this).M(1, y: ""Two"");
return 1;
}
}";
var permutation = new[] {
new AddedParameterOrExistingIndex(1),
new AddedParameterOrExistingIndex(new AddedParameter("int", "newIntegerParameter", "12345")),
new AddedParameterOrExistingIndex(0)
};
var updatedCode = @"
public class B
{
/// <param name=""y""></param>
/// <param name=""newIntegerParameter""></param>
/// <param name=""x""></param>
public virtual int M(string y, int newIntegerParameter, int x)
{
return 1;
}
}
public class D : B
{
/// <param name=""b""></param>
/// <param name=""a""></param>
public override int M(string b, int newIntegerParameter, int a)
{
return 1;
}
}
public class D2 : D
{
/// <param name=""x""></param>
/// <param name=""y""></param>
public override int M(string x, int newIntegerParameter, int y)
{
M(""Two"", 12345, 1);
((D)this).M(""Two"", 12345, 1);
((B)this).M(""Two"", 12345, 1);
M(x: ""Two"", 12345, y: 1);
((D)this).M(b: ""Two"", a: 1, newIntegerParameter: 12345);
((B)this).M(y: ""Two"", x: 1, newIntegerParameter: 12345);
return 1;
}
}";
await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode);
}
}
}
......@@ -66,7 +66,7 @@ static class Ext
static class Ext
{
/// <summary>
/// This is a summary of <see cref=""M(object, string,int,string, string)""/>
/// This is a summary of <see cref=""M(object, string, int, string, string)""/>
/// </summary>
/// <param name=""o""></param>
/// <param name=""b""></param>
......@@ -79,24 +79,24 @@ static void M(this object o, string b, int newIntegerParameter, string newString
{
object t = new object();
M(t, ""two"", 12345,, ""four"");
M(t, ""two"", 12345,, ""four"");
t.M(""two"", 12345,, ""four"");
t.M(""two"", 12345,, ""four"");
M(t, ""two"", 12345, , ""four"");
M(t, ""two"", 12345, , ""four"");
t.M(""two"", 12345, , ""four"");
t.M(""two"", 12345, , ""four"");
M(t, ""two"", 12345,, ""four"");
M(t, ""two"", 12345,);
M(t, ""two"", 12345,);
M(t, ""two"", 12345, , ""four"");
M(t, ""two"", 12345, );
M(t, ""two"", 12345, );
M(t, ""two"", 12345,);
M(t, ""two"", 12345,, y: ""four"");
M(t, ""two"", 12345, );
M(t, ""two"", 12345, , y: ""four"");
M(t, ""two"", 12345,);
M(t, ""two"", 12345,);
M(t, ""two"", 12345,, y: ""four"");
M(t, ""two"", 12345,);
M(t, ""two"", 12345, );
M(t, ""two"", 12345, );
M(t, ""two"", 12345, , y: ""four"");
M(t, ""two"", 12345, );
M(t, ""two"", 12345,, y: ""four"");
M(t, ""two"", 12345, , y: ""four"");
M(t, y: ""four"", newIntegerParameter: 12345, newString:, b: ""two"");
M(t, y: ""four"", newIntegerParameter: 12345, newString:, b: ""two"");
M(t, y: ""four"", newIntegerParameter: 12345, newString:, b: ""two"");
......@@ -1024,7 +1024,7 @@ class C
class C
{
/// <summary>
/// See <see cref=""M(string,byte, int)""/> and <see cref=""M""/>
/// See <see cref=""M(string, byte, int)""/> and <see cref=""M""/>
/// </summary>
void M(string y, byte b, int x)
{ }
......
......@@ -303,35 +303,35 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (updatedNode.IsKind(SyntaxKind.MethodDeclaration))
{
var method = (MethodDeclarationSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(method.ParameterList.Parameters, signaturePermutation);
var updatedParameters = PermuteDeclaration(method.ParameterList.Parameters, signaturePermutation, CreateNewParameterSyntax);
return method.WithParameterList(method.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
}
if (updatedNode.IsKind(SyntaxKind.LocalFunctionStatement))
{
var localFunction = (LocalFunctionStatementSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(localFunction.ParameterList.Parameters, signaturePermutation);
var updatedParameters = PermuteDeclaration(localFunction.ParameterList.Parameters, signaturePermutation, CreateNewParameterSyntax);
return localFunction.WithParameterList(localFunction.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
}
if (updatedNode.IsKind(SyntaxKind.ConstructorDeclaration))
{
var constructor = (ConstructorDeclarationSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(constructor.ParameterList.Parameters, signaturePermutation);
var updatedParameters = PermuteDeclaration(constructor.ParameterList.Parameters, signaturePermutation, CreateNewParameterSyntax);
return constructor.WithParameterList(constructor.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
}
if (updatedNode.IsKind(SyntaxKind.IndexerDeclaration))
{
var indexer = (IndexerDeclarationSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(indexer.ParameterList.Parameters, signaturePermutation);
var updatedParameters = PermuteDeclaration(indexer.ParameterList.Parameters, signaturePermutation, CreateNewParameterSyntax);
return indexer.WithParameterList(indexer.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
}
if (updatedNode.IsKind(SyntaxKind.DelegateDeclaration))
{
var delegateDeclaration = (DelegateDeclarationSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(delegateDeclaration.ParameterList.Parameters, signaturePermutation);
var updatedParameters = PermuteDeclaration(delegateDeclaration.ParameterList.Parameters, signaturePermutation, CreateNewParameterSyntax);
return delegateDeclaration.WithParameterList(delegateDeclaration.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
}
......@@ -345,7 +345,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
return anonymousMethod;
}
var updatedParameters = PermuteDeclaration(anonymousMethod.ParameterList.Parameters, signaturePermutation);
var updatedParameters = PermuteDeclaration(anonymousMethod.ParameterList.Parameters, signaturePermutation, CreateNewParameterSyntax);
return anonymousMethod.WithParameterList(anonymousMethod.ParameterList.WithParameters(updatedParameters).WithAdditionalAnnotations(changeSignatureFormattingAnnotation));
}
......@@ -355,7 +355,12 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (signaturePermutation.UpdatedConfiguration.ToListOfParameters().Any())
{
Debug.Assert(false, "Updating a simple lambda expression without removing its parameter");
var updatedParameters = PermuteDeclaration(SyntaxFactory.SeparatedList<ParameterSyntax>(new[] { lambda.Parameter }), signaturePermutation, CreateNewParameterSyntax);
return SyntaxFactory.ParenthesizedLambdaExpression(
lambda.AsyncKeyword,
SyntaxFactory.ParameterList(updatedParameters),
lambda.ArrowToken,
lambda.Body);
}
else
{
......@@ -372,7 +377,14 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
if (updatedNode.IsKind(SyntaxKind.ParenthesizedLambdaExpression))
{
var lambda = (ParenthesizedLambdaExpressionSyntax)updatedNode;
var updatedParameters = PermuteDeclaration(lambda.ParameterList.Parameters, signaturePermutation);
bool doNotSkipType = lambda.ParameterList.Parameters.Any() && lambda.ParameterList.Parameters.First().Type != null;
Func<AddedParameter, ParameterSyntax> createNewParameterDelegate =
p => CreateNewParameterSyntax(p, !doNotSkipType);
var updatedParameters = PermuteDeclaration(
lambda.ParameterList.Parameters,
signaturePermutation,
createNewParameterDelegate);
return lambda.WithParameterList(lambda.ParameterList.WithParameters(updatedParameters));
}
......@@ -439,7 +451,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
return nameMemberCref;
}
var newParameters = PermuteDeclaration(nameMemberCref.Parameters.Parameters, signaturePermutation);
var newParameters = PermuteDeclaration(nameMemberCref.Parameters.Parameters, signaturePermutation, CreateNewCrefParameterSyntax);
var newCrefParameterList = nameMemberCref.Parameters.WithParameters(newParameters);
return nameMemberCref.WithParameters(newCrefParameterList);
......@@ -477,7 +489,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
seenNameEquals ? SyntaxFactory.NameColon(addedParameter.Name) : default,
refKindKeyword: default,
expression: SyntaxFactory.ParseExpression(addedParameter.CallsiteValue)));
separators.Add(SyntaxFactory.Token(SyntaxKind.CommaToken));
separators.Add(SyntaxFactory.Token(SyntaxKind.CommaToken).WithTrailingTrivia(SyntaxFactory.ElasticSpace));
}
}
else
......@@ -511,35 +523,32 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
fullList.Add(newArguments[indexInExistingList++]);
}
if (fullList.Count == separators.Count && separators.Count != 0)
{
separators.Remove(separators.Last());
}
return SyntaxFactory.SeparatedList(fullList, separators);
}
private T CreateNewParameter<T>(AddedParameter addedParameter) where T : SyntaxNode
{
var type = typeof(T);
private static ParameterSyntax CreateNewParameterSyntax(AddedParameter addedParameter)
=> CreateNewParameterSyntax(addedParameter, skipType: false);
if (type == typeof(ParameterSyntax))
{
return SyntaxFactory.Parameter(
attributeLists: SyntaxFactory.List<AttributeListSyntax>(),
modifiers: SyntaxFactory.TokenList(),
type: SyntaxFactory.ParseTypeName(addedParameter.TypeName),
SyntaxFactory.Identifier(addedParameter.ParameterName),
@default: default) as T;
}
private static ParameterSyntax CreateNewParameterSyntax(AddedParameter addedParameter, bool skipType)
=> SyntaxFactory.Parameter(
attributeLists: SyntaxFactory.List<AttributeListSyntax>(),
modifiers: SyntaxFactory.TokenList(),
type: skipType ? default : SyntaxFactory.ParseTypeName(addedParameter.TypeName).WithTrailingTrivia(SyntaxFactory.ElasticSpace),
SyntaxFactory.Identifier(addedParameter.ParameterName),
@default: default);
if (type == typeof(CrefParameterSyntax))
{
return SyntaxFactory.CrefParameter(
type: SyntaxFactory.ParseTypeName(addedParameter.TypeName)) as T;
}
return default;
}
private static CrefParameterSyntax CreateNewCrefParameterSyntax(AddedParameter addedParameter)
=> SyntaxFactory.CrefParameter(type: SyntaxFactory.ParseTypeName(addedParameter.TypeName)).WithLeadingTrivia(SyntaxFactory.ElasticSpace);
private SeparatedSyntaxList<T> PermuteDeclaration<T>(
SeparatedSyntaxList<T> list,
SignatureChange updatedSignature) where T : SyntaxNode
SignatureChange updatedSignature,
Func<AddedParameter, T> createNewParameterMethod) where T : SyntaxNode
{
var originalParameters = updatedSignature.OriginalConfiguration.ToListOfParameters();
var reorderedParameters = updatedSignature.UpdatedConfiguration.ToListOfParameters();
......@@ -556,7 +565,7 @@ private SyntaxNode GetNodeContainingTargetNode(SyntaxNode matchingNode)
{
// Added parameter
numAddedParameters++;
var newParameter = CreateNewParameter<T>(newParam as AddedParameter);
var newParameter = createNewParameterMethod(newParam as AddedParameter);
newParameters.Add(newParameter);
}
else
......@@ -795,7 +804,7 @@ private List<SyntaxTrivia> GetPermutedTrivia(CSharpSyntaxNode node, List<XmlElem
var extraNodeList = new List<XmlNodeSyntax>();
while (index < permutedParamNodes.Count)
{
extraNodeList.Add(permutedParamNodes[index]);//.WithLeadingTrivia(node.GetLeadingTrivia()).WithTrailingTrivia(node.GetTrailingTrivia()));
extraNodeList.Add(permutedParamNodes[index]);
index++;
}
......@@ -820,7 +829,7 @@ private List<SyntaxTrivia> GetPermutedTrivia(CSharpSyntaxNode node, List<XmlElem
{
if (i >= arguments.SeparatorCount)
{
separators.Add(SyntaxFactory.Token(SyntaxKind.CommaToken));
separators.Add(SyntaxFactory.Token(SyntaxKind.CommaToken).WithTrailingTrivia(SyntaxFactory.ElasticSpace));
}
else
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册