File: Microsoft.CodeQuality.Analyzers\ApiDesignGuidelines\IdentifiersShouldHaveCorrectSuffixTests.cs
Web Access
Project: ..\..\..\src\Microsoft.CodeAnalysis.NetAnalyzers\tests\Microsoft.CodeAnalysis.NetAnalyzers.UnitTests\Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj (Microsoft.CodeAnalysis.NetAnalyzers.UnitTests)
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the MIT license.  See License.txt in the project root for license information.
 
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using Test.Utilities;
using Xunit;
using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
    Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines.IdentifiersShouldHaveCorrectSuffixAnalyzer,
    Microsoft.CodeQuality.CSharp.Analyzers.ApiDesignGuidelines.CSharpIdentifiersShouldHaveCorrectSuffixFixer>;
using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier<
    Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines.IdentifiersShouldHaveCorrectSuffixAnalyzer,
    Microsoft.CodeQuality.VisualBasic.Analyzers.ApiDesignGuidelines.BasicIdentifiersShouldHaveCorrectSuffixFixer>;
 
namespace Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines.UnitTests
{
    public class IdentifiersShouldHaveCorrectSuffixTests
    {
        [Fact]
        public async Task CA1710_AllScenarioDiagnostics_CSharpAsync()
        {
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
 
public class EventsItemsEventArgs : EventArgs { }
public class EventsItemsDerived : EventsItemsEventArgs { }
 
public class EventsItems : EventArgs { }
 
public delegate void EventCallback(object sender, EventArgs e);
 
public class EventHandlerTest
{
    public event EventCallback EventOne;
}
 
[Serializable]
public class DiskError : Exception
{
    public DiskError() { }
 
    public DiskError(string message) : base(message) { }
    public DiskError(string message, Exception innerException) : base(message, innerException) { }
    protected DiskError(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
 
 
[AttributeUsage(AttributeTargets.Class)]
public sealed class Verifiable : Attribute
{
}
 
public class ConditionClass : IMembershipCondition
{
    public bool Check(Evidence evidence) { return false; }
    public IMembershipCondition Copy() { return (IMembershipCondition)null; }
    public void FromXml(SecurityElement e, PolicyLevel level) { }
    public SecurityElement ToXml(PolicyLevel level) { return (SecurityElement)null; }
    public void FromXml(SecurityElement e) { }
    public SecurityElement ToXml() { return (SecurityElement)null; }
}
 
[Serializable]
public class MyTable<TKey, TValue> : System.Collections.Generic.Dictionary<TKey, TValue>
{
    protected MyTable(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
 
[Serializable]
public class MyStringObjectHashtable : System.Collections.Generic.Dictionary<string, object>
{
    protected MyStringObjectHashtable(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
 
public class MyList<T> : System.Collections.ObjectModel.Collection<T> { }
 
public class StringGrouping<T> : System.Collections.ObjectModel.Collection<T> { }
 
public class LastInFirstOut<T> : System.Collections.Generic.Stack<T> { }
 
public class StackOfIntegers : System.Collections.Generic.Stack<int> { }
 
public class FirstInFirstOut<T> : System.Collections.Generic.Queue<T> { }
 
public class QueueOfNumbers : System.Collections.Generic.Queue<int> { }
 
public class MyDataStructure : Stack { }
 
public class AnotherDataStructure : Queue { }
 
public class WronglyNamedPermissionClass : CodeAccessPermission
{
    public override IPermission Copy() { return (IPermission)null; }
    public override void FromXml(SecurityElement e) { }
    public override IPermission Intersect(IPermission target) { return (IPermission)null; }
    public override bool IsSubsetOf(IPermission target) { return false; }
    public override SecurityElement ToXml() { return (SecurityElement)null; }
}
 
public class WronglyNamedIPermissionClass : IPermission
{
    public IPermission Copy() { return (IPermission)null; }
    public void FromXml(SecurityElement e) { }
    public IPermission Intersect(IPermission target) { return (IPermission)null; }
    public bool IsSubsetOf(IPermission target) { return false; }
    public SecurityElement ToXml() { return (SecurityElement)null; }
    public IPermission Union(IPermission target) { return (IPermission)null; }
    public void Demand() { }
}
 
public class WronglyNamedType : Stream
{
    public override bool CanRead { get { return false; } }
    public override bool CanSeek { get { return false; } }
    public override bool CanWrite { get { return false; } }
    public override long Length { get { return 0; } }
    public override long Position { get { return 0; } set { } }
    public override void Close() { base.Close(); }
    public override void Flush() { }
    public override int Read(byte[] buffer, int offset, int count) { return 0; }
    public override long Seek(long offset, SeekOrigin origin) { return 0; }
    public override void SetLength(long value) { }
    public override void Write(byte[] buffer, int offset, int count) { }
}
 
public class MyCollectionIsEnumerable : IEnumerable
{
    public void CopyTo(Array destination, int index)
    {
        System.Console.WriteLine(this);
        System.Console.WriteLine(destination);
        System.Console.WriteLine(index);
    }
    public int Count
    {
        get
        {
            Console.WriteLine(this);
            return 0;
        }
        set
        {
            System.Console.WriteLine(this);
            System.Console.WriteLine(value);
        }
    }
    public bool IsSynchronized
    {
        get
        {
            Console.WriteLine(this);
            return true;
        }
        set
        {
            System.Console.WriteLine(this);
            System.Console.WriteLine(value);
        }
    }
    public object SyncRoot
    {
        get
        {
            return this;
        }
        set
        {
            System.Console.WriteLine(this);
            System.Console.WriteLine(value);
        }
    }
    public IEnumerator GetEnumerator() { return null; }
}
 
public class CollectionDoesNotEndInCollectionClass : StringCollection { }
 
[Serializable]
public class DictionaryDoesNotEndInDictionaryClass : Hashtable
{
    protected DictionaryDoesNotEndInDictionaryClass(SerializationInfo info, StreamingContext context)
        : base(info, context) { }
}
 
public class MyTest<T> : List<T>
{
}
 
[Serializable]
public class DataSetWithWrongSuffix : DataSet
{
    protected DataSetWithWrongSuffix(SerializationInfo info, StreamingContext context)
        : base(info, context) { }
}
 
[Serializable]
public class DataTableWithWrongSuffix : DataTable
{
    protected DataTableWithWrongSuffix(SerializationInfo info, StreamingContext context)
        : base(info, context) { }
}",
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.CA1710.exclude_indirect_base_types = false") },
                    ExpectedDiagnostics =
                    {
                        GetCA1710CSharpResultAt(line: 16, column: 14, typeName: "EventsItemsDerived", suffix: "EventArgs"),
                        GetCA1710CSharpResultAt(line: 18, column: 14, typeName: "EventsItems", suffix: "EventArgs"),
                        GetCA1710CSharpResultAt(line: 24, column: 32, typeName: "EventCallback", suffix: "EventHandler"),
                        GetCA1710CSharpResultAt(line: 28, column: 14, typeName: "DiskError", suffix: "Exception"),
                        GetCA1710CSharpResultAt(line: 39, column: 21, typeName: "Verifiable", suffix: "Attribute"),
                        GetCA1710CSharpResultAt(line: 43, column: 14, typeName: "ConditionClass", suffix: "Condition"),
                        GetCA1710CSharpResultAt(line: 54, column: 14, typeName: "MyTable<TKey, TValue>", suffix: "Dictionary", additionalSuffixes: "Collection"),
                        GetCA1710CSharpResultAt(line: 60, column: 14, typeName: "MyStringObjectHashtable", suffix: "Dictionary", additionalSuffixes: "Collection"),
                        GetCA1710CSharpResultAt(line: 65, column: 14, typeName: "MyList<T>", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710CSharpResultAt(line: 67, column: 14, typeName: "StringGrouping<T>", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710CSharpResultAt(line: 69, column: 14, typeName: "LastInFirstOut<T>", suffix: "Stack", additionalSuffixes: "Collection"),
                        GetCA1710CSharpResultAt(line: 71, column: 14, typeName: "StackOfIntegers", suffix: "Stack", additionalSuffixes: "Collection"),
                        GetCA1710CSharpResultAt(line: 73, column: 14, typeName: "FirstInFirstOut<T>", suffix: "Queue", additionalSuffixes: "Collection"),
                        GetCA1710CSharpResultAt(line: 75, column: 14, typeName: "QueueOfNumbers", suffix: "Queue", additionalSuffixes: "Collection"),
                        GetCA1710CSharpResultAt(line: 77, column: 14, typeName: "MyDataStructure", suffix: "Stack", additionalSuffixes: "Collection"),
                        GetCA1710CSharpResultAt(line: 79, column: 14, typeName: "AnotherDataStructure", suffix: "Queue", additionalSuffixes: "Collection"),
                        GetCA1710CSharpResultAt(line: 81, column: 14, typeName: "WronglyNamedPermissionClass", suffix: "Permission"),
                        GetCA1710CSharpResultAt(line: 90, column: 14, typeName: "WronglyNamedIPermissionClass", suffix: "Permission"),
                        GetCA1710CSharpResultAt(line: 101, column: 14, typeName: "WronglyNamedType", suffix: "Stream"),
                        GetCA1710CSharpResultAt(line: 116, column: 14, typeName: "MyCollectionIsEnumerable", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710CSharpResultAt(line: 165, column: 14, typeName: "CollectionDoesNotEndInCollectionClass", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710CSharpResultAt(line: 168, column: 14, typeName: "DictionaryDoesNotEndInDictionaryClass", suffix: "Dictionary", additionalSuffixes: "Collection"),
                        GetCA1710CSharpResultAt(line: 174, column: 14, typeName: "MyTest<T>", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710CSharpResultAt(line: 179, column: 14, typeName: "DataSetWithWrongSuffix", suffix: "DataSet"),
                        GetCA1710CSharpResultAt(line: 186, column: 14, typeName: "DataTableWithWrongSuffix", suffix: "DataTable", additionalSuffixes: "Collection"),
                    }
                }
            }.RunAsync();
        }
 
        [Fact]
        public async Task CA1710_NoDiagnostics_CSharpAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync(@"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
 
[Serializable]
public class MyDictionary<TKey, TValue> : System.Collections.Generic.Dictionary<TKey, TValue>
{
    protected MyDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
 
[Serializable]
public class MyStringObjectDictionary : System.Collections.Generic.Dictionary<string, object>
{
    protected MyStringObjectDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
 
public class MyCollection<T> : System.Collections.ObjectModel.Collection<T> { }
 
public class MyStringCollection : System.Collections.ObjectModel.Collection<string> { }
 
public class MyStack<T> : System.Collections.Generic.Stack<T> { }
 
public class MyIntegerStack : System.Collections.Generic.Stack<int> { }
 
public class StackCollection<T> : System.Collections.Generic.Stack<T> { }
 
public class IntegerStackCollection : System.Collections.Generic.Stack<int> { }
 
public class MyQueue<T> : System.Collections.Generic.Queue<T> { }
 
public class MyIntegerQueue : System.Collections.Generic.Queue<int> { }
 
public class QueueCollection<T> : System.Collections.Generic.Queue<T> { }
 
public class IntegerQueueCollection : System.Collections.Generic.Queue<int> { }
 
public delegate void SimpleEventHandler(object sender, EventArgs e);
 
public class EventHandlerTest
{
    public event SimpleEventHandler EventOne;
 
    public event EventHandler<EventArgs> EventTwo;
}
 
[Serializable]
public class DiskErrorException : Exception
{
    public DiskErrorException() { }
    public DiskErrorException(string message) : base(message) { }
    public DiskErrorException(string message, Exception innerException) : base(message, innerException) { }
    protected DiskErrorException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
 
 
[AttributeUsage(AttributeTargets.Class)]
public sealed class VerifiableAttribute : Attribute
{
}
 
public class MyCondition : IMembershipCondition
{
    public bool Check(Evidence evidence) { return false; }
    public IMembershipCondition Copy() { return (IMembershipCondition)null; }
    public void FromXml(SecurityElement e, PolicyLevel level) { }
    public SecurityElement ToXml(PolicyLevel level) { return (SecurityElement)null; }
    public void FromXml(SecurityElement e) { }
    public SecurityElement ToXml() { return (SecurityElement)null; }
}
 
public class CorrectlyNamedPermission : CodeAccessPermission
{
    public override IPermission Copy() { return (IPermission)null; }
    public override void FromXml(SecurityElement e) { }
    public override IPermission Intersect(IPermission target) { return (IPermission)null; }
    public override bool IsSubsetOf(IPermission target) { return false; }
    public override SecurityElement ToXml() { return (SecurityElement)null; }
}
 
public class CorrectlyNamedIPermission : IPermission
{
    public IPermission Copy() { return (IPermission)null; }
    public void FromXml(SecurityElement e) { }
    public IPermission Intersect(IPermission target) { return (IPermission)null; }
    public bool IsSubsetOf(IPermission target) { return false; }
    public SecurityElement ToXml() { return (SecurityElement)null; }
    public IPermission Union(IPermission target) { return (IPermission)null; }
    public void Demand() { }
}
 
 
public class CorrectlyNamedTypeStream : Stream
{
    public override bool CanRead { get { return false; } }
    public override bool CanSeek { get { return false; } }
    public override bool CanWrite { get { return false; } }
    public override long Length { get { return 0; } }
    public override long Position { get { return 0; } set { } }
    public override void Close() { base.Close(); }
    public override void Flush() { }
    public override int Read(byte[] buffer, int offset, int count) { return 0; }
    public override long Seek(long offset, SeekOrigin origin) { return 0; }
    public override void SetLength(long value) { }
    public override void Write(byte[] buffer, int offset, int count) { }
}
 
 
public class CollectionEndsInCollection : StringCollection { }
 
[Serializable]
public class DictionaryEndsInDictionary : Hashtable
{
    public DictionaryEndsInDictionary() { }
    protected DictionaryEndsInDictionary(SerializationInfo info, StreamingContext context)
        : base(info, context) { }
}
 
[Serializable]
public class MySpecialQueue : Queue { }
 
public class QueueCollection : Queue { }
 
[Serializable]
public class MyStack : Stack { }
 
public class StackCollection : Stack { }
 
[Serializable]
public class MyDataSet : DataSet
{
    public MyDataSet() { }
 
    protected MyDataSet(SerializationInfo info, StreamingContext context) : base(info, context) { }
 
    public void DoWork() { Console.WriteLine(this); }
}
 
[Serializable]
public class MyDataTable : DataTable
{
    public MyDataTable() { }
 
    protected MyDataTable(SerializationInfo info, StreamingContext context)
        : base(info, context) { }
 
    public void DoWork() { Console.WriteLine(this); }
}
 
[Serializable]
public class MyCollectionDataTable : DataTable, IEnumerable
{
    public MyCollectionDataTable() { }
 
    protected MyCollectionDataTable(SerializationInfo info, StreamingContext context)
        : base(info, context) { }
 
    public void DoWork() { Console.WriteLine(this); }
 
    public IEnumerator GetEnumerator()
    {
        return null;
    }
}");
        }
 
        [Fact]
        public async Task CA1710_AllScenarioDiagnostics_VisualBasicAsync()
        {
            await new VerifyVB.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.Data
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Security
Imports System.Security.Policy
 
Public Class AnotherDataStructure
    Inherits Queue
 
End Class
Public Class CollectionDoesNotEndInCollectionClass
    Inherits StringCollection
 
End Class
 
Public Class ConditionClass
    Implements IMembershipCondition, ISecurityEncodable, ISecurityPolicyEncodable
 
    ' Methods
    Public Function Check(ByVal evidence As Evidence) As Boolean Implements IMembershipCondition.Check
        Return False
    End Function
 
    Public Function Copy() As IMembershipCondition Implements IMembershipCondition.Copy
        Return Nothing
    End Function
 
    Public Sub FromXml(ByVal e As SecurityElement) Implements ISecurityEncodable.FromXml
 
    End Sub
 
    Public Sub FromXml(ByVal e As SecurityElement, ByVal level As PolicyLevel) Implements ISecurityPolicyEncodable.FromXml
 
    End Sub
 
    Public Function ToXml() As SecurityElement Implements ISecurityEncodable.ToXml
        Return Nothing
    End Function
 
    Public Function ToXml(ByVal level As PolicyLevel) As SecurityElement Implements ISecurityPolicyEncodable.ToXml
        Return Nothing
    End Function
 
    Public Overrides Function ToString() As String Implements IMembershipCondition.ToString
        Return MyBase.ToString()
    End Function
 
    Public Overrides Function Equals(ByVal obj As Object) As Boolean Implements IMembershipCondition.Equals
        Return MyBase.Equals(obj)
    End Function
 
    Public Overrides Function GetHashCode() As Integer
        Return MyBase.GetHashCode()
    End Function
End Class
 
<Serializable()>
Public Class DataSetWithWrongSuffix
    Inherits DataSet
 
    ' Methods
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
End Class
 
<Serializable()>
Public Class DataTableWithWrongSuffix
    Inherits DataTable
 
    ' Methods
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
End Class
 
<Serializable()>
Public Class DictionaryDoesNotEndInDictionaryClass
    Inherits Hashtable
 
    ' Methods
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
End Class
 
<Serializable()>
Public Class DiskError
    Inherits Exception
 
    ' Methods
    Public Sub New()
    End Sub
 
    Public Sub New(ByVal message As String)
        MyBase.New(message)
    End Sub
 
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
    Public Sub New(ByVal message As String, ByVal innerException As Exception)
        MyBase.New(message, innerException)
    End Sub
 
End Class
 
Public Delegate Sub EventCallback(ByVal sender As Object, ByVal e As EventArgs)
 
Public Class EventHandlerTest
    ' Events
    Public Event EventOne As EventCallback
End Class
 
Public Class EventsItems
    Inherits EventArgs
 
End Class
 
Public Class FirstInFirstOut(Of T)
    Inherits Queue(Of T)
 
End Class
 
Public Class LastInFirstOut(Of T)
    Inherits Stack(Of T)
 
End Class
 
Public Class MyCollectionIsEnumerable
    Implements IEnumerable
 
    Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
        Return Nothing
    End Function
End Class
 
Public Class MyDataStructure
    Inherits Stack
 
End Class
 
Public Class MyList(Of T)
    Inherits Collection(Of T)
 
End Class
 
<Serializable()>
Public Class MyStringObjectHashtable
    Inherits Dictionary(Of String, Object)
 
    ' Methods
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
End Class
 
<Serializable()>
Public Class MyTable(Of TKey, TValue)
    Inherits Dictionary(Of TKey, TValue)
 
    ' Methods
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
End Class
 
Public Class MyTest(Of T)
    Inherits List(Of T)
 
End Class
 
Public Class QueueOfNumbers
    Inherits Queue(Of Integer)
 
End Class
 
Public Class StackOfIntegers
    Inherits Stack(Of Integer)
 
End Class
 
Public Class StringGrouping(Of T)
    Inherits Collection(Of T)
 
End Class
 
<AttributeUsage(AttributeTargets.Class)>
Public NotInheritable Class Verifiable
    Inherits Attribute
 
End Class
 
Public Class WronglyNamedIPermissionClass
    Implements IPermission, ISecurityEncodable
 
    ' Methods
    Public Function Copy() As IPermission Implements IPermission.Copy
        Return Nothing
    End Function
 
    Public Sub Demand() Implements IPermission.Demand
    End Sub
 
    Public Sub FromXml(ByVal e As SecurityElement) Implements ISecurityEncodable.FromXml
    End Sub
 
    Public Function Intersect(ByVal target As IPermission) As IPermission Implements IPermission.Intersect
        Return Nothing
    End Function
 
    Public Function IsSubsetOf(ByVal target As IPermission) As Boolean Implements IPermission.IsSubsetOf
        Return False
    End Function
 
    Public Function ToXml() As SecurityElement Implements ISecurityEncodable.ToXml
        Return Nothing
    End Function
 
    Public Function Union(ByVal target As IPermission) As IPermission Implements IPermission.Union
        Return Nothing
    End Function
 
End Class
 
Public Class WronglyNamedPermissionClass
    Inherits CodeAccessPermission
 
    ' Methods
    Public Overrides Function Copy() As IPermission
        Return Nothing
    End Function
 
    Public Overrides Sub FromXml(ByVal e As SecurityElement)
    End Sub
 
    Public Overrides Function Intersect(ByVal target As IPermission) As IPermission
        Return Nothing
    End Function
 
    Public Overrides Function IsSubsetOf(ByVal target As IPermission) As Boolean
        Return False
    End Function
 
    Public Overrides Function ToXml() As SecurityElement
        Return Nothing
    End Function
 
End Class
 
Public Class WronglyNamedType
    Inherits Stream
 
    ' Methods
    Public Overrides Sub Close()
        MyBase.Close()
    End Sub
 
    Public Overrides Sub Flush()
    End Sub
 
    Public Overrides Function Read(ByVal buffer As Byte(), ByVal offset As Integer, ByVal count As Integer) As Integer
        Return 0
    End Function
 
    Public Overrides Function Seek(ByVal offset As Long, ByVal origin As SeekOrigin) As Long
        Return CType(0, Long)
    End Function
 
    Public Overrides Sub SetLength(ByVal value As Long)
    End Sub
 
    Public Overrides Sub Write(ByVal buffer As Byte(), ByVal offset As Integer, ByVal count As Integer)
    End Sub
 
 
    ' Properties
    Public Overrides ReadOnly Property CanRead() As Boolean
        Get
            Return False
        End Get
    End Property
 
    Public Overrides ReadOnly Property CanSeek() As Boolean
        Get
            Return False
        End Get
    End Property
 
    Public Overrides ReadOnly Property CanWrite() As Boolean
        Get
            Return False
        End Get
    End Property
 
    Public Overrides ReadOnly Property Length() As Long
        Get
            Return CType(0, Long)
        End Get
    End Property
 
    Public Overrides Property Position() As Long
        Get
            Return CType(0, Long)
        End Get
        Set(ByVal value As Long)
        End Set
    End Property
 
End Class",
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.CA1710.exclude_indirect_base_types = false") },
                    ExpectedDiagnostics =
                    {
                        GetCA1710BasicResultAt(line: 13, column: 14, typeName: "AnotherDataStructure", suffix: "Queue", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 17, column: 14, typeName: "CollectionDoesNotEndInCollectionClass", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710BasicResultAt(line: 22, column: 14, typeName: "ConditionClass", suffix: "Condition"),
                        GetCA1710BasicResultAt(line: 64, column: 14, typeName: "DataSetWithWrongSuffix", suffix: "DataSet"),
                        GetCA1710BasicResultAt(line: 75, column: 14, typeName: "DataTableWithWrongSuffix", suffix: "DataTable", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 86, column: 14, typeName: "DictionaryDoesNotEndInDictionaryClass", suffix: "Dictionary", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 97, column: 14, typeName: "DiskError", suffix: "Exception"),
                        GetCA1710BasicResultAt(line: 122, column: 18, typeName: "EventCallback", suffix: "EventHandler"),
                        GetCA1710BasicResultAt(line: 125, column: 14, typeName: "EventsItems", suffix: "EventArgs"),
                        GetCA1710BasicResultAt(line: 130, column: 14, typeName: "FirstInFirstOut(Of T)", suffix: "Queue", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 135, column: 14, typeName: "LastInFirstOut(Of T)", suffix: "Stack", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 140, column: 14, typeName: "MyCollectionIsEnumerable", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710BasicResultAt(line: 148, column: 14, typeName: "MyDataStructure", suffix: "Stack", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 153, column: 14, typeName: "MyList(Of T)", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710BasicResultAt(line: 159, column: 14, typeName: "MyStringObjectHashtable", suffix: "Dictionary", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 170, column: 14, typeName: "MyTable(Of TKey, TValue)", suffix: "Dictionary", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 180, column: 14, typeName: "MyTest(Of T)", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710BasicResultAt(line: 185, column: 14, typeName: "QueueOfNumbers", suffix: "Queue", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 190, column: 14, typeName: "StackOfIntegers", suffix: "Stack", additionalSuffixes: "Collection"),
                        GetCA1710BasicResultAt(line: 195, column: 14, typeName: "StringGrouping(Of T)", suffix: "Collection", additionalSuffixes: "Dictionary', 'Set', 'Stack', 'Queue"),
                        GetCA1710BasicResultAt(line: 201, column: 29, typeName: "Verifiable", suffix: "Attribute"),
                        GetCA1710BasicResultAt(line: 206, column: 14, typeName: "WronglyNamedIPermissionClass", suffix: "Permission"),
                        GetCA1710BasicResultAt(line: 238, column: 14, typeName: "WronglyNamedPermissionClass", suffix: "Permission"),
                        GetCA1710BasicResultAt(line: 263, column: 14, typeName: "WronglyNamedType", suffix: "Stream"),
                    }
                }
            }.RunAsync();
        }
 
        [Fact]
        public async Task CA1710_NoDiagnostics_VisualBasicAsync()
        {
            await VerifyVB.VerifyAnalyzerAsync(@"
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.Data
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Security
Imports System.Security.Policy
 
Public Class CollectionEndsInCollection
    Inherits StringCollection
 
End Class
 
Public Class CorrectlyNamedIPermission
    Implements IPermission, ISecurityEncodable
 
 
    Public Function Copy() As System.Security.IPermission Implements System.Security.IPermission.Copy
        Return Me
 
    End Function
 
    Public Sub Demand() Implements System.Security.IPermission.Demand
 
    End Sub
 
    Public Function Intersect(ByVal target As System.Security.IPermission) As System.Security.IPermission Implements System.Security.IPermission.Intersect
        Return Nothing
 
    End Function
 
    Public Function IsSubsetOf(ByVal target As System.Security.IPermission) As Boolean Implements System.Security.IPermission.IsSubsetOf
        Return False
    End Function
 
    Public Function Union(ByVal target As System.Security.IPermission) As System.Security.IPermission Implements System.Security.IPermission.Union
        Return Me
 
    End Function
 
    Public Sub FromXml(ByVal e As System.Security.SecurityElement) Implements System.Security.ISecurityEncodable.FromXml
 
    End Sub
 
    Public Function ToXml() As System.Security.SecurityElement Implements System.Security.ISecurityEncodable.ToXml
 
    End Function
End Class
 
Public Class CorrectlyNamedPermission
    Inherits CodeAccessPermission
 
    Public Overrides Function Copy() As System.Security.IPermission
 
    End Function
 
    Public Overrides Sub FromXml(ByVal elem As System.Security.SecurityElement)
 
    End Sub
 
    Public Overrides Function Intersect(ByVal target As System.Security.IPermission) As System.Security.IPermission
 
    End Function
 
    Public Overrides Function IsSubsetOf(ByVal target As System.Security.IPermission) As Boolean
 
    End Function
 
    Public Overrides Function ToXml() As System.Security.SecurityElement
 
    End Function
End Class
 
Public Class CorrectlyNamedTypeStream
    Inherits FileStream
 
    Public Sub New()
        MyBase.New("""", FileMode.Open)
    End Sub
End Class
 
<Serializable()>
Public Class DictionaryEndsInDictionary
    Inherits Hashtable
 
    ' Methods
    Public Sub New()
    End Sub
 
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
End Class
 
<Serializable()>
Public Class DiskErrorException
    Inherits Exception
 
    ' Methods
    Public Sub New()
    End Sub
 
    Public Sub New(ByVal message As String)
        MyBase.New(message)
    End Sub
 
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
    Public Sub New(ByVal message As String, ByVal innerException As Exception)
        MyBase.New(message, innerException)
    End Sub
 
End Class
 
Public Class EventHandlerTest
    ' Events
    Public Event EventOne As SimpleEventHandler
End Class
 
Public Class EventsItemsEventArgs
    Inherits EventArgs
 
End Class
 
Public Class IntegerQueueCollection
    Inherits Queue(Of Integer)
 
End Class
 
Public Class IntegerStackCollection
    Inherits Stack(Of Integer)
 
End Class
 
Public Class MyCollection(Of T)
    Inherits Collection(Of T)
 
End Class
 
Public Class MyCondition
    Implements IMembershipCondition, ISecurityEncodable, ISecurityPolicyEncodable
 
    Public Sub FromXml(ByVal e As System.Security.SecurityElement) Implements System.Security.ISecurityEncodable.FromXml
 
    End Sub
 
    Public Function ToXml() As System.Security.SecurityElement Implements System.Security.ISecurityEncodable.ToXml
 
    End Function
 
    Public Sub FromXml1(ByVal e As System.Security.SecurityElement, ByVal level As System.Security.Policy.PolicyLevel) Implements System.Security.ISecurityPolicyEncodable.FromXml
 
    End Sub
 
    Public Function ToXml1(ByVal level As System.Security.Policy.PolicyLevel) As System.Security.SecurityElement Implements System.Security.ISecurityPolicyEncodable.ToXml
 
    End Function
 
    Public Function Check(ByVal evidence As System.Security.Policy.Evidence) As Boolean Implements System.Security.Policy.IMembershipCondition.Check
 
    End Function
 
    Public Function Copy() As System.Security.Policy.IMembershipCondition Implements System.Security.Policy.IMembershipCondition.Copy
 
    End Function
 
    Public Function Equals1(ByVal obj As Object) As Boolean Implements System.Security.Policy.IMembershipCondition.Equals
 
    End Function
 
    Public Function ToString1() As String Implements System.Security.Policy.IMembershipCondition.ToString
 
    End Function
End Class
 
<Serializable()>
Public Class MyDataSet
    Inherits DataSet
 
    ' Methods
    Public Sub New()
    End Sub
 
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
    Public Sub DoWork()
        Console.WriteLine(Me)
    End Sub
 
End Class
 
<Serializable()>
Public Class MyDataTable
    Inherits DataTable
 
    ' Methods
    Public Sub New()
    End Sub
 
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
    Public Sub DoWork()
        Console.WriteLine(Me)
    End Sub
 
End Class
 
<Serializable()>
Public Class MyDictionary(Of TKey, TValue)
    Inherits Dictionary(Of TKey, TValue)
 
    ' Methods
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
End Class
 
Public Class MyIntegerQueue
    Inherits Queue(Of Integer)
 
End Class
 
Public Class MyIntegerStack
    Inherits Stack(Of Integer)
 
End Class
 
Public Class MyQueue(Of T)
    Inherits Queue(Of T)
 
End Class
 
<Serializable()>
Public Class MySpecialQueue
    Inherits Queue
 
End Class
 
Public Class MyStack(Of T)
    Inherits Stack(Of T)
 
End Class
 
<Serializable()>
Public Class MyStack
    Inherits Stack
 
End Class
 
Public Class MyStringCollection
    Inherits Collection(Of String)
 
End Class
 
<Serializable()>
Public Class MyStringObjectDictionary
    Inherits Dictionary(Of String, Object)
 
    ' Methods
    Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub
 
End Class
 
Public Class QueueCollection(Of T)
    Inherits Queue(Of T)
 
End Class
 
Public Class QueueCollection
    Inherits Queue
 
End Class
 
Public Delegate Sub SimpleEventHandler(ByVal sender As Object, ByVal e As EventArgs)
 
Public Class StackCollection(Of T)
    Inherits Stack(Of T)
 
End Class
 
Public Class StackCollection
    Inherits Stack
 
End Class
 
<AttributeUsage(AttributeTargets.Class)>
Public NotInheritable Class VerifiableAttribute
    Inherits Attribute
 
End Class");
        }
 
        [Fact, WorkItem(1822, "https://github.com/dotnet/roslyn-analyzers/issues/1822")]
        public async Task CA1710_SystemAction_CSharpAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync(@"
using System;
 
public class C
{
    public event Action MyEvent;
}");
        }
 
        [Fact, WorkItem(1822, "https://github.com/dotnet/roslyn-analyzers/issues/1822")]
        public async Task CA1710_CustomDelegate_CSharpAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync(@"
using System;
 
public class C
{
    public delegate void MyDelegate(int param);
    public event MyDelegate MyEvent;
}");
        }
 
        [Fact, WorkItem(2955, "https://github.com/dotnet/roslyn-analyzers/issues/2955")]
        public async Task CA1710_IReadOnlyDictionaryAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync(@"
using System;
using System.Collections;
using System.Collections.Generic;
 
public class C : IReadOnlyDictionary<int, string>
{
    public string this[int key] => throw new System.NotImplementedException();
 
    public IEnumerable<int> Keys => throw new System.NotImplementedException();
 
    public IEnumerable<string> Values => throw new System.NotImplementedException();
 
    public int Count => throw new System.NotImplementedException();
 
    public bool ContainsKey(int key) => throw new System.NotImplementedException();
    public IEnumerator<KeyValuePair<int, string>> GetEnumerator() => throw new System.NotImplementedException();
    public bool TryGetValue(int key, out string value) => throw new System.NotImplementedException();
    IEnumerator IEnumerable.GetEnumerator() => throw new System.NotImplementedException();
}",
                GetCA1710CSharpResultAt(6, 14, "C", "Dictionary", "Collection"));
        }
 
        [Fact, WorkItem(2955, "https://github.com/dotnet/roslyn-analyzers/issues/2955")]
        public async Task CA1710_IReadOnlyCollection_IncludeIndirectBaseTypes()
        {
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
using System;
using System.Collections;
using System.Collections.Generic;
 
public class C : IReadOnlyCollection<int>
{
    public int Count => throw new System.NotImplementedException();
 
    public IEnumerator<int> GetEnumerator() => throw new System.NotImplementedException();
    IEnumerator IEnumerable.GetEnumerator() => throw new System.NotImplementedException();
}",
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.CA1710.exclude_indirect_base_types = false") },
                    ExpectedDiagnostics =
                    {
                        GetCA1710CSharpResultAt(6, 14, "C", "Collection", "Dictionary', 'Set', 'Stack', 'Queue"),
                    },
                }
            }.RunAsync();
        }
 
        [Theory, WorkItem(3065, "https://github.com/dotnet/roslyn-analyzers/issues/3065")]
        [InlineData("")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = MyNamespace.SomeClass->FirstSuffix")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:MyNamespace.SomeClass->FirstSuffix")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = SomeOtherClass->ABC")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:SomeOtherClass->ABC")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = MyNamespace.SomeClass->FirstSuffix|MyNamespace.IMyInterface->Interface")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:MyNamespace.SomeClass->FirstSuffix|T:MyNamespace.IMyInterface->Interface")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = invalid")]
        // In case of duplicated entries, only the first is kept
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = MyNamespace.SomeClass->FirstSuffix|MyNamespace.SomeClass->SecondSuffix")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:MyNamespace.SomeClass->FirstSuffix|T:MyNamespace.SomeClass->SecondSuffix")]
        public async Task CA1710_AdditionalSuffixesAsync(string editorConfigText)
        {
            editorConfigText = $@"dotnet_code_quality.CA1710.exclude_indirect_base_types = false
{editorConfigText}";
 
            var csharpTest = new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
using System;
 
namespace MyNamespace
{
    public interface IMyInterface {}
    public class SomeClass {}
 
    public class SomeSubClass : SomeClass {}
    public class SomeSubSubClass : SomeSubClass {}
 
    public class C : ICloneable, IMyInterface
    {
        public object Clone() => null;
    }
}
 
public class SomeOtherClass
{
}
 
public class SomeOtherSubClass : SomeOtherClass {}"},
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                }
            };
 
            if (editorConfigText.EndsWith("Suffix", StringComparison.Ordinal))
            {
                csharpTest.ExpectedDiagnostics.AddRange(new[]
                {
                    GetCA1710CSharpResultAt(9, 18, "MyNamespace.SomeSubClass", "FirstSuffix"),
                    GetCA1710CSharpResultAt(10, 18, "MyNamespace.SomeSubSubClass", "FirstSuffix"),
                });
            }
            else if (editorConfigText.EndsWith("ABC", StringComparison.Ordinal))
            {
                csharpTest.ExpectedDiagnostics.Add(GetCA1710CSharpResultAt(22, 14, "SomeOtherSubClass", "ABC"));
            }
            else if (editorConfigText.EndsWith("Interface", StringComparison.Ordinal))
            {
                csharpTest.ExpectedDiagnostics.AddRange(new[]
                {
                    GetCA1710CSharpResultAt(9, 18, "MyNamespace.SomeSubClass", "FirstSuffix"),
                    GetCA1710CSharpResultAt(10, 18, "MyNamespace.SomeSubSubClass", "FirstSuffix"),
                    GetCA1710CSharpResultAt(12, 18, "MyNamespace.C", "Interface"),
                });
            }
 
            await csharpTest.RunAsync();
 
            var vbTest = new VerifyVB.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
Imports System
 
Namespace MyNamespace
    Interface IMyInterface
    End Interface
 
    Public Class SomeClass
    End Class
 
    Public Class SomeSubClass
        Inherits SomeClass
    End Class
 
    Public Class SomeSubSubClass
        Inherits SomeSubClass
    End Class
 
    Public Class C
        Implements ICloneable, IMyInterface
 
        Public Function Clone() As Object Implements ICloneable.Clone
            Return Nothing
        End Function
    End Class
End Namespace
 
Public Class SomeOtherClass
End Class
 
Public Class SomeOtherSubClass
    Inherits SomeOtherClass
End Class"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                }
            };
 
            if (editorConfigText.EndsWith("Suffix", StringComparison.Ordinal))
            {
                vbTest.ExpectedDiagnostics.AddRange(new[]
                {
                    GetCA1710BasicResultAt(11, 18, "MyNamespace.SomeSubClass", "FirstSuffix"),
                    GetCA1710BasicResultAt(15, 18, "MyNamespace.SomeSubSubClass", "FirstSuffix"),
                });
            }
            else if (editorConfigText.EndsWith("ABC", StringComparison.Ordinal))
            {
                vbTest.ExpectedDiagnostics.Add(GetCA1710CSharpResultAt(31, 14, "SomeOtherSubClass", "ABC"));
            }
            else if (editorConfigText.EndsWith("Interface", StringComparison.Ordinal))
            {
                vbTest.ExpectedDiagnostics.AddRange(new[]
                {
                    GetCA1710BasicResultAt(11, 18, "MyNamespace.SomeSubClass", "FirstSuffix"),
                    GetCA1710BasicResultAt(15, 18, "MyNamespace.SomeSubSubClass", "FirstSuffix"),
                    GetCA1710BasicResultAt(19, 18, "MyNamespace.C", "Interface"),
                });
            }
 
            await vbTest.RunAsync();
        }
 
        [Theory, WorkItem(3065, "https://github.com/dotnet/roslyn-analyzers/issues/3065")]
        // methods are not handled
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = M:MyNamespace.SomeClass.MyMethod()->Suffix")]
        // namespaces are not handled
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = N:MyNamespace:Suffix")]
        // more than one -> is not handled
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:MyNamespace.SomeClass->Suffix1->Suffix2")]
        // no suffix
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:MyNamespace.SomeClass")]
        public async Task CA1710_InvalidSyntaxNoSuffixAsync(string editorConfigText)
        {
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
namespace MyNamespace
{
    public class SomeClass
    {
        public void MyMethod() {}
    }
}"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                }
            }.RunAsync();
 
            await new VerifyVB.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
Namespace MyNamespace
    Public Class SomeClass
        Public Sub MyMethod()
        End Sub
    End Class
End Namespace"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                }
            }.RunAsync();
        }
 
        [Fact, WorkItem(3065, "https://github.com/dotnet/roslyn-analyzers/issues/3065")]
        public async Task CA1710_UserMappingWinsOverHardcodedAsync()
        {
            var editorConfigText = @"dotnet_code_quality.CA1710.exclude_indirect_base_types = false
dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Collections.Generic.IDictionary`2->MySuffix";
 
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
using System.Collections.Generic;
 
public class SomeClass : Dictionary<string, string>
{
}
"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                    ExpectedDiagnostics =
                    {
                        GetCA1710CSharpResultAt(4, 14, "SomeClass", "MySuffix"),
                    }
                }
            }.RunAsync();
 
            await new VerifyVB.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
Imports System.Collections.Generic
 
Public Class SomeClass
    Inherits Dictionary(Of String, String)
End Class"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                    ExpectedDiagnostics =
                    {
                        GetCA1710BasicResultAt(4, 14, "SomeClass", "MySuffix"),
                    }
                }
            }.RunAsync();
        }
 
        [Fact, WorkItem(1818, "https://github.com/dotnet/roslyn-analyzers/issues/1818")]
        public async Task CA1710_DefaultValueForExclusionAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync(@"
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
 
public class FreezableList : ReadOnlyCollection<int>
{
    public FreezableList(IList<int> list) : base(list)
    {
    }
}");
 
            await VerifyVB.VerifyAnalyzerAsync(@"
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
 
Public Class FreezableList
    Inherits ReadOnlyCollection(Of Integer)
 
    Public Sub New(ByVal list As IList(Of Integer))
        MyBase.New(list)
    End Sub
End Class");
        }
 
        [Theory, WorkItem(1818, "https://github.com/dotnet/roslyn-analyzers/issues/1818")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Data.IDataReader->{}")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Data.IDataReader-> {}")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Data.IDataReader->{} ")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Data.IDataReader-> {} ")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Data.IDataReader->{ }")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Data.IDataReader-> { }")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Data.IDataReader->{ } ")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Data.IDataReader-> { } ")]
        [InlineData("dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Data.IDataReader-> {     } ")]
        public async Task CA1710_AllowEmptySuffixAsync(string editorConfigText)
        {
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
using System;
using System.Data;
 
public class SomeClass : IDataReader
{
    public object this[int i] => throw new NotImplementedException();
 
    public object this[string name] => throw new NotImplementedException();
 
    public int Depth => throw new NotImplementedException();
 
    public bool IsClosed => throw new NotImplementedException();
 
    public int RecordsAffected => throw new NotImplementedException();
 
    public int FieldCount => throw new NotImplementedException();
 
    public void Close() => throw new NotImplementedException();
    public void Dispose() => throw new NotImplementedException();
    public bool GetBoolean(int i) => throw new NotImplementedException();
    public byte GetByte(int i) => throw new NotImplementedException();
    public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) => throw new NotImplementedException();
    public char GetChar(int i) => throw new NotImplementedException();
    public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) => throw new NotImplementedException();
    public IDataReader GetData(int i) => throw new NotImplementedException();
    public string GetDataTypeName(int i) => throw new NotImplementedException();
    public DateTime GetDateTime(int i) => throw new NotImplementedException();
    public decimal GetDecimal(int i) => throw new NotImplementedException();
    public double GetDouble(int i) => throw new NotImplementedException();
    public Type GetFieldType(int i) => throw new NotImplementedException();
    public float GetFloat(int i) => throw new NotImplementedException();
    public Guid GetGuid(int i) => throw new NotImplementedException();
    public short GetInt16(int i) => throw new NotImplementedException();
    public int GetInt32(int i) => throw new NotImplementedException();
    public long GetInt64(int i) => throw new NotImplementedException();
    public string GetName(int i) => throw new NotImplementedException();
    public int GetOrdinal(string name) => throw new NotImplementedException();
    public DataTable GetSchemaTable() => throw new NotImplementedException();
    public string GetString(int i) => throw new NotImplementedException();
    public object GetValue(int i) => throw new NotImplementedException();
    public int GetValues(object[] values) => throw new NotImplementedException();
    public bool IsDBNull(int i) => throw new NotImplementedException();
    public bool NextResult() => throw new NotImplementedException();
    public bool Read() => throw new NotImplementedException();
}
"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                }
            }.RunAsync();
 
            await new VerifyVB.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
Imports System
Imports System.Data
 
Public Class SomeClass
    Implements System.Data.IDataReader
 
    Public ReadOnly Property Depth As Integer Implements IDataReader.Depth
        Get
            Throw New NotImplementedException()
        End Get
    End Property
 
    Public ReadOnly Property IsClosed As Boolean Implements IDataReader.IsClosed
        Get
            Throw New NotImplementedException()
        End Get
    End Property
 
    Public ReadOnly Property RecordsAffected As Integer Implements IDataReader.RecordsAffected
        Get
            Throw New NotImplementedException()
        End Get
    End Property
 
    Public ReadOnly Property FieldCount As Integer Implements IDataRecord.FieldCount
        Get
            Throw New NotImplementedException()
        End Get
    End Property
 
    Default Public ReadOnly Property Item(i As Integer) As Object Implements IDataRecord.Item
        Get
            Throw New NotImplementedException()
        End Get
    End Property
 
    Default Public ReadOnly Property Item(name As String) As Object Implements IDataRecord.Item
        Get
            Throw New NotImplementedException()
        End Get
    End Property
 
    Public Sub Close() Implements IDataReader.Close
        Throw New NotImplementedException()
    End Sub
 
    Public Function GetSchemaTable() As DataTable Implements IDataReader.GetSchemaTable
        Throw New NotImplementedException()
    End Function
 
    Public Function NextResult() As Boolean Implements IDataReader.NextResult
        Throw New NotImplementedException()
    End Function
 
    Public Function Read() As Boolean Implements IDataReader.Read
        Throw New NotImplementedException()
    End Function
 
    Public Function GetBoolean(i As Integer) As Boolean Implements IDataRecord.GetBoolean
        Throw New NotImplementedException()
    End Function
 
    Public Function GetByte(i As Integer) As Byte Implements IDataRecord.GetByte
        Throw New NotImplementedException()
    End Function
 
    Public Function GetBytes(i As Integer, fieldOffset As Long, buffer() As Byte, bufferoffset As Integer, length As Integer) As Long Implements IDataRecord.GetBytes
        Throw New NotImplementedException()
    End Function
 
    Public Function GetChar(i As Integer) As Char Implements IDataRecord.GetChar
        Throw New NotImplementedException()
    End Function
 
    Public Function GetChars(i As Integer, fieldoffset As Long, buffer() As Char, bufferoffset As Integer, length As Integer) As Long Implements IDataRecord.GetChars
        Throw New NotImplementedException()
    End Function
 
    Public Function GetData(i As Integer) As IDataReader Implements IDataRecord.GetData
        Throw New NotImplementedException()
    End Function
 
    Public Function GetDataTypeName(i As Integer) As String Implements IDataRecord.GetDataTypeName
        Throw New NotImplementedException()
    End Function
 
    Public Function GetDateTime(i As Integer) As Date Implements IDataRecord.GetDateTime
        Throw New NotImplementedException()
    End Function
 
    Public Function GetDecimal(i As Integer) As Decimal Implements IDataRecord.GetDecimal
        Throw New NotImplementedException()
    End Function
 
    Public Function GetDouble(i As Integer) As Double Implements IDataRecord.GetDouble
        Throw New NotImplementedException()
    End Function
 
    Public Function GetFieldType(i As Integer) As Type Implements IDataRecord.GetFieldType
        Throw New NotImplementedException()
    End Function
 
    Public Function GetFloat(i As Integer) As Single Implements IDataRecord.GetFloat
        Throw New NotImplementedException()
    End Function
 
    Public Function GetGuid(i As Integer) As Guid Implements IDataRecord.GetGuid
        Throw New NotImplementedException()
    End Function
 
    Public Function GetInt16(i As Integer) As Short Implements IDataRecord.GetInt16
        Throw New NotImplementedException()
    End Function
 
    Public Function GetInt32(i As Integer) As Integer Implements IDataRecord.GetInt32
        Throw New NotImplementedException()
    End Function
 
    Public Function GetInt64(i As Integer) As Long Implements IDataRecord.GetInt64
        Throw New NotImplementedException()
    End Function
 
    Public Function GetName(i As Integer) As String Implements IDataRecord.GetName
        Throw New NotImplementedException()
    End Function
 
    Public Function GetOrdinal(name As String) As Integer Implements IDataRecord.GetOrdinal
        Throw New NotImplementedException()
    End Function
 
    Public Function GetString(i As Integer) As String Implements IDataRecord.GetString
        Throw New NotImplementedException()
    End Function
 
    Public Function GetValue(i As Integer) As Object Implements IDataRecord.GetValue
        Throw New NotImplementedException()
    End Function
 
    Public Function GetValues(values() As Object) As Integer Implements IDataRecord.GetValues
        Throw New NotImplementedException()
    End Function
 
    Public Function IsDBNull(i As Integer) As Boolean Implements IDataRecord.IsDBNull
        Throw New NotImplementedException()
    End Function
 
#Region ""IDisposable Support""
    Private disposedValue As Boolean ' To detect redundant calls
 
    ' IDisposable
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not disposedValue Then
            If disposing Then
                ' TODO: dispose managed state (managed objects).
            End If
 
            ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
            ' TODO: set large fields to null.
        End If
        disposedValue = True
    End Sub
 
    ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
    'Protected Overrides Sub Finalize()
    '    ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub
 
    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
        Dispose(True)
        ' TODO: uncomment the following line if Finalize() is overridden above.
        ' GC.SuppressFinalize(Me)
    End Sub
#End Region
 
End Class"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                }
            }.RunAsync();
        }
 
        [Fact, WorkItem(5035, "https://github.com/dotnet/roslyn-analyzers/issues/5035")]
        public async Task CA1710_AllowEmptySuffix2Async()
        {
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
using System.Collections;
using System.Collections.Generic;
 
public class C : IReadOnlyDictionary<string, object>
{
    public object this[string key] => throw new System.NotImplementedException();
 
    public IEnumerable<string> Keys => throw new System.NotImplementedException();
 
    public IEnumerable<object> Values => throw new System.NotImplementedException();
 
    public int Count => throw new System.NotImplementedException();
 
    public bool ContainsKey(string key)
    {
        throw new System.NotImplementedException();
    }
 
    public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
    {
        throw new System.NotImplementedException();
    }
 
    public bool TryGetValue(string key, out object value)
    {
        throw new System.NotImplementedException();
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new System.NotImplementedException();
    }
}
"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Collections.Generic.IReadOnlyDictionary`2->{}
")  },
                }
            }.RunAsync();
        }
 
        [Fact, WorkItem(5035, "https://github.com/dotnet/roslyn-analyzers/issues/5035")]
        public async Task CA1710_AllowEmptySuffix3Async()
        {
            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
using System.Collections;
using System.Collections.Generic;
 
public class C : IReadOnlyDictionary<string, object>, ICollection<KeyValuePair<string, object>>
{
    public object this[string key] => throw new System.NotImplementedException();
 
    public IEnumerable<string> Keys => throw new System.NotImplementedException();
 
    public IEnumerable<object> Values => throw new System.NotImplementedException();
 
    public int Count => throw new System.NotImplementedException();
 
    public bool IsReadOnly => throw new System.NotImplementedException();
 
    public void Add(KeyValuePair<string, object> item) => throw new System.NotImplementedException();
 
    public void Clear() => throw new System.NotImplementedException();
 
    public bool Contains(KeyValuePair<string, object> item) => throw new System.NotImplementedException();
 
    public bool ContainsKey(string key) => throw new System.NotImplementedException();
 
    public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) => throw new System.NotImplementedException();
 
    public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => throw new System.NotImplementedException();
 
    public bool Remove(KeyValuePair<string, object> item) => throw new System.NotImplementedException();
 
    public bool TryGetValue(string key, out object value) => throw new System.NotImplementedException();
 
    IEnumerator IEnumerable.GetEnumerator() => throw new System.NotImplementedException();
}
"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", @"root = true
 
[*]
dotnet_code_quality.CA1710.additional_required_suffixes = T:System.Collections.Generic.IReadOnlyDictionary`2->{}
")  },
                    ExpectedDiagnostics = { GetCA1710CSharpResultAt(5, 14, "C", "Collection", "Dictionary', 'Set', 'Stack', 'Queue") }
                }
            }.RunAsync();
        }
 
        [Theory, WorkItem(3065, "https://github.com/dotnet/roslyn-analyzers/issues/3065")]
        [InlineData("")]
        [InlineData("dotnet_code_quality.CA1710.exclude_indirect_base_types = false")]
        [InlineData("dotnet_code_quality.CA1710.exclude_indirect_base_types = true")]
        [InlineData("dotnet_code_quality.CA1710.exclude_indirect_base_types = invalid")]
        [InlineData(@"dotnet_code_quality.CA1710.exclude_indirect_base_types = true
                      dotnet_code_quality.CA1710.additional_required_suffixes = SomeClass->Suffix1")]
        [InlineData(@"dotnet_code_quality.CA1710.exclude_indirect_base_types = false
                      dotnet_code_quality.CA1710.additional_required_suffixes = SomeClass->Suffix1")]
        public async Task CA1710_ExcludeIndirectTypesAsync(string editorConfigText)
        {
            var csharpTest = new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
 
public class C : Exception {}
public class Sub : C {}
 
public class FreezableList : ReadOnlyCollection<int>
{
    public FreezableList(IList<int> list) : base(list)
    {
    }
}
 
public class SomeClass {}
public class SomeSubClass : SomeClass {}
public class SomeSubSubClass : SomeSubClass {}"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                    ExpectedDiagnostics = { GetCA1710CSharpResultAt(7, 14, "C", "Exception") },
                }
            };
 
            if (editorConfigText.Contains("exclude_indirect_base_types = false", StringComparison.Ordinal))
            {
                csharpTest.ExpectedDiagnostics.AddRange(new[]
                {
                    GetCA1710CSharpResultAt(8, 14, "Sub", "Exception"),
                    GetCA1710CSharpResultAt(10, 14, "FreezableList", "Collection", "Dictionary', 'Set', 'Stack', 'Queue"),
                });
 
                if (editorConfigText.EndsWith("Suffix1", StringComparison.Ordinal))
                {
                    csharpTest.ExpectedDiagnostics.AddRange(new[]
                    {
                        GetCA1710CSharpResultAt(18, 14, "SomeSubClass", "Suffix1"),
                        GetCA1710CSharpResultAt(19, 14, "SomeSubSubClass", "Suffix1"),
                    });
                }
            }
            else
            {
                if (editorConfigText.EndsWith("Suffix1", StringComparison.Ordinal))
                {
                    csharpTest.ExpectedDiagnostics.Add(GetCA1710CSharpResultAt(18, 14, "SomeSubClass", "Suffix1"));
                }
            }
 
            await csharpTest.RunAsync();
 
            var vbTest = new VerifyVB.Test
            {
                TestState =
                {
                    Sources =
                    {
                        @"
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
 
Public Class C
    Inherits Exception
End Class
 
Public Class [Sub]
    Inherits C
End Class
 
Public Class FreezableList
    Inherits ReadOnlyCollection(Of Integer)
 
    Public Sub New(ByVal list As IList(Of Integer))
        MyBase.New(list)
    End Sub
End Class
 
Public Class SomeClass
End Class
 
Public Class SomeSubClass
    Inherits SomeClass
End Class
 
Public Class SomeSubSubClass
    Inherits SomeSubClass
End Class"
                    },
                    AnalyzerConfigFiles = { ("/.editorconfig", $@"root = true
 
[*]
{editorConfigText}
")  },
                    ExpectedDiagnostics = { GetCA1710BasicResultAt(7, 14, "C", "Exception") },
                }
            };
 
            if (editorConfigText.Contains("exclude_indirect_base_types = false", StringComparison.Ordinal))
            {
                vbTest.ExpectedDiagnostics.AddRange(new[]
                {
                    GetCA1710BasicResultAt(11, 14, "[Sub]", "Exception"),
                    GetCA1710BasicResultAt(15, 14, "FreezableList", "Collection", "Dictionary', 'Set', 'Stack', 'Queue"),
                });
 
                if (editorConfigText.EndsWith("Suffix1", StringComparison.Ordinal))
                {
                    vbTest.ExpectedDiagnostics.AddRange(new[]
                    {
                        GetCA1710BasicResultAt(26, 14, "SomeSubClass", "Suffix1"),
                        GetCA1710BasicResultAt(30, 14, "SomeSubSubClass", "Suffix1"),
                    });
                }
            }
            else
            {
                if (editorConfigText.EndsWith("Suffix1", StringComparison.Ordinal))
                {
                    vbTest.ExpectedDiagnostics.Add(GetCA1710BasicResultAt(26, 14, "SomeSubClass", "Suffix1"));
                }
            }
 
            await vbTest.RunAsync();
        }
 
        [Fact, WorkItem(3414, "https://github.com/dotnet/roslyn-analyzers/issues/3414")]
        public async Task CA1710_InterfacesAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync(@"
public interface I
{
}");
        }
 
        [Fact]
        public async Task EventArgsNotInheritingFromSystemEventArgs_DiagnosticAsync()
        {
            await VerifyCS.VerifyAnalyzerAsync(@"
// Reproduce UWP specific EventArgs
namespace Windows.UI.Xaml
{
    public class RoutedEventArgs {}
}
public class C
{
    public delegate void Page_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e);
}");
 
            await VerifyVB.VerifyAnalyzerAsync(@"
' Reproduce UWP specific EventArgs
Namespace Windows.UI.Xaml
    Public Class RoutedEventArgs
    End Class
End Namespace
 
Public Class C
    Public Delegate Sub Page_Loaded(ByVal sender As Object, ByVal e As Windows.UI.Xaml.RoutedEventArgs)
End Class");
        }
 
        [Theory, WorkItem(4513, "https://github.com/dotnet/roslyn-analyzers/issues/4513")]
        [InlineData("")]
        [InlineData("Set")]
        [InlineData("Collection")]
        public async Task CA1710_ISet_IReadOnlySet(string typeNameSuffix)
        {
            var test = new VerifyCS.Test
            {
                ReferenceAssemblies = ReferenceAssemblies.Net.Net50,
                TestCode = @"
using System;
using System.Collections;
using System.Collections.Generic;
 
public class {|#0:First" + typeNameSuffix + @"|} : ISet<int>
{
    public int Count => throw new NotImplementedException();
 
    public bool IsReadOnly => throw new NotImplementedException();
 
    public bool Add(int item)
    {
        throw new NotImplementedException();
    }
 
    public void Clear()
    {
        throw new NotImplementedException();
    }
 
    public bool Contains(int item)
    {
        throw new NotImplementedException();
    }
 
    public void CopyTo(int[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }
 
    public void ExceptWith(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public IEnumerator<int> GetEnumerator()
    {
        throw new NotImplementedException();
    }
 
    public void IntersectWith(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool IsProperSubsetOf(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool IsProperSupersetOf(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool IsSubsetOf(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool IsSupersetOf(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool Overlaps(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool Remove(int item)
    {
        throw new NotImplementedException();
    }
 
    public bool SetEquals(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public void SymmetricExceptWith(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public void UnionWith(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    void ICollection<int>.Add(int item)
    {
        throw new NotImplementedException();
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}
 
public class {|#1:Second" + typeNameSuffix + @"|} : IReadOnlySet<int>
{
    public int Count => throw new NotImplementedException();
 
    public bool Contains(int item)
    {
        throw new NotImplementedException();
    }
 
    public IEnumerator<int> GetEnumerator()
    {
        throw new NotImplementedException();
    }
 
    public bool IsProperSubsetOf(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool IsProperSupersetOf(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool IsSubsetOf(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool IsSupersetOf(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool Overlaps(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    public bool SetEquals(IEnumerable<int> other)
    {
        throw new NotImplementedException();
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}",
            };
 
            if (typeNameSuffix.Length == 0)
            {
                test.ExpectedDiagnostics.AddRange(new[]
                {
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(0)
                        .WithArguments("First", "Set", "Collection"),
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(1)
                        .WithArguments("Second", "Set", "Collection"),
                });
            }
 
            await test.RunAsync();
        }
 
        [Theory, WorkItem(4513, "https://github.com/dotnet/roslyn-analyzers/issues/4513")]
        [InlineData("")]
        [InlineData("Collection")]
        public async Task CA1710_IReadOnlyCollection(string typeNameSuffix)
        {
            var test = new VerifyCS.Test
            {
                TestCode = @"
using System;
using System.Collections;
using System.Collections.Generic;
 
public class {|#0:C" + typeNameSuffix + @"|} : IReadOnlyCollection<int>
{
    public int Count => throw new System.NotImplementedException();
 
    public IEnumerator<int> GetEnumerator() => throw new System.NotImplementedException();
    IEnumerator IEnumerable.GetEnumerator() => throw new System.NotImplementedException();
}",
            };
 
            if (typeNameSuffix.Length == 0)
            {
                test.ExpectedDiagnostics.Add(
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(0)
                        .WithArguments("C", "Collection", "Dictionary', 'Set', 'Stack', 'Queue"));
            }
 
            await test.RunAsync();
        }
 
        [Theory]
        [InlineData("")]
        [InlineData("Dictionary")]
        [InlineData("Collection")]
        public async Task CA1710_IDictionary_IDictionary2_IReadOnlyDictionary2(string typeNameSuffix)
        {
            var test = new VerifyCS.Test
            {
                TestCode = @"
using System;
using System.Collections;
using System.Collections.Generic;
 
public class {|#0:First" + typeNameSuffix + @"|} : IDictionary
{
    public object this[object key] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
 
    public bool IsFixedSize => throw new NotImplementedException();
 
    public bool IsReadOnly => throw new NotImplementedException();
 
    public ICollection Keys => throw new NotImplementedException();
 
    public ICollection Values => throw new NotImplementedException();
 
    public int Count => throw new NotImplementedException();
 
    public bool IsSynchronized => throw new NotImplementedException();
 
    public object SyncRoot => throw new NotImplementedException();
 
    public void Add(object key, object value)
    {
        throw new NotImplementedException();
    }
 
    public void Clear()
    {
        throw new NotImplementedException();
    }
 
    public bool Contains(object key)
    {
        throw new NotImplementedException();
    }
 
    public void CopyTo(Array array, int index)
    {
        throw new NotImplementedException();
    }
 
    public IDictionaryEnumerator GetEnumerator()
    {
        throw new NotImplementedException();
    }
 
    public void Remove(object key)
    {
        throw new NotImplementedException();
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}
 
public class {|#1:Second" + typeNameSuffix + @"|} : IDictionary<int, string>
{
    public string this[int key] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
 
    public ICollection<int> Keys => throw new NotImplementedException();
 
    public ICollection<string> Values => throw new NotImplementedException();
 
    public int Count => throw new NotImplementedException();
 
    public bool IsReadOnly => throw new NotImplementedException();
 
    public void Add(int key, string value)
    {
        throw new NotImplementedException();
    }
 
    public void Add(KeyValuePair<int, string> item)
    {
        throw new NotImplementedException();
    }
 
    public void Clear()
    {
        throw new NotImplementedException();
    }
 
    public bool Contains(KeyValuePair<int, string> item)
    {
        throw new NotImplementedException();
    }
 
    public bool ContainsKey(int key)
    {
        throw new NotImplementedException();
    }
 
    public void CopyTo(KeyValuePair<int, string>[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }
 
    public IEnumerator<KeyValuePair<int, string>> GetEnumerator()
    {
        throw new NotImplementedException();
    }
 
    public bool Remove(int key)
    {
        throw new NotImplementedException();
    }
 
    public bool Remove(KeyValuePair<int, string> item)
    {
        throw new NotImplementedException();
    }
 
    public bool TryGetValue(int key, out string value)
    {
        throw new NotImplementedException();
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}
 
public class {|#2:Third" + typeNameSuffix + @"|} : IReadOnlyDictionary<int, string>
{
    public string this[int key] => throw new NotImplementedException();
 
    public IEnumerable<int> Keys => throw new NotImplementedException();
 
    public IEnumerable<string> Values => throw new NotImplementedException();
 
    public int Count => throw new NotImplementedException();
 
    public bool ContainsKey(int key)
    {
        throw new NotImplementedException();
    }
 
    public IEnumerator<KeyValuePair<int, string>> GetEnumerator()
    {
        throw new NotImplementedException();
    }
 
    public bool TryGetValue(int key, out string value)
    {
        throw new NotImplementedException();
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}",
            };
 
            if (typeNameSuffix.Length == 0)
            {
                test.ExpectedDiagnostics.AddRange(new[]
                {
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(0)
                        .WithArguments("First", "Dictionary", "Collection"),
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(1)
                        .WithArguments("Second", "Dictionary", "Collection"),
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(2)
                        .WithArguments("Third", "Dictionary", "Collection"),
                });
            }
 
            await test.RunAsync();
        }
 
        [Theory]
        [InlineData("")]
        [InlineData("Queue")]
        [InlineData("Collection")]
        public async Task CA1710_Queue_Queue1(string typeNameSuffix)
        {
            var test = new VerifyCS.Test
            {
                TestCode = @"
using System;
using System.Collections;
using System.Collections.Generic;
 
public class {|#0:First" + typeNameSuffix + @"|} : Queue
{
}
 
public class {|#1:Second" + typeNameSuffix + @"|} : Queue<int>
{
}",
            };
 
            if (typeNameSuffix.Length == 0)
            {
                test.ExpectedDiagnostics.AddRange(new[]
                {
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(0)
                        .WithArguments("First", "Queue", "Collection"),
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(1)
                        .WithArguments("Second", "Queue", "Collection"),
                });
            }
 
            await test.RunAsync();
        }
 
        [Theory]
        [InlineData("")]
        [InlineData("Stack")]
        [InlineData("Collection")]
        public async Task CA1710_Stack_Stack1(string typeNameSuffix)
        {
            var test = new VerifyCS.Test
            {
                TestCode = @"
using System;
using System.Collections;
using System.Collections.Generic;
 
public class {|#0:First" + typeNameSuffix + @"|} : Stack
{
}
 
public class {|#1:Second" + typeNameSuffix + @"|} : Stack<int>
{
}",
            };
 
            if (typeNameSuffix.Length == 0)
            {
                test.ExpectedDiagnostics.AddRange(new[]
                {
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(0)
                        .WithArguments("First", "Stack", "Collection"),
                    VerifyCS.Diagnostic(IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule)
                        .WithLocation(1)
                        .WithArguments("Second", "Stack", "Collection"),
                });
            }
 
            await test.RunAsync();
        }
 
        private static DiagnosticResult GetCA1710BasicResultAt(int line, int column, string typeName, string suffix, params string[] additionalSuffixes)
        {
            var args = new[] { typeName, suffix }.Concat(additionalSuffixes).ToArray();
#pragma warning disable RS0030 // Do not use banned APIs
            return VerifyVB
                .Diagnostic(additionalSuffixes.Length > 0
                    ? IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule
                    : IdentifiersShouldHaveCorrectSuffixAnalyzer.OneSuffixRule)
                .WithLocation(line, column)
#pragma warning restore RS0030 // Do not use banned APIs
                .WithArguments(args);
        }
 
        private static DiagnosticResult GetCA1710CSharpResultAt(int line, int column, string typeName, string suffix, params string[] additionalSuffixes)
        {
            var args = new[] { typeName, suffix }.Concat(additionalSuffixes).ToArray();
#pragma warning disable RS0030 // Do not use banned APIs
            return VerifyCS
                .Diagnostic(additionalSuffixes.Length > 0
                    ? IdentifiersShouldHaveCorrectSuffixAnalyzer.MultipleSuffixesRule
                    : IdentifiersShouldHaveCorrectSuffixAnalyzer.OneSuffixRule)
                .WithLocation(line, column)
#pragma warning restore RS0030 // Do not use banned APIs
                .WithArguments(args);
        }
    }
}