File: ImplementationIsObsoleteAnalyzerTests.cs
Web Access
Project: src\src\RoslynAnalyzers\Microsoft.CodeAnalysis.Analyzers\UnitTests\Microsoft.CodeAnalysis.Analyzers.UnitTests.csproj (Microsoft.CodeAnalysis.Analyzers.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 Test.Utilities;
using Xunit;
using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<Microsoft.CodeAnalysis.Analyzers.ImplementationIsObsoleteAnalyzer, Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier<Microsoft.CodeAnalysis.Analyzers.ImplementationIsObsoleteAnalyzer, Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
 
namespace Microsoft.CodeAnalysis.Analyzers.UnitTests
{
    public class ImplementationIsObsoleteAnalyzerTests
    {
        private const string AttributeStringCSharp = """
 
            namespace System.Runtime.CompilerServices
            {
                internal class ImplementationIsObsoleteAttribute : System.Attribute { public ImplementationIsObsoleteAttribute(string url) { } }
            }
 
            """;
        [Fact]
        public async Task CSharp_VerifySameAssemblyAsync()
        {
            string source = $$"""
                {{AttributeStringCSharp}}
 
                [System.Runtime.CompilerServices.ImplementationIsObsoleteAttribute("https://example.com")]
                public interface IMyInterface { }
 
                class SomeClass : IMyInterface { }
                """;
 
            // Verify no diagnostic since interface is in the same assembly.
            await new VerifyCS.Test
            {
                ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithoutRoslynSymbols,
                TestState = { Sources = { source } },
            }.RunAsync();
        }
 
        [Fact]
        public async Task CSharp_VerifyDifferentAssemblyAsync()
        {
            string source1 = AttributeStringCSharp + """
 
 
                [System.Runtime.CompilerServices.ImplementationIsObsoleteAttribute("https://example.com")]
                public interface IMyInterface { }
 
                public interface IMyOtherInterface : IMyInterface { }
                """;
 
            var source2 = """
 
                class SomeClass : IMyInterface { }
 
                class SomeOtherClass : IMyOtherInterface { }
                """;
 
            // Verify errors since interface is not in a friend assembly.
            await new VerifyCS.Test
            {
                ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithoutRoslynSymbols,
                TestState =
                {
                    Sources = { source2 },
                    AdditionalProjects =
                    {
                        ["DependencyProject"] =
                        {
                            Sources = { source1 },
                        },
                    },
                    AdditionalProjectReferences = { "DependencyProject" },
                    ExpectedDiagnostics =
                    {
                        // /0/Test0.cs(2,7): error RS1042: Type SomeClass cannot implement interface IMyInterface because IMyInterface is obsolete for implementation. See https://example.com for more details.
                        VerifyCS.Diagnostic().WithSpan(2, 7, 2, 16).WithArguments("SomeClass", "IMyInterface", "https://example.com"),
                        // /0/Test0.cs(4,7): error RS1042: Type SomeOtherClass cannot implement interface IMyInterface because IMyInterface is obsolete for implementation. See https://example.com for more details.
                        VerifyCS.Diagnostic().WithSpan(4, 7, 4, 21).WithArguments("SomeOtherClass", "IMyInterface", "https://example.com"),
                    },
                },
            }.RunAsync();
        }
 
        [Fact]
        public async Task CSharp_VerifyDifferentFriendAssemblyAsync()
        {
            string source1 = $$"""

                [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("TestProject")]
 
                {{AttributeStringCSharp}}
 
 
                [System.Runtime.CompilerServices.ImplementationIsObsoleteAttribute("https://example.com")]
                public interface IMyInterface { }
 
                public interface IMyOtherInterface : IMyInterface { }
                """;
 
            var source2 = """
 
                class SomeClass : IMyInterface { }
 
                class SomeOtherClass : IMyOtherInterface { }
                """;
 
            // Verify no diagnostic since interface is in a friend assembly.
            await new VerifyCS.Test
            {
                ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithoutRoslynSymbols,
                TestState =
                {
                    Sources = { source2 },
                    AdditionalProjects =
                    {
                        ["DependencyProject"] =
                        {
                            Sources = { source1 },
                        },
                    },
                    AdditionalProjectReferences = { "DependencyProject" },
                },
            }.RunAsync();
        }
 
        private const string AttributeStringBasic = """
 
            Namespace System.Runtime.CompilerServices
                Friend Class ImplementationIsObsoleteAttribute 
                    Inherits System.Attribute
 
                    Public Sub New(url As String)
                    End Sub
                End Class
            End Namespace
 
            """;
 
        [Fact]
        public async Task Basic_VerifySameAssemblyAsync()
        {
            string source = $"""
                {AttributeStringBasic}
 
                <System.Runtime.CompilerServices.ImplementationIsObsoleteAttribute("https://example.com")>
                Public Interface IMyInterface
                End Interface
 
                Class SomeClass 
                    Implements IMyInterface 
                End Class
                """;
 
            // Verify no diagnostic since interface is in the same assembly.
            await new VerifyVB.Test
            {
                ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithoutRoslynSymbols,
                TestState = { Sources = { source } },
            }.RunAsync();
        }
 
        [Fact]
        public async Task Basic_VerifyDifferentAssemblyAsync()
        {
            string source1 = $"""
                {AttributeStringBasic}
 
                <System.Runtime.CompilerServices.ImplementationIsObsoleteAttribute("https://example.com")>
                Public Interface IMyInterface
                End Interface
 
                Public Interface IMyOtherInterface
                    Inherits IMyInterface
                End Interface

                """;
 
            var source2 = """
 
                Class SomeClass 
                    Implements IMyInterface 
                End Class
 
                Class SomeOtherClass
                    Implements IMyOtherInterface
                End Class
 
                """;
 
            // Verify errors since interface is not in a friend assembly.
            await new VerifyVB.Test
            {
                ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithoutRoslynSymbols,
                TestState =
                {
                    Sources = { source2 },
                    AdditionalProjects =
                    {
                        ["DependencyProject"] =
                        {
                            Sources = { source1 },
                        },
                    },
                    AdditionalProjectReferences = { "DependencyProject" },
                    ExpectedDiagnostics =
                    {
                        // /0/Test0.vb(2,7): error RS1042: Type SomeClass cannot implement interface IMyInterface because IMyInterface is obsolete for implementation. See https://example.com for more details.
                        VerifyVB.Diagnostic().WithSpan(2, 7, 2, 16).WithArguments("SomeClass", "IMyInterface", "https://example.com"),
                        // /0/Test0.vb(6,7): error RS1042: Type SomeOtherClass cannot implement interface IMyInterface because IMyInterface is obsolete for implementation. See https://example.com for more details.
                        VerifyVB.Diagnostic().WithSpan(6, 7, 6, 21).WithArguments("SomeOtherClass", "IMyInterface", "https://example.com"),
                    },
                },
            }.RunAsync();
        }
 
        [Fact]
        public async Task Basic_VerifyDifferentFriendAssemblyAsync()
        {
            string source1 = $"""
                <Assembly: System.Runtime.CompilerServices.InternalsVisibleTo("TestProject")>
                {AttributeStringBasic}
 
                <System.Runtime.CompilerServices.ImplementationIsObsoleteAttribute("https://example.com")>
                Public Interface IMyInterface
                End Interface
 
                Public Interface IMyOtherInterface
                    Inherits IMyInterface
                End Interface
                """;
 
            var source2 = @"
Class SomeClass 
    Implements IMyInterface 
End Class
 
Class SomeOtherClass
    Implements IMyOtherInterface
End Class
";
 
            // Verify no diagnostic since interface is in a friend assembly.
            await new VerifyVB.Test
            {
                ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithoutRoslynSymbols,
                TestState =
                {
                    Sources = { source2 },
                    AdditionalProjects =
                    {
                        ["DependencyProject"] =
                        {
                            Sources = { source1 },
                        },
                    },
                    AdditionalProjectReferences = { "DependencyProject" },
                },
            }.RunAsync();
        }
    }
}