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 Task TestNoConvertToFileScopedInCSharp9()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp9,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestNoConvertToFileScopedInCSharp10WithFileScopedPreference()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToFileScopedInCSharp10WithBlockScopedPreference()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
            }
            """,
            FixedCode = """
            namespace $$N;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestOnNamespaceToken()
        => new VerifyCS.Test
        {
            TestCode = """
            $$namespace N
            {
            }
            """,
            FixedCode = """
            namespace N;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestNotBeforeNamespaceToken()
        => new VerifyCS.Test
        {
            TestCode = """
            $$
            namespace N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestNotOnOpenBrace()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace N
            $${
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestNoConvertWithMultipleNamespaces()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
            }
 
            namespace N2
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestNoConvertWithNestedNamespaces1()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
                namespace N2
                {
                }
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestNoConvertWithNestedNamespaces2()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace N
            {
                namespace $$N2
                {
                }
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestNoConvertWithTopLevelStatement1()
        => new VerifyCS.Test
        {
            TestCode = """
            {|CS8805:int i = 0;|}
 
            namespace $$N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestNoConvertWithTopLevelStatement2()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
            }
 
            {|CS8805:{|CS8803:int i = 0;|}|}
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToFileScopedWithUsing1()
        => new VerifyCS.Test
        {
            TestCode = """
            using System;
 
            namespace $$N
            {
            }
            """,
            FixedCode = """
            using System;
 
            namespace $$N;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToFileScopedWithUsing2()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
                using System;
            }
            """,
            FixedCode = """
            namespace $$N;
 
            using System;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToFileScopedWithClass()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N
            {
                class C
                {
                }
            }
            """,
            FixedCode = """
            namespace $$N;
 
            class C
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToFileScopedWithClassWithDocComment()
        => 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 Task TestConvertToFileScopedWithMissingCloseBrace()
        => 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 Task TestConvertToFileScopedWithCommentOnOpenCurly()
        => 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 Task TestConvertToFileScopedWithLeadingComment()
        => 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 Task TextConvertToFileScopedWithCommentedOutContents()
        => 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 Task TextConvertToFileScopedWithCommentedAfterContents()
        => 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 Task TextConvertToFileScopedWithTriviaAroundNamespace1()
        => 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 Task TextConvertToFileScopedWithTriviaAroundNamespace2()
        => 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 Task TestConvertToBlockScopedInCSharp9(string endOfDocumentSequence)
        => new VerifyCS.Test
        {
            TestCode = $$"""
            {|CS8773:namespace|} $$N;{{endOfDocumentSequence}}
            """,
            FixedCode = $$"""
            namespace $$N
            {
            }{{endOfDocumentSequence}}
            """,
            LanguageVersion = LanguageVersion.CSharp9,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestNoConvertToBlockScopedInCSharp10WithBlockScopedPreference()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToBlockScopedInCSharp10WithFileScopedPreference()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
            """,
            FixedCode = """
            namespace $$N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToBlockOnNamespaceToken2()
        => new VerifyCS.Test
        {
            TestCode = """
            $$namespace N;
            """,
            FixedCode = """
            namespace N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToBlockNotBeforeNamespaceToken2()
        => new VerifyCS.Test
        {
            TestCode = """
            $$
            namespace N;
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToBlockNotAfterSemicolon()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace N;
            $$
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToBlockAfterSemicolon()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace N; $$
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToBlockWithMultipleNamespaces()
        => 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 Task TestConvertToBlockWithNestedNamespaces1()
        => 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 Task TestConvertToBlockWithNestedNamespaces2()
        => 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 Task TestConvertToBlockWithTopLevelStatement1()
        => 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 Task TestConvertToBlockWithTopLevelStatement2()
        => 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 Task TestConvertToBlockScopedWithUsing1()
        => new VerifyCS.Test
        {
            TestCode = """
            using System;
 
            namespace $$N;
            """,
            FixedCode = """
            using System;
 
            namespace $$N
            {
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToBlockScopedWithUsing2()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
 
            using System;
            """,
            FixedCode = """
            namespace $$N
            {
                using System;
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToBlockScopedWithClass()
        => new VerifyCS.Test
        {
            TestCode = """
            namespace $$N;
 
            class C
            {
            }
            """,
            FixedCode = """
            namespace $$N
            {
                class C
                {
                }
            }
            """,
            LanguageVersion = LanguageVersion.CSharp10,
            Options =
            {
                { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped }
            }
        }.RunAsync();
 
    [Fact]
    public Task TestConvertToBlockScopedWithClassWithDocComment()
        => 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 Task TestConvertToBlockScopedWithMissingCloseBrace()
        => 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 Task TestConvertToBlockScopedWithCommentOnSemicolon()
        => 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 Task TestConvertToBlockScopedWithLeadingComment()
        => 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
}