コード例 #1
0
        public void AssemblyVersionMustBeStrictlyCompatible()
        {
            string leftSyntax  = "[assembly: System.Reflection.AssemblyVersionAttribute(\"1.0.0.0\")]";
            string rightSyntax = "[assembly: System.Reflection.AssemblyVersionAttribute(\"2.0.0.0\")]";

            IAssemblySymbol leftSymbol  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol rightSymbol = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            Assert.Equal(new Version(1, 0, 0, 0), leftSymbol.Identity.Version);
            Assert.Equal(new Version(2, 0, 0, 0), rightSymbol.Identity.Version);

            // Compatible assembly versions
            ApiComparer differ = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(leftSymbol, rightSymbol);

            Assert.Empty(differences);

            differ.StrictMode = true;

            // Not strictly compatible
            differences = differ.GetDifferences(leftSymbol, rightSymbol);
            Assert.Single(differences);

            CompatDifference expected = new(DiagnosticIds.AssemblyIdentityMustMatch, string.Empty, DifferenceType.Changed, $"{leftSymbol.Name}, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");

            Assert.Equal(expected, differences.First());
        }
コード例 #2
0
        public void LeftAssemblyKeyTokenNull(bool strictMode)
        {
            string syntax = "namespace EmptyNs { }";

            IAssemblySymbol leftSymbol  = SymbolFactory.GetAssemblyFromSyntax(syntax);
            IAssemblySymbol rightSymbol = SymbolFactory.GetAssemblyFromSyntax(syntax, publicKey: _publicKey);

            Assert.False(leftSymbol.Identity.HasPublicKey);
            Assert.Equal(_publicKey, rightSymbol.Identity.PublicKey);

            ApiComparer differ = new();

            differ.StrictMode = strictMode;
            IEnumerable <CompatDifference> differences = differ.GetDifferences(leftSymbol, rightSymbol);

            if (strictMode)
            {
                Assert.Single(differences);
                CompatDifference expected = new(DiagnosticIds.AssemblyIdentityMustMatch, string.Empty, DifferenceType.Changed, $"{rightSymbol.Name}, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
                Assert.Equal(expected, differences.First());
            }
            else
            {
                Assert.Empty(differences);
            }
        }
コード例 #3
0
ファイル: TypeMustExistTests.cs プロジェクト: nohwnd/sdk
        public void NestedTypeVsNamespaces()
        {
            string          leftSyntax                 = @"
namespace A
{
  public class B { }
}
";
            string          rightSyntax                = @"
public class A
{
  public class B { }
}
";
            ApiComparer     differ                     = new();
            bool            enableNullable             = false;
            IAssemblySymbol left                       = SymbolFactory.GetAssemblyFromSyntax(leftSyntax, enableNullable);
            IAssemblySymbol right                      = SymbolFactory.GetAssemblyFromSyntax(rightSyntax, enableNullable);
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            CompatDifference[] expected = new[]
            {
                new CompatDifference(DiagnosticIds.TypeMustExist, string.Empty, DifferenceType.Removed, "T:A.B"),
            };

            Assert.Equal(expected, differences);
        }
コード例 #4
0
        public static void NoDifferencesWithNoWarn()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First
  {
    public void MissingMember() { }
    public int MissingProperty { get; }
    public int MissingField;
  }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class First
  {
  }
}
";

            IAssemblySymbol left   = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right  = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiDiffer       differ = new();

            differ.NoWarn = DiagnosticIds.MemberMustExist;
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            Assert.Empty(differences);
        }
コード例 #5
0
ファイル: MembersMustExistTests.cs プロジェクト: nohwnd/sdk
        public static void MembersWithDifferentNullableAnnotationsNoErrors()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string? MyMethod(string? a) => null;
  }
}
";

            string          rightSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string MyMethod(string a) => null;
  }
}
";
            IAssemblySymbol left        = SymbolFactory.GetAssemblyFromSyntax(leftSyntax, enableNullable: true);
            IAssemblySymbol right       = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiComparer     differ      = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            Assert.Empty(differences);
        }
