File: src\Analyzers\CSharp\Tests\SimplifyBooleanExpression\SimplifyConditionalTests.cs
Web Access
Project: src\src\CodeStyle\CSharp\Tests\Microsoft.CodeAnalysis.CSharp.CodeStyle.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.CodeStyle.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.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.SimplifyBooleanExpression;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.SimplifyBooleanExpression;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SimplifyBooleanExpression;
 
[Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyConditional)]
public sealed partial class SimplifyConditionalTests(ITestOutputHelper logger)
    : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor(logger)
{
    internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace)
        => (new CSharpSimplifyConditionalDiagnosticAnalyzer(), new SimplifyConditionalCodeFixProvider());
 
    [Fact]
    public async Task TestSimpleCase()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                bool M()
                {
                    return [|X() && Y() ? true : false|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                bool M()
                {
                    return X() && Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact]
    public async Task TestSimpleNegatedCase()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                bool M()
                {
                    return [|X() && Y() ? false : true|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                bool M()
                {
                    return !X() || !Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact]
    public async Task TestMustBeBool1()
    {
        await TestMissingInRegularAndScriptAsync(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X() && Y() ? "" : null|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact]
    public async Task TestMustBeBool2()
    {
        await TestMissingAsync(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X() && Y() ? null : ""|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact]
    public async Task TestWithTrueTrue()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                bool M()
                {
                    return [|X() && Y() ? true : true|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                bool M()
                {
                    return X() && Y() || true;
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact]
    public async Task TestWithFalseFalse()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                bool M()
                {
                    return [|X() && Y() ? false : false|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                bool M()
                {
                    return X() && Y() && false;
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact]
    public async Task TestWhenTrueIsTrueAndWhenFalseIsUnknown()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X() ? true : Y()|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                string M()
                {
                    return X() || Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71418")]
    public async Task TestWhenTrueIsTrueAndWhenFalseIsUnknown_A()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X()
                        ? true
                        : Y()|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                string M()
                {
                    return X() || Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact]
    public async Task TestWhenTrueIsFalseAndWhenFalseIsUnknown()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X() ? false : Y()|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                string M()
                {
                    return !X() && Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71418")]
    public async Task TestWhenTrueIsFalseAndWhenFalseIsUnknown_A()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X()
                        ? false
                        : Y()|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                string M()
                {
                    return !X() && Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact]
    public async Task TestWhenTrueIsUnknownAndWhenFalseIsTrue()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X() ? Y() : true|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                string M()
                {
                    return !X() || Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71418")]
    public async Task TestWhenTrueIsUnknownAndWhenFalseIsTrue_A()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X()
                        ? Y()
                        : true|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                string M()
                {
                    return !X() || Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact]
    public async Task TestWhenTrueIsUnknownAndWhenFalseIsFalse()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X() ? Y() : false|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                string M()
                {
                    return X() && Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71418")]
    public async Task TestWhenTrueIsUnknownAndWhenFalseIsFalse_A()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                string M()
                {
                    return [|X()
                        ? Y()
                        : false|];
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """,
            """
            using System;
 
            class C
            {
                string M()
                {
                    return X() && Y();
                }
 
                private bool X() => throw new NotImplementedException();
                private bool Y() => throw new NotImplementedException();
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62827")]
    public async Task TestFixAll()
    {
        await TestInRegularAndScriptAsync(
            """
            using System;
 
            class C
            {
                public bool M(object x, object y, Func<object, object, bool> isEqual)
                {
                    return {|FixAllInDocument:x == null ? false : y == null ? false : isEqual == null ? x.Equals(y) : isEqual(x, y)|};
                }
            }
            """,
            """
            using System;
 
            class C
            {
                public bool M(object x, object y, Func<object, object, bool> isEqual)
                {
                    return x != null && y != null && (isEqual == null ? x.Equals(y) : isEqual(x, y));
                }
            }
            """);
    }
}