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); } }
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); }
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 })); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } }
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)); }
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()); }
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); }
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); }
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 _)); }
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); }
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); }
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); }
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)); }
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)); }
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); }
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); } }
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); }
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); }
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); } }
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); }