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));
        }
        public void LoadMatchingAssemblies_DifferentIdentity(bool validateIdentities)
        {
            var             assetInfo    = GetSimpleTestAsset();
            IAssemblySymbol fromAssembly = SymbolFactory.GetAssemblyFromSyntax(SimpleAssemblySourceContents, assemblyName: assetInfo.TestAsset.TestProject.Name);

            AssemblySymbolLoader          loader             = new();
            IEnumerable <IAssemblySymbol> matchingAssemblies = loader.LoadMatchingAssemblies(new[] { fromAssembly }, new[] { assetInfo.OutputDirectory }, validateMatchingIdentity: validateIdentities);

            if (validateIdentities)
            {
                Assert.Empty(matchingAssemblies);
                Assert.True(loader.HasLoadWarnings(out IEnumerable <AssemblyLoadWarning> warnings));

                IEnumerable <AssemblyLoadWarning> expected = new[]
                {
                    new AssemblyLoadWarning(DiagnosticIds.AssemblyNotFound, fromAssembly.Identity.GetDisplayName(), $"Could not find matching assembly: '{fromAssembly.Identity.GetDisplayName()}' in any of the search directories.")
                };

                Assert.Equal(expected, warnings);
            }
            else
            {
                Assert.Single(matchingAssemblies);
                Assert.False(loader.HasLoadWarnings(out var _));
                Assert.NotEqual(fromAssembly.Identity, matchingAssemblies.FirstOrDefault().Identity);
            }
        }
Beispiel #3
0
        public void CustomSideNameAreNotSpecified()
        {
            string leftSyntax = @"

namespace CompatTests
{
  public class First { }
  public class Second { }
}
";

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

            ApiComparer     differ                     = new();
            bool            enableNullable             = false;
            IAssemblySymbol left                       = SymbolFactory.GetAssemblyFromSyntax(leftSyntax, enableNullable);
            IAssemblySymbol right                      = SymbolFactory.GetAssemblyFromSyntax(rightSyntax, enableNullable);
            string          expectedLeftName           = "left";
            string          expectedRightName          = "right";
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            Assert.Single(differences);
            AssertNames(differences.First(), expectedLeftName, expectedRightName);
        }
Beispiel #4
0
        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);
        }
        public void NoDifferencesReportedWithNoWarn()
        {
            string leftSyntax = @"
namespace CompatTests
{
  public class First { }
}
";

            string rightSyntax = @"

namespace CompatTests
{
  public class First { }
  public class Second { }
}
";

            ApiComparer differ = new();

            differ.StrictMode = true;
            differ.NoWarn     = DiagnosticIds.TypeMustExist;
            IAssemblySymbol left  = SymbolFactory.GetAssemblyFromSyntax(leftSyntax);
            IAssemblySymbol right = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);

            Assert.Empty(differ.GetDifferences(new[] { left }, new[] { right }));
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
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);
        }
Beispiel #10
0
        public void TypeInDifferentNamespaces()
        {
            string          leftSyntax                 = @"
namespace A.B
{
  public class C { }
}
";
            string          rightSyntax                = @"
namespace B.B
{
  public class C { }
}
";
            ApiComparer     differ                     = new();
            bool            enableNullable             = false;
            IAssemblySymbol left                       = SymbolFactory.GetAssemblyFromSyntax(leftSyntax, enableNullable);
            IAssemblySymbol right                      = SymbolFactory.GetAssemblyFromSyntax(rightSyntax, enableNullable);
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

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

            Assert.Equal(expected, differences, CompatDifferenceComparer.Default);
        }
Beispiel #11
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);
            ApiComparer     differ = new();

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

            Assert.Empty(differences);
        }
Beispiel #12
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);
            }
        }
Beispiel #13
0
        public void RetargetableFlagSet(bool strictMode)
        {
            string syntax = @"
using System.Reflection;

[assembly: AssemblyFlags(AssemblyNameFlags.Retargetable)]
";

            // Emitting the assembly to a physical location to workaround:
            // https://github.com/dotnet/roslyn/issues/54836
            string leftAssembly  = SymbolFactory.EmitAssemblyFromSyntax(syntax, publicKey: _publicKey);
            string rightAssembly = SymbolFactory.EmitAssemblyFromSyntax(syntax);

            IAssemblySymbol leftSymbol  = new AssemblySymbolLoader().LoadAssembly(leftAssembly);
            IAssemblySymbol rightSymbol = new AssemblySymbolLoader().LoadAssembly(rightAssembly);

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

            ApiComparer differ = new();

            differ.StrictMode = strictMode;

            Assert.Empty(differ.GetDifferences(leftSymbol, rightSymbol));
        }
