File: ConvertNamespace\ConvertNamespaceRefactoringTests.cs
Web Access
Project: src\src\Features\CSharpTest\Microsoft.CodeAnalysis.CSharp.Features.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Features.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.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.ConvertNamespace;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Testing;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertNamespace;
 
using VerifyCS = CSharpCodeRefactoringVerifier<ConvertNamespaceCodeRefactoringProvider>;
 
[UseExportProvider]
public sealed class ConvertNamespaceRefactoringTests
{
    public static IEnumerable<object[]> EndOfDocumentSequences => [[""], ["\r\n"]];
 
    #region Convert To File Scoped
 
    [Fact]
    public async Task TestNoConvertToFileScopedInCSharp9()
    {
        var code = """
            namespace $$N
            {
            }
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp9,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNoConvertToFileScopedInCSharp10WithFileScopedPreference()
    {
        var code = """
            namespace $$N
            {
            }
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToFileScopedInCSharp10WithBlockScopedPreference()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
            }
            """,
            FixedCode = """
            namespace $$N;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestOnNamespaceToken()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            $$namespace N
            {
            }
            """,
            FixedCode = """
            namespace N;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNotBeforeNamespaceToken()
    {
        var code = """
            $$
            namespace N
            {
            }
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNotOnOpenBrace()
    {
        var code = """
            namespace N
            $${
            }
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNoConvertWithMultipleNamespaces()
    {
        var code = """
            namespace $$N
            {
            }
 
            namespace N2
            {
            }
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNoConvertWithNestedNamespaces1()
    {
        var code = """
            namespace $$N
            {
                namespace N2
                {
                }
            }
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNoConvertWithNestedNamespaces2()
    {
        var code = """
            namespace N
            {
                namespace $$N2
                {
                }
            }
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNoConvertWithTopLevelStatement1()
    {
        var code = """
            {|CS8805:int i = 0;|}
 
            namespace $$N
            {
            }
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNoConvertWithTopLevelStatement2()
    {
        var code = """
            namespace $$N
            {
            }
 
            {|CS8805:{|CS8803:int i = 0;|}|}
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToFileScopedWithUsing1()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            using System;
 
            namespace $$N
            {
            }
            """,
            FixedCode = """
            using System;
 
            namespace $$N;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToFileScopedWithUsing2()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
                using System;
            }
            """,
            FixedCode = """
            namespace $$N;
 
            using System;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToFileScopedWithClass()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
                class C
                {
                }
            }
            """,
            FixedCode = """
            namespace $$N;
 
            class C
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToFileScopedWithClassWithDocComment()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
                /// <summary/>
                class C
                {
                }
            }
            """,
            FixedCode = """
            namespace $$N;
 
            /// <summary/>
            class C
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToFileScopedWithMissingCloseBrace()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
                /// <summary/>
                class C
                {
                }{|CS1513:|}
            """,
            FixedCode = """
            namespace N;
 
            /// <summary/>
            class C
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToFileScopedWithCommentOnOpenCurly()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            { // comment
                class C
                {
                }
            }
            """,
            FixedCode = """
            namespace $$N;
            // comment
            class C
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToFileScopedWithLeadingComment()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            // copyright
            namespace $$N
            {
                class C
                {
                }
            }
            """,
            FixedCode = """
            // copyright
            namespace $$N;
 
            class C
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57564")]
    public async Task TextConvertToFileScopedWithCommentedOutContents()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            $$namespace N
            {
                // public class C
                // {
                // }
            }
            """,
            FixedCode = """
            namespace N;
 
            // public class C
            // {
            // }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57564")]
    public async Task TextConvertToFileScopedWithCommentedAfterContents()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            $$namespace N
            {
                public class C
                {
                }
 
                // I'll probably write some more code here later
            }
            """,
            FixedCode = """
            namespace N;
 
            public class C
            {
            }
 
            // I'll probably write some more code here later
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57564")]
    public async Task TextConvertToFileScopedWithTriviaAroundNamespace1()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            #if !NONEXISTENT
            $$namespace NDebug
            #else
            namespace NRelease
            #endif
            {
                public class C
                {
                }
            }
            """,
            FixedCode = """
            #if !NONEXISTENT
            namespace NDebug;
            #else
            namespace NRelease
            #endif
 
            public class C
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57564")]
    public async Task TextConvertToFileScopedWithTriviaAroundNamespace2()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            #if NONEXISTENT
            namespace NDebug
            #else
            $$namespace NRelease
            #endif
            {
                public class C
                {
                }
            }
            """,
            FixedCode = """
            #if NONEXISTENT
            namespace NDebug
            #else
            namespace NRelease;
            #endif
 
            public class C
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    #endregion
 
    #region Convert To Block Scoped
 
    [Theory]
    [MemberData(nameof(EndOfDocumentSequences))]
    public async Task TestConvertToBlockScopedInCSharp9(string endOfDocumentSequence)
    {
        await new VerifyCS.Test
        {
            TestCode = $$"""
            {|CS8773:namespace|} $$N;{{endOfDocumentSequence}}
            """,
            FixedCode = $$"""
            namespace $$N
            {
            }{{endOfDocumentSequence}}
            """,
            LanguageVersion = LanguageVersion.CSharp9,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestNoConvertToBlockScopedInCSharp10WithBlockScopedPreference()
    {
        var code = """
            namespace $$N;
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockScopedInCSharp10WithFileScopedPreference()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
            """,
            FixedCode = """
            namespace $$N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockOnNamespaceToken2()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            $$namespace N;
            """,
            FixedCode = """
            namespace N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockNotBeforeNamespaceToken2()
    {
        var code = """
            $$
            namespace N;
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockNotAfterSemicolon()
    {
        var code = """
            namespace N;
            $$
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockAfterSemicolon()
    {
        var code = """
            namespace N; $$
            """;
        await new VerifyCS.Test
        {
            TestCode = code,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockWithMultipleNamespaces()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
 
            namespace {|CS8955:N2|}
            {
            }
            """,
            FixedCode = """
            namespace $$N
            {
                namespace N2
                {
                }
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockWithNestedNamespaces1()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
 
            namespace {|CS8954:N2|};
            """,
            FixedCode = """
            namespace $$N
            {
                namespace {|CS8955:N2|};
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockWithNestedNamespaces2()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace N
            {
                namespace $${|CS8955:N2|};
            }
            """,
            FixedCode = """
            namespace N
            {
                namespace $$N2
                {
                }
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockWithTopLevelStatement1()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            {|CS8805:int i = 0;|}
 
            namespace $${|CS8956:N|};
            """,
            FixedCode = """
            {|CS8805:int i = 0;|}
 
            namespace $$N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockWithTopLevelStatement2()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
 
            int {|CS0116:i|} = 0;
            """,
            FixedCode = """
            namespace $$N
            {
                int {|CS0116:i|} = 0;
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockScopedWithUsing1()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            using System;
 
            namespace $$N;
            """,
            FixedCode = """
            using System;
 
            namespace $$N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockScopedWithUsing2()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
 
            using System;
            """,
            FixedCode = """
            namespace $$N
            {
                using System;
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockScopedWithClass()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
 
            class C
            {
            }
            """,
            FixedCode = """
            namespace $$N
            {
                class C
                {
                }
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockScopedWithClassWithDocComment()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
 
            /// <summary/>
            class C
            {
            }
            """,
            FixedCode = """
            namespace $$N
            {
                /// <summary/>
                class C
                {
                }
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockScopedWithMissingCloseBrace()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
 
            /// <summary/>
            class C
            {{|CS1513:|}
            """,
            FixedCode = """
            namespace N
            {
                /// <summary/>
                class C
                {
            }{|CS1513:|}
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            CodeActionValidationMode = CodeActionValidationMode.None,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockScopedWithCommentOnSemicolon()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            namespace $$N; // comment
 
            class C
            {
            }
            """,
            FixedCode = """
            namespace $$N
            { // comment
                class C
                {
                }
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    [Fact]
    public async Task TestConvertToBlockScopedWithLeadingComment()
    {
        await new VerifyCS.Test
        {
            TestCode = """
            // copyright
            namespace $$N;
 
            class C
            {
            }
            """,
            FixedCode = """
            // copyright
            namespace $$N
            {
                class C
                {
                }
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
    }
 
    #endregion
}