|
// 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.
#nullable disable
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CSharp.SplitOrMergeIfStatements;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SplitOrMergeIfStatements;
[Trait(Traits.Feature, Traits.Features.CodeActionsMergeConsecutiveIfStatements)]
public sealed partial class MergeConsecutiveIfStatementsTests : AbstractCSharpCodeActionTest_NoEditor
{
protected override CodeRefactoringProvider CreateCodeRefactoringProvider(TestWorkspace workspace, TestParameters parameters)
=> new CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider();
[Theory]
[InlineData("[||]else if (b)")]
[InlineData("el[||]se if (b)")]
[InlineData("else[||] if (b)")]
[InlineData("else [||]if (b)")]
[InlineData("else i[||]f (b)")]
[InlineData("else if[||] (b)")]
[InlineData("else if [||](b)")]
[InlineData("else if (b)[||]")]
[InlineData("else [|if|] (b)")]
[InlineData("else [|if (b)|]")]
[InlineData("[|else if (b)|]")]
public async Task MergedOnElseIfSpans(string elseIfLine)
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
" + elseIfLine + @"
{
}
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
{
}
}
}");
}
[Fact]
public async Task MergedOnElseIfExtendedHeaderSelection()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
[| else if (b)
|] {
}
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
{
}
}
}");
}
[Fact]
public async Task MergedOnElseIfFullSelectionWithoutElseClause()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
else [|if (b)
{
}|]
else
{
}
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
{
}
else
{
}
}
}");
}
[Fact]
public async Task MergedOnElseIfExtendedFullSelectionWithoutElseClause()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
[| else if (b)
{
}
|] else
{
}
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
{
}
else
{
}
}
}");
}
[Fact]
public async Task NotMergedOnElseIfFullSelectionWithElseClause()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
else [|if (b)
{
}
else
{
}|]
}
}");
}
[Fact]
public async Task NotMergedOnElseIfExtendedFullSelectionWithElseClause()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
[| else if (b)
{
}
else
{
}
|] }
}");
}
[Theory]
[InlineData("else if ([||]b)")]
[InlineData("[|else|] if (b)")]
[InlineData("[|else if|] (b)")]
[InlineData("else [|i|]f (b)")]
[InlineData("else [|if (|]b)")]
[InlineData("else if [|(|]b)")]
[InlineData("else if (b[|)|]")]
[InlineData("else if ([|b|])")]
[InlineData("else if [|(b)|]")]
public async Task NotMergedOnElseIfSpans(string elseIfLine)
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
" + elseIfLine + @"
{
}
}
}");
}
[Fact]
public async Task NotMergedOnElseIfOverreachingSelection1()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
else [|if (b)
|]{
}
}
}");
}
[Fact]
public async Task NotMergedOnElseIfOverreachingSelection2()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
[|else if (b)
{|]
}
}
}");
}
[Fact]
public async Task NotMergedOnElseIfBodySelection()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
else if (b)
[|{
}|]
}
}");
}
[Fact]
public async Task NotMergedOnElseIfBodyCaret1()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
else if (b)
[||]{
}
}
}");
}
[Fact]
public async Task NotMergedOnElseIfBodyCaret2()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
}
else if (b)
{
}[||]
}
}");
}
[Fact]
public async Task NotMergedOnSingleIf()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
[||]if (b)
{
}
}
}");
}
[Fact]
public async Task MergedWithOrExpressions()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if (a || b)
{
}
else [||]if (c || d)
{
}
}
}",
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if (a || b || c || d)
{
}
}
}");
}
[Fact]
public async Task MergedWithAndExpressionNotParenthesized1()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if (a && b)
{
}
else [||]if (c || d)
{
}
}
}",
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if (a && b || c || d)
{
}
}
}");
}
[Fact]
public async Task MergedWithAndExpressionNotParenthesized2()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if (a || b)
{
}
else [||]if (c && d)
{
}
}
}",
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if (a || b || c && d)
{
}
}
}");
}
[Fact]
public async Task MergedWithConditionalExpressionParenthesized1()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if (true ? a : b)
{
}
else [||]if (c == d)
{
}
}
}",
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if ((true ? a : b) || c == d)
{
}
}
}");
}
[Fact]
public async Task MergedWithConditionalExpressionParenthesized2()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if (a == b)
{
}
else [||]if (true ? c : d)
{
}
}
}",
@"class C
{
void M(bool a, bool b, bool c, bool d)
{
if (a == b || (true ? c : d))
{
}
}
}");
}
[Fact]
public async Task MergedIntoParentWithStatementInsideBlock()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
System.Console.WriteLine(a || b);
}
else [||]if (b)
{
System.Console.WriteLine(a || b);
}
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
{
System.Console.WriteLine(a || b);
}
}
}");
}
[Fact]
public async Task MergedIntoParentWithStatementWithoutBlock()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
System.Console.WriteLine(a || b);
else [||]if (b)
System.Console.WriteLine(a || b);
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
System.Console.WriteLine(a || b);
}
}");
}
[Fact]
public async Task MergedIntoParentWithDifferenceInBlocks1()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
System.Console.WriteLine(a || b);
else [||]if (b)
{
System.Console.WriteLine(a || b);
}
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
System.Console.WriteLine(a || b);
}
}");
}
[Fact]
public async Task MergedIntoParentWithDifferenceInBlocks2()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
System.Console.WriteLine(a || b);
}
else [||]if (b)
System.Console.WriteLine(a || b);
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
{
System.Console.WriteLine(a || b);
}
}
}");
}
[Fact]
public async Task MergedIntoParentWithDifferenceInBlocks3()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
System.Console.WriteLine(a || b);
}
else [||]if (b)
{
{
System.Console.WriteLine(a || b);
}
}
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
{
System.Console.WriteLine(a || b);
}
}
}");
}
[Fact]
public async Task NotMergedIntoParentWithUnmatchingStatements1()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
System.Console.WriteLine(a || b);
}
else [||]if (b)
{
System.Console.WriteLine(a || a);
}
}
}");
}
[Fact]
public async Task NotMergedIntoParentWithUnmatchingStatements2()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
System.Console.WriteLine(a || b);
else [||]if (b)
System.Console.WriteLine(a || a);
}
}");
}
[Fact]
public async Task NotMergedIntoParentWithUnmatchingStatements3()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
System.Console.WriteLine(a);
}
else [||]if (b)
System.Console.WriteLine(b);
}
}");
}
[Fact]
public async Task NotMergedIntoParentWithUnmatchingStatements4()
{
// Do not consider the using statement to be a simple block (as might be suggested by some language-agnostic helpers).
await TestMissingInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
{
System.Console.WriteLine(a);
}
else [||]if (b)
using (null)
System.Console.WriteLine(a);
}
}");
}
[Fact]
public async Task MergedIntoParentWithElseStatementInsideBlock()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
System.Console.WriteLine();
else [||]if (b)
System.Console.WriteLine();
else
{
System.Console.WriteLine(a || b);
}
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
System.Console.WriteLine();
else
{
System.Console.WriteLine(a || b);
}
}
}");
}
[Fact]
public async Task MergedIntoParentWithElseStatementWithoutBlock()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
System.Console.WriteLine();
else [||]if (b)
System.Console.WriteLine();
else
System.Console.WriteLine(a || b);
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
System.Console.WriteLine();
else
System.Console.WriteLine(a || b);
}
}");
}
[Fact]
public async Task MergedIntoParentWithElseNestedIfStatement()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
System.Console.WriteLine();
else [||]if (b)
System.Console.WriteLine();
else if (true) { }
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
System.Console.WriteLine();
else if (true) { }
}
}");
}
[Fact]
public async Task MergedIntoParentWithElseIfElse()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
System.Console.WriteLine();
else [||]if (b)
System.Console.WriteLine();
else if (a)
System.Console.WriteLine(a);
else
System.Console.WriteLine(b);
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b)
System.Console.WriteLine();
else if (a)
System.Console.WriteLine(a);
else
System.Console.WriteLine(b);
}
}");
}
[Fact]
public async Task MergedIntoParentPartOfElseIf()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a)
System.Console.WriteLine();
else if (b)
System.Console.WriteLine(a);
else [||]if (a)
System.Console.WriteLine(a);
else
System.Console.WriteLine(b);
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a)
System.Console.WriteLine();
else if (b || a)
System.Console.WriteLine(a);
else
System.Console.WriteLine(b);
}
}");
}
[Fact]
public async Task MergedWithPreservedSingleLineFormatting()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(bool a, bool b)
{
if (a) System.Console.WriteLine();
else [||]if (b) System.Console.WriteLine();
}
}",
@"class C
{
void M(bool a, bool b)
{
if (a || b) System.Console.WriteLine();
}
}");
}
}
|