Beispiel #14
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());
        }
Beispiel #15
0
        public void CustomSideNamesAreUsedStrictMode()
        {
            string leftSyntax = @"

namespace CompatTests
{
  public class First { }
}
";

            string rightSyntax = @"
namespace CompatTests
{
  public class First
  {
    public string Method1() => string.Empty;
  }
}
";

            ApiComparer     differ            = new();
            bool            enableNullable    = false;
            IAssemblySymbol left              = SymbolFactory.GetAssemblyFromSyntax(leftSyntax, enableNullable);
            IAssemblySymbol right             = SymbolFactory.GetAssemblyFromSyntax(rightSyntax, enableNullable);
            string          expectedLeftName  = "ref/net6.0/a.dll";
            string          expectedRightName = "lib/net6.0/a.dll";

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

            Assert.Single(differences);
            AssertNames(differences.First(), expectedLeftName, expectedRightName, leftFirst: false);
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        public void LoadMatchingAssembliesSameIdentitySucceeds()
        {
            string          assemblyName = nameof(LoadMatchingAssembliesSameIdentitySucceeds);
            IAssemblySymbol fromAssembly = SymbolFactory.GetAssemblyFromSyntax(SimpleAssemblySourceContents, assemblyName: assemblyName);

            TestProject testProject = new(assemblyName)
            {
                TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
                IsExe            = false,
            };

            testProject.SourceFiles.Add("MyClass.cs", SimpleAssemblySourceContents);
            testProject.AdditionalProperties.Add("AssemblyVersion", "0.0.0.0");
            TestAsset testAsset = _testAssetsManager.CreateTestProject(testProject);

            BuildTestAsset(testAsset, out string outputDirectory)
            .Should()
            .Pass();

            AssemblySymbolLoader          loader             = new();
            IEnumerable <IAssemblySymbol> matchingAssemblies = loader.LoadMatchingAssemblies(new[] { fromAssembly }, new[] { outputDirectory });

            Assert.Single(matchingAssemblies);
            Assert.False(loader.HasLoadWarnings(out var _));
        }
Beispiel #18
0
        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 }, includeDefaultReferences: true);
            IAssemblySymbol right       = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiDiffer       differ      = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(new[] { left }, new[] { right });

            CompatDifference[] expected = new[]
            {
                new CompatDifference(DiagnosticIds.TypeMustExist, $"Type 'CompatTests.ForwardedTestType' exists on the contract but not on the implementation", DifferenceType.Removed, "T:CompatTests.ForwardedTestType")
            };

            Assert.Equal(expected, differences);
        }
Beispiel #19
0
        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);
        }
Beispiel #20
0
        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, includeDefaultReferences: true);
            IAssemblySymbol right       = SymbolFactory.GetAssemblyFromSyntax(rightSyntax);
            ApiComparer     differ      = new();
            IEnumerable <CompatDifference> differences = differ.GetDifferences(left, right);

            Assert.Empty(differences);
        }
Beispiel #21
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);
        }
        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));
        }
Beispiel #23
0
        public void LoadMatchingAssemblies_Throws()
        {
            AssemblySymbolLoader loader   = new();
            IEnumerable <string> paths    = new[] { Guid.NewGuid().ToString("N") };
            IAssemblySymbol      assembly = SymbolFactory.GetAssemblyFromSyntax("namespace MyNamespace { class Foo { } }");

            Assert.Throws <FileNotFoundException>(() => loader.LoadMatchingAssemblies(new[] { assembly }, paths));
            Assert.Throws <ArgumentNullException>("fromAssemblies", () => loader.LoadMatchingAssemblies(null, paths));
            Assert.Throws <ArgumentNullException>("searchPaths", () => loader.LoadMatchingAssemblies(Array.Empty <IAssemblySymbol>(), null));
        }
Beispiel #24
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);
        }
Beispiel #25
0
        public void AddedToUnsealedTypeInRightNotReported(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);
        }
        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, CompatDifferenceComparer.Default);
            }
            else
            {
                Assert.Empty(differences);
            }
        }
Beispiel #27
0
        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);
        }
Beispiel #28
0
        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);
        }
Beispiel #29
0
        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);
            }
        }
Beispiel #30
0
        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);
        }