コード例 #6
0
ファイル: EnumsMustMatchTests.cs プロジェクト: nohwnd/sdk
        public static void AddedEnum()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public enum First {
    A = 0,
    B = 1,
    C = 2,
    D = 3,
  }
}
";

            string          rightSyntax = @"
namespace CompatTests
{
  public enum First {
    D = 3,
    C = 2,
    B = 1,
    A = 0,
  }
  public enum Second {}
}
";
            IAssemblySymbol left        = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right       = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiComparer     differ      = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            Assert.Empty(differences);
        }
コード例 #7
0
ファイル: MembersMustExistTests.cs プロジェクト: nohwnd/sdk
        public void ParameterlessConstructorRemovalIsReported()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public sealed class First
  {
  }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class First
  {
    private First() { }
  }
}
";

            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            CompatDifference[] expected = new[]
            {
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Removed, "M:CompatTests.First.#ctor")
            };

            Assert.Equal(expected, differences);
        }
コード例 #8
0
ファイル: MembersMustExistTests.cs プロジェクト: nohwnd/sdk
        public static void ParametersWithDifferentModifiersNoErrors()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string MyMethod(ref string a) => throw null;
    public void MyOutMethod(out string a) => throw null;
  }
}
";

            string          rightSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string MyMethod(string a) => throw null;
    public void MyOutMethod(string a) { }
  }
}
";
            IAssemblySymbol left        = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right       = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiComparer     differ      = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            Assert.Empty(differences);
        }
コード例 #9
0
ファイル: TypeMustExistTests.cs プロジェクト: nohwnd/sdk
        public void MissingTypeFromTypeForwardIsReported()
        {
            string forwardedTypeSyntax = @"
namespace CompatTests
{
  public class ForwardedTestType { }
}
";
            string leftSyntax          = @"
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(CompatTests.ForwardedTestType))]
namespace CompatTests
{
  public class First { }
}
";

            string          rightSyntax = @"
namespace CompatTests
{
  public class First { }
}
";
            IAssemblySymbol left        = SymbolFactory.GetAssemblyFromSyntaxWithReferences(leftSyntax, new[] { forwardedTypeSyntax });
            IAssemblySymbol right       = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiComparer     differ      = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            CompatDifference[] expected = new[]
            {
                new CompatDifference(DiagnosticIds.TypeMustExist, string.Empty, DifferenceType.Removed, "T:CompatTests.ForwardedTestType")
            };

            Assert.Equal(expected, differences);
        }
コード例 #10
0
ファイル: TypeMustExistTests.cs プロジェクト: nohwnd/sdk
        public static void MultipleRightsNoDifferences()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First
  {
    public class FirstNested
    {
      public class SecondNested
      {
        public class ThirdNested
        {
          public string MyField;
        }
      }
    }
  }
}
";

            string[] rightSyntaxes = new[] { leftSyntax, leftSyntax, leftSyntax, leftSyntax };

            ApiComparer differ = new();
            ElementContainer <IAssemblySymbol> left =
                new(SymbolFactory.GetAssemblyFromSyntax(leftSyntax), new MetadataInformation(string.Empty, string.Empty, "ref"));

            IList <ElementContainer <IAssemblySymbol> > right = SymbolFactory.GetElementContainersFromSyntaxes(rightSyntaxes);

            IEnumerable <(MetadataInformation, MetadataInformation, IEnumerable <CompatDifference>)> differences =
                differ.GetDifferences(left, right);

            AssertExtensions.MultiRightEmptyDifferences(left.MetadataInformation, rightSyntaxes.Length, differences);
        }
コード例 #11
0
ファイル: TypeMustExistTests.cs プロジェクト: nohwnd/sdk
        public void MultipleRightsMissingTypeForwardIsReported()
        {
            string forwardedTypeSyntax = @"
namespace CompatTests
{
  public class ForwardedTestType { }
}
";
            string rightWithForward    = @"
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(CompatTests.ForwardedTestType))]
";

            string[]             rightSyntaxes      = new[] { rightWithForward, "namespace CompatTests { internal class Foo { } }", rightWithForward };
            IEnumerable <string> references         = new[] { forwardedTypeSyntax };
            ElementContainer <IAssemblySymbol> left =
                new(SymbolFactory.GetAssemblyFromSyntax(forwardedTypeSyntax), new MetadataInformation(string.Empty, string.Empty, "ref"));
            IList <ElementContainer <IAssemblySymbol> > right = SymbolFactory.GetElementContainersFromSyntaxes(rightSyntaxes, references);

            ApiComparer differ = new();
            IEnumerable <(MetadataInformation, MetadataInformation, IEnumerable <CompatDifference>)> differences =
                differ.GetDifferences(left, right);

            CompatDifference[][] expected =
            {
                Array.Empty <CompatDifference>(),
                new[]
                {
                    new CompatDifference(DiagnosticIds.TypeMustExist,string.Empty,  DifferenceType.Removed, "T:CompatTests.ForwardedTestType"),
                },
                Array.Empty <CompatDifference>(),
            };

            AssertExtensions.MultiRightResult(left.MetadataInformation, expected, differences);
        }
コード例 #12
0
        public static void TypesMissingOnBothSidesAreReported()
        {
            string      leftSyntax  = @"
namespace CompatTests
{
  public class LeftType { }
}
";
            string      rightSyntax = @"
namespace CompatTests
{
  public class RightType { }
}
";
            ApiComparer differ      = new();

            differ.StrictMode = true;
            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            List <CompatDifference> expected = new()
            {
                new CompatDifference(DiagnosticIds.TypeMustExist, string.Empty, DifferenceType.Removed, "T:CompatTests.LeftType"),
                new CompatDifference(DiagnosticIds.TypeMustExist, string.Empty, DifferenceType.Added, "T:CompatTests.RightType"),
            };

            Assert.Equal(expected, differences);
        }
コード例 #13
0
        public void PromotedBaseClassOrInterfaceIsNotReported()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First : FirstBase, IFirstInterface { }
  public class Second : SecondBase { }
  public class SecondBase { }
  public class FirstBase { }
  public interface IFirstInterface { }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class First : NewBase { }
  public class Second : NewSecondBase { }
  public class NewBase : FirstBase, INewInterface { }
  public class FirstBase { }
  public class SecondBase { }
  public class NewSecondBase : NewSecondBaseBase { }
  public class NewSecondBaseBase : SecondBase { }
  public interface IFirstInterface { }
  public interface INewInterface : IFirstInterface { }
}
";

            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();

            Assert.Empty(differ.GetDifferences(left, right));
        }
コード例 #14
0
        public static void MultipleRightsMissingTypesOnLeftAreReported()
        {
            string leftSyntax = @"

namespace CompatTests
{
  public class First { }
}
";

            string[] rightSyntaxes = new[]
            { @"
namespace CompatTests
{
  public class First { }
}
",
              @"
namespace CompatTests
{
  public class First { }
  public class Second { }
}
",
              @"
namespace CompatTests
{
  public class First { }
  public class Third { }
}
" };

            ApiComparer differ = new();

            differ.StrictMode = true;
            ElementContainer <IAssemblySymbol> left =
                new(SymbolFactory.GetAssemblyFromSyntax(leftSyntax), new MetadataInformation(string.Empty, string.Empty, "ref"));

            IList <ElementContainer <IAssemblySymbol> > right = SymbolFactory.GetElementContainersFromSyntaxes(rightSyntaxes);

            IEnumerable <(MetadataInformation, MetadataInformation, IEnumerable <CompatDifference>)> differences =
                differ.GetDifferences(left, right);

            CompatDifference[][] expected =
            {
                Array.Empty <CompatDifference>(),
                new[]
                {
                    new CompatDifference(DiagnosticIds.TypeMustExist,string.Empty,  DifferenceType.Added, "T:CompatTests.Second"),
                },
                new[]
                {
                    new CompatDifference(DiagnosticIds.TypeMustExist,string.Empty,  DifferenceType.Added, "T:CompatTests.Third"),
                },
            };

            AssertExtensions.MultiRightResult(left.MetadataInformation, expected, differences);
        }
コード例 #15
0
        public void MembersPushedDownToNewBaseNotReported()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First : FirstBase { }
  public class Second : SecondBase
  {
    public string MyMethod() => string.Empty;
    public int MyProperty => 0;
  }
  public class SecondBase : ThirdBase
  {
    public void AnotherMethod() { }
    public string MethodWithArguments(string a) => MethodWithArguments(a, string.Empty);
    public string MethodWithArguments(string a, string b) => MethodWithArguments(a, string.Empty, string.Empty);
    public string MethodWithArguments(string a, string b, string c) => c;
  }
  public class FirstBase { }
  public class ThirdBase { }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class First : NewBase { }
  public class Second : NewSecondBase
  {
    public int MyProperty => 0;
  }
  public class NewBase : FirstBase { }
  public class FirstBase { }
  public class NewSecondBase : SecondBase
  {
    public string MyMethod() => string.Empty;
  }
  public class SecondBase : NewThirdBase
  {
    public void AnotherMethod() { }
    public string MethodWithArguments(string a) => MethodWithArguments(a, string.Empty);
  }
  public class NewThirdBase : ThirdBase
  {
    public string MethodWithArguments(string a, string b) => MethodWithArguments(a, string.Empty, string.Empty);
    public string MethodWithArguments(string a, string b, string c) => c;
  }
  public class ThirdBase { }
}
";

            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();

            Assert.Empty(differ.GetDifferences(left, right));
        }
コード例 #16
0
        public void NoDifferencesShouldBeReported(string leftSyntax, string rightSyntax)
        {
            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            Assert.Empty(differences);
        }
コード例 #17
0
        public void AddedAbstractMemberNoVisibleConstructor(string leftSyntax, string rightSyntax)
        {
            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            Assert.Empty(differences);
        }
コード例 #18
0
        public static void IncludeInternalsIsRespectedForMembers_IndividualAssemblies(bool includeInternals)
        {
            string rightSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string MultipleOverrides() => string.Empty;
    public string MultipleOverrides(string a) => string.Empty;
    public string MultipleOverrides(string a, string b) => string.Empty;
    public string MultipleOverrides(string a, int b, string c) => string.Empty;
    internal string MultipleOverrides(string a, int b, int c) => string.Empty;
    internal int InternalProperty { get; set; }
  }
}
";

            string leftSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string MultipleOverrides() => string.Empty;
    public string MultipleOverrides(string a) => string.Empty;
    public string MultipleOverrides(string a, string b) => string.Empty;
    public string MultipleOverrides(string a, int b, string c) => string.Empty;
    internal int InternalProperty { get; }
  }
}
";

            IAssemblySymbol left   = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right  = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiComparer     differ = new();

            differ.IncludeInternalSymbols = includeInternals;
            differ.StrictMode             = true;
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            if (includeInternals)
            {
                CompatDifference[] expected = new[]
                {
                    new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "M:CompatTests.First.MultipleOverrides(System.String,System.Int32,System.Int32)"),
                    new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "M:CompatTests.First.set_InternalProperty(System.Int32)"),
                };

                Assert.Equal(expected, differences);
            }
            else
            {
                Assert.Empty(differences);
            }
        }
コード例 #19
0
ファイル: CannotSealTypeTests.cs プロジェクト: nohwnd/sdk
        public void SealInheritableTypeReported(string leftSyntax, string rightSyntax)
        {
            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            CompatDifference difference = new(DiagnosticIds.CannotSealType, string.Empty, DifferenceType.Changed, "T:CompatTests.First");

            Assert.Contains(difference, differences);
        }
コード例 #20
0
ファイル: CannotSealTypeTests.cs プロジェクト: nohwnd/sdk
        public void MultipleRightsNoDifferences()
        {
            string leftSyntax = @"
namespace CompatTests
{
    public class First
    {
    }
}
";

            string[] rightSyntaxes = new[]
            {
                @"
namespace CompatTests
{
    public class First
    {
    }
}",
                @"
namespace CompatTests
{
    public class First
    {
        protected First() { }
    }
}",
                @"
namespace CompatTests
{
    public class First
    {
        internal First() { }
    }
}"
            };

            IAssemblySymbol     left         = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            MetadataInformation leftMetadata = new("left", "net6.0", "ref/a.dll");
            ElementContainer <IAssemblySymbol> leftContainer = new(left, leftMetadata);

            IList <ElementContainer <IAssemblySymbol> > right = SymbolFactory.GetElementContainersFromSyntaxes(rightSyntaxes);

            ApiComparer differ = new();

            differ.IncludeInternalSymbols = true;
            IEnumerable <(MetadataInformation left, MetadataInformation right, IEnumerable <CompatDifference> differences)> result =
                differ.GetDifferences(leftContainer, right);

            AssertExtensions.MultiRightEmptyDifferences(leftMetadata, 3, result);
        }
コード例 #21
0
ファイル: CannotSealTypeTests.cs プロジェクト: nohwnd/sdk
        public void SealNonInheritableTypeNotReported(string leftSyntax, string rightSyntax)
        {
            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            foreach (CompatDifference difference in differences)
            {
                Assert.NotEqual(DiagnosticIds.CannotSealType, difference.DiagnosticId);
            }
        }
コード例 #22
0
ファイル: TypeMustExistTests.cs プロジェクト: nohwnd/sdk
        public static void MissingNestedTypeIsReported(bool includeInternalSymbols)
        {
            string leftSyntax = @"

namespace CompatTests
{
  public class First
  {
    public class FirstNested
    {
      public class SecondNested { }
    }
    internal class InternalNested
    {
        internal class DoubleNested { }
    }
  }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class First
  {
    internal class InternalNested { }
  }
}
";

            ApiComparer differ = new();

            differ.IncludeInternalSymbols = includeInternalSymbols;
            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            List <CompatDifference> expected = new()
            {
                new CompatDifference(DiagnosticIds.TypeMustExist, string.Empty, DifferenceType.Removed, "T:CompatTests.First.FirstNested"),
            };

            if (includeInternalSymbols)
            {
                expected.Add(
                    new CompatDifference(DiagnosticIds.TypeMustExist, string.Empty, DifferenceType.Removed, "T:CompatTests.First.InternalNested.DoubleNested")
                    );
            }

            Assert.Equal(expected, differences);
        }
コード例 #23
0
        public static void IncludeInternalsIsRespectedForMembers(bool includeInternals)
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string MultipleOverrides() { }
    public string MultipleOverrides(string a) { }
    public string MultipleOverrides(string a, string b) { }
    public string MultipleOverrides(string a, int b, string c) { }
    internal string MultipleOverrides(string a, int b, int c) { }
    internal int InternalProperty { get; set; }
  }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string MultipleOverrides() { }
    public string MultipleOverrides(string a) { }
    public string MultipleOverrides(string a, string b) { }
    public string MultipleOverrides(string a, int b, string c) { }
    internal int InternalProperty { get; }
  }
}
";

            IAssemblySymbol left   = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right  = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiDiffer       differ = new(includeInternalSymbols : includeInternals);
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            if (includeInternals)
            {
                CompatDifference[] expected = new[]
                {
                    new CompatDifference(DiagnosticIds.MemberMustExist, "Member 'CompatTests.First.MultipleOverrides(string, int, int)' exists on the contract but not on the implementation", DifferenceType.Removed, "M:CompatTests.First.MultipleOverrides(System.String,System.Int32,System.Int32)"),
                    new CompatDifference(DiagnosticIds.MemberMustExist, "Member 'CompatTests.First.InternalProperty.set' exists on the contract but not on the implementation", DifferenceType.Removed, "M:CompatTests.First.set_InternalProperty(System.Int32)"),
                };

                Assert.Equal(expected, differences);
            }
            else
            {
                Assert.Empty(differences);
            }
        }
コード例 #24
0
        public static void MissingMembersOnLeftAreReported()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string Parameterless() => string.Empty;
  }
  public delegate void EventHandler(object sender, System.EventArgs e);
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string Parameterless() => string.Empty;
    public void ShouldReportMethod(string a, string b) { }
    public string ShouldReportMissingProperty { get; }
    public string this[int index] { get => string.Empty; }
    public event EventHandler ShouldReportMissingEvent;
    public int ReportMissingField = 0;
  }

  public delegate void EventHandler(object sender, System.EventArgs e);
}
";

            IAssemblySymbol left   = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right  = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiComparer     differ = new();

            differ.StrictMode = true;
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            CompatDifference[] expected = new[]
            {
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "M:CompatTests.First.ShouldReportMethod(System.String,System.String)"),
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "M:CompatTests.First.get_ShouldReportMissingProperty"),
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "M:CompatTests.First.get_Item(System.Int32)"),
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "M:CompatTests.First.add_ShouldReportMissingEvent(CompatTests.EventHandler)"),
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "M:CompatTests.First.remove_ShouldReportMissingEvent(CompatTests.EventHandler)"),
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "F:CompatTests.First.ReportMissingField"),
            };

            Assert.Equal(expected, differences);
        }
コード例 #25
0
ファイル: CannotSealTypeTests.cs プロジェクト: nohwnd/sdk
        public void StrictModeSealedLeftIsReported(string leftSyntax, string rightSyntax)
        {
            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();

            differ.StrictMode = true;
            CompatDifference[] differences = differ.GetDifferences(left, right).ToArray();

            CompatDifference difference = new(DiagnosticIds.CannotSealType, string.Empty, DifferenceType.Changed, "T:CompatTests.First");

            Assert.Contains(difference, differences);
            Assert.True(differences[0].Message.IndexOf("left") < differences[0].Message.IndexOf("right"));
        }
コード例 #26
0
        public void AddedAbstractMemberIsReported(string leftSyntax, string rightSyntax, bool includeInternals)
        {
            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();

            differ.IncludeInternalSymbols = includeInternals;
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            CompatDifference[] expected = new[]
            {
                new CompatDifference(DiagnosticIds.CannotAddAbstractMember, string.Empty, DifferenceType.Added, "M:CompatTests.First.SecondAbstract")
            };

            Assert.Equal(expected, differences);
        }
コード例 #27
0
        public void RemovedFromLeftReportedOnStrictMode()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First { }
  public class FirstBase { }
  public interface IFirstInterface { }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class First : FirstBase, IFirstInterface { }
  public class FirstBase { }
  public interface IFirstInterface { }
}
";

            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();

            differ.StrictMode = true;

            CompatDifference[] differences = differ.GetDifferences(left, right).ToArray();

            CompatDifference[] expected = new[]
            {
                new CompatDifference(DiagnosticIds.CannotRemoveBaseType, string.Empty, DifferenceType.Changed, "T:CompatTests.First"),
                new CompatDifference(DiagnosticIds.CannotRemoveBaseInterface, string.Empty, DifferenceType.Changed, "T:CompatTests.First"),
            };

            Assert.Equal(expected, differences);

            string firstMessage  = differences[0].Message;
            string secondMessage = differences[1].Message;

            firstMessage.Contains("CompatTests.FirstBase");
            secondMessage.Contains("CompatTests.IFirstInterface");

            Assert.True(firstMessage.IndexOf("right") > firstMessage.IndexOf("left"));
            Assert.True(secondMessage.IndexOf("right") > firstMessage.IndexOf("left"));
        }
コード例 #28
0
        public static void MissingMembersOnEnumReported()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public enum First
  {
    A = 0,
    B = 1,
    C = 2,
    D = 3,
  }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public enum First
  {
    F = 5,
    E = 4,
    D = 3,
    C = 2,
  }
}
";

            IAssemblySymbol left   = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right  = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiComparer     differ = new();

            differ.StrictMode = true;
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            CompatDifference[] expected = new[]
            {
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Removed, "F:CompatTests.First.A"),
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Removed, "F:CompatTests.First.B"),
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "F:CompatTests.First.F"),
                new CompatDifference(DiagnosticIds.MemberMustExist, string.Empty, DifferenceType.Added, "F:CompatTests.First.E"),
            };

            Assert.Equal(expected, differences);
        }
コード例 #29
0
        public static void HiddenMemberInRightIsNotReported()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class FirstBase
  {
    public void MyMethod() { }
    public string MyMethodWithParams(string a, int b, FirstBase c) => string.Empty;
    public T MyGenericMethod<T, T2, T3>(string name, T2 a, T3 b) => throw null;
    public virtual string MyVirtualMethod() => string.Empty;
  }
  public class Second : FirstBase { }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class FirstBase
  {
    public void MyMethod() { }
    public string MyMethodWithParams(string a, int b, FirstBase c) => string.Empty;
    public T MyGenericMethod<T, T2, T3>(string name, T2 a, T3 b) => throw null;
    public virtual string MyVirtualMethod() => string.Empty;
  }
  public class Second : FirstBase
  {
    public new void MyMethod() { }
    public new string MyMethodWithParams(string a, int b, FirstBase c) => string.Empty;
    public new T MyGenericMethod<T, T2, T3>(string name, T2 a, T3 b) => throw null;
    public override string MyVirtualMethod() => string.Empty;
  }
}
";

            IAssemblySymbol left   = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right  = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiComparer     differ = new();

            differ.StrictMode = true;
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            Assert.Empty(differences);
        }
コード例 #30
0
        public void AddedMembersAreReported()
        {
            string          leftSyntax  = @"
namespace CompatTests
{
  public interface IFoo
  {
  }
}
";
            string          rightSyntax = @"
namespace CompatTests
{
  public interface IFoo
  {
    string MyMethod();
    byte MyPropertyWithoutDefaultImplementation { get; set; }
    event System.EventHandler MyEventWithoutImplementation;

    // .NET Framework doesn't support default implementations.
#if !NETFRAMEWORK
    static int MyField = 2;
    event System.EventHandler MyEvent { add { } remove { } }
    int MyPropertyWithDefaultImplementation { get => 0; set { } }
#endif
  }
}
";
            IAssemblySymbol left        = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right       = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            ApiComparer differ = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            CompatDifference[] expected = new[]
            {
                new CompatDifference(DiagnosticIds.CannotAddMemberToInterface, string.Empty, DifferenceType.Added, "M:CompatTests.IFoo.MyMethod"),
                new CompatDifference(DiagnosticIds.CannotAddMemberToInterface, string.Empty, DifferenceType.Added, "P:CompatTests.IFoo.MyPropertyWithoutDefaultImplementation"),
                new CompatDifference(DiagnosticIds.CannotAddMemberToInterface, string.Empty, DifferenceType.Added, "E:CompatTests.IFoo.MyEventWithoutImplementation"),
            };

            Assert.Equal(expected, differences);
        }