public void NestedTypeTests() { var assembly = AssemblyData.FromAssembly(typeof(ChangedAccessibilityFromPublicToProtectedTests).Assembly); var nestedDerivedFromBase = TypeDefinitionData.FromType(typeof(NestedDerivedFromBase)); var nestedDerivedFromSpecializedBase = TypeDefinitionData.FromType(typeof(NestedDerivedFromSpecializedBase)); var nestedDerivedFromOtherBase = TypeDefinitionData.FromType(typeof(NestedDerivedFromOtherBase)); var breakingChanges = MetadataComparer.CompareTypes(nestedDerivedFromBase, nestedDerivedFromSpecializedBase); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when the new type derives from a more specialized base class."); breakingChanges = MetadataComparer.CompareTypes(nestedDerivedFromBase, nestedDerivedFromOtherBase); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the new type derives from a different base class."); Assert.AreEqual(BreakingChangeKind.IncompatibleClassHierarchy, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(nestedDerivedFromBase.GetNestedType("Class"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(nestedDerivedFromOtherBase.GetNestedType("Class"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(nestedDerivedFromSpecializedBase, nestedDerivedFromBase); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the new type derives from a less specialized base class."); Assert.AreEqual(BreakingChangeKind.IncompatibleClassHierarchy, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(nestedDerivedFromSpecializedBase.GetNestedType("Class"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(nestedDerivedFromBase.GetNestedType("Class"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(nestedDerivedFromSpecializedBase, nestedDerivedFromOtherBase); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the new type derives from a different base class."); Assert.AreEqual(BreakingChangeKind.IncompatibleClassHierarchy, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(nestedDerivedFromSpecializedBase.GetNestedType("Class"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(nestedDerivedFromOtherBase.GetNestedType("Class"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void GenericParameterRenameTest() { var context = MetadataResolutionContext.CreateFromTypes(typeof(MiscellaneousTests)); var typeData1 = context.GetTypeDefinitionData(typeof(GenericParameter1 <>)); var typeData2 = context.GetTypeDefinitionData(typeof(GenericParameter2 <>)); var typeData3 = context.GetTypeDefinitionData(typeof(GenericParameter3 <,>)); var typeData4 = context.GetTypeDefinitionData(typeof(GenericParameter4 <,>)); var breakingChanges = MetadataComparer.CompareTypes(typeData1, typeData2); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes for renaming a class's generic type parameter."); breakingChanges = MetadataComparer.CompareTypes(typeData3, typeData4); AssertX.Equal(1, breakingChanges.Count, "There should be a breaking changes for using a different generic type parameter position as a return type."); AssertX.Equal(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "There should be a breaking changes for using a different generic type parameter position as a return type."); typeData1 = context.GetTypeDefinitionData(typeof(GenericMethodParameter1)); typeData2 = context.GetTypeDefinitionData(typeof(GenericMethodParameter2)); typeData3 = context.GetTypeDefinitionData(typeof(GenericMethodParameter3)); typeData4 = context.GetTypeDefinitionData(typeof(GenericMethodParameter4)); breakingChanges = MetadataComparer.CompareTypes(typeData1, typeData2); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes for renaming a class's generic type parameter."); breakingChanges = MetadataComparer.CompareTypes(typeData3, typeData4); AssertX.Equal(1, breakingChanges.Count, "There should be a breaking changes for using a different generic type parameter position as a return type."); AssertX.Equal(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "There should be a breaking changes for using a different generic type parameter position as a return type."); }
public void NestedTypeTests() { var assembly = AssemblyData.FromAssembly(typeof(ChangedClassToStaticTests).Assembly); var NestedClass = TypeDefinitionData.FromType(typeof(NestedClass)); var NestedClassWithInternalConstructor = TypeDefinitionData.FromType(typeof(NestedClassWithInternalConstructor)); var NestedClassWithProtectedConstructor = TypeDefinitionData.FromType(typeof(NestedClassWithProtectedConstructor)); var NestedStaticClass = TypeDefinitionData.FromType(typeof(NestedStaticClass)); var breakingChanges = MetadataComparer.CompareTypes(NestedClass, NestedStaticClass).Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedClassToStatic).ToList(); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when a class is made static."); Assert.AreEqual(BreakingChangeKind.ChangedClassToStatic, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(NestedClass.GetMember("Class"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(NestedStaticClass.GetMember("Class"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(NestedClassWithInternalConstructor, NestedStaticClass); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when a class with no public constructors is made abstract."); breakingChanges = MetadataComparer.CompareTypes(NestedClassWithProtectedConstructor, NestedStaticClass).Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedClassToStatic).ToList(); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when a class is made static."); Assert.AreEqual(BreakingChangeKind.ChangedClassToStatic, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(NestedClassWithProtectedConstructor.GetMember("Class"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(NestedStaticClass.GetMember("Class"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void ConstructorTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(ChangedAccessibilityFromPublicToProtectedTests)); var publicConstructor = context.GetTypeDefinitionData(typeof(PublicConstructor)); var protectedConstructor = context.GetTypeDefinitionData(typeof(ProtectedConstructor)); var protectedInternalConstructor = context.GetTypeDefinitionData(typeof(ProtectedInternalConstructor)); var breakingChanges = MetadataComparer.CompareTypes(publicConstructor, protectedConstructor); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when a constant is changed from public to protected"); AssertX.Equal(BreakingChangeKind.ChangedAccessibilityFromPublicToProtected, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(context.GetTypeDefinitionData(typeof(PublicConstructor)).GetMembers(".ctor")[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(context.GetTypeDefinitionData(typeof(ProtectedConstructor)).GetMembers(".ctor")[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(publicConstructor, protectedInternalConstructor); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when a constructor is changed from public to protected internal"); AssertX.Equal(BreakingChangeKind.ChangedAccessibilityFromPublicToProtected, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(context.GetTypeDefinitionData(typeof(PublicConstructor)).GetMembers(".ctor")[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(context.GetTypeDefinitionData(typeof(ProtectedInternalConstructor)).GetMembers(".ctor")[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(protectedConstructor, publicConstructor); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when a constructor is changed from protected to public"); breakingChanges = MetadataComparer.CompareTypes(protectedConstructor, protectedInternalConstructor); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when a constructor is changed from protected to protected internal"); breakingChanges = MetadataComparer.CompareTypes(protectedInternalConstructor, publicConstructor); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when a constructor is changed from protected internal to public"); breakingChanges = MetadataComparer.CompareTypes(protectedInternalConstructor, protectedConstructor); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when a constructor is changed from protected internal to protected"); }
public void ConstantTests() { var assembly = AssemblyData.FromAssembly(typeof(ChangedAccessibilityFromPublicToProtectedTests).Assembly); var publicConstant = TypeDefinitionData.FromType(typeof(PublicConstant)); var protectedConstant = TypeDefinitionData.FromType(typeof(ProtectedConstant)); var protectedInternalConstant = TypeDefinitionData.FromType(typeof(ProtectedInternalConstant)); var breakingChanges = MetadataComparer.CompareTypes(publicConstant, protectedConstant); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when a constant is changed from public to protected"); Assert.AreEqual(BreakingChangeKind.ChangedAccessibilityFromPublicToProtected, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(TypeDefinitionData.FromType(typeof(PublicConstant)).GetMember("Constant"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(TypeDefinitionData.FromType(typeof(ProtectedConstant)).GetMember("Constant"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(publicConstant, protectedInternalConstant); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when a constant is changed from public to protected internal"); Assert.AreEqual(BreakingChangeKind.ChangedAccessibilityFromPublicToProtected, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(TypeDefinitionData.FromType(typeof(PublicConstant)).GetMember("Constant"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(TypeDefinitionData.FromType(typeof(ProtectedInternalConstant)).GetMember("Constant"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(protectedConstant, publicConstant); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when a constant is changed from protected to public"); breakingChanges = MetadataComparer.CompareTypes(protectedConstant, protectedInternalConstant); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when a constant is changed from protected to protected internal"); breakingChanges = MetadataComparer.CompareTypes(protectedInternalConstant, publicConstant); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when a constant is changed from protected internal to public"); breakingChanges = MetadataComparer.CompareTypes(protectedInternalConstant, protectedConstant); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when a constant is changed from protected internal to protected"); }
public void MethodTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(AddedAbstractMemberTests)); var MethodNonVirtual = context.GetTypeDefinitionData(typeof(MethodNonVirtual)); var MethodVirtual = context.GetTypeDefinitionData(typeof(MethodVirtual)); var MethodAbstract = context.GetTypeDefinitionData(typeof(MethodAbstract)); var breakingChanges = MetadataComparer.CompareTypes(MethodVirtual, MethodNonVirtual); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when a virtual member changes to non-virtual."); AssertX.Equal(BreakingChangeKind.ChangedMemberToNonVirtual, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(MethodVirtual.GetMember("Method"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(MethodNonVirtual.GetMember("Method"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(MethodAbstract, MethodNonVirtual); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when an abstract member changes to non-virtual."); AssertX.Equal(BreakingChangeKind.ChangedMemberToNonVirtual, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(MethodAbstract.GetMember("Method"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(MethodNonVirtual.GetMember("Method"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(MethodNonVirtual, MethodVirtual); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when a non-virtual member changes to virtual."); }
public void MethodTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(RemovedOverrideOfAbstractMemberTests)); var MethodVirtual = context.GetTypeDefinitionData(typeof(MethodVirtual)); var MethodAbstract = context.GetTypeDefinitionData(typeof(MethodAbstract)); var MethodVirtualOverride = context.GetTypeDefinitionData(typeof(MethodVirtualOverride)); var MethodAbstractOverride = context.GetTypeDefinitionData(typeof(MethodAbstractOverride)); var MethodVirtualOverrideInternalConstructor = context.GetTypeDefinitionData(typeof(MethodVirtualOverrideInternalConstructor)); var MethodAbstractOverrideInternalConstructor = context.GetTypeDefinitionData(typeof(MethodAbstractOverrideInternalConstructor)); var MethodVirtualNoOverride = context.GetTypeDefinitionData(typeof(MethodVirtualNoOverride)); var MethodAbstractNoOverride = context.GetTypeDefinitionData(typeof(MethodAbstractNoOverride)); var breakingChanges = MetadataComparer.CompareTypes(MethodVirtualOverride, MethodVirtualNoOverride); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when an override of a virtual member is removed."); breakingChanges = MetadataComparer.CompareTypes(MethodVirtualOverrideInternalConstructor, MethodVirtualNoOverride); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when an override of a virtual member is removed and there are no externally visible constructors."); breakingChanges = MetadataComparer.CompareTypes(MethodAbstractOverride, MethodAbstractNoOverride); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when an override of an abstract member is removed."); AssertX.Equal(BreakingChangeKind.RemovedOverrideOfAbstractMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(MethodAbstractOverride.GetMember("Method"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Null(breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(MethodAbstractNoOverride, breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(MethodAbstractOverrideInternalConstructor, MethodAbstractNoOverride); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when an override of an abstract member is removed and there are no externally visible constructors."); }
public void IndexerTests() { var assembly = AssemblyData.FromAssembly(typeof(RemovedOverrideOfAbstractMemberTests).Assembly); var IndexerVirtual = TypeDefinitionData.FromType(typeof(IndexerVirtual)); var IndexerAbstract = TypeDefinitionData.FromType(typeof(IndexerAbstract)); var IndexerVirtualOverride = TypeDefinitionData.FromType(typeof(IndexerVirtualOverride)); var IndexerAbstractOverride = TypeDefinitionData.FromType(typeof(IndexerAbstractOverride)); var IndexerVirtualOverrideInternalConstructor = TypeDefinitionData.FromType(typeof(IndexerVirtualOverrideInternalConstructor)); var IndexerAbstractOverrideInternalConstructor = TypeDefinitionData.FromType(typeof(IndexerAbstractOverrideInternalConstructor)); var IndexerVirtualNoOverride = TypeDefinitionData.FromType(typeof(IndexerVirtualNoOverride)); var IndexerAbstractNoOverride = TypeDefinitionData.FromType(typeof(IndexerAbstractNoOverride)); var breakingChanges = MetadataComparer.CompareTypes(IndexerVirtualOverride, IndexerVirtualNoOverride); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when an override of a virtual member is removed."); breakingChanges = MetadataComparer.CompareTypes(IndexerVirtualOverrideInternalConstructor, IndexerVirtualNoOverride); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when an override of a virtual member is removed and there are no externally visible constructors."); breakingChanges = MetadataComparer.CompareTypes(IndexerAbstractOverride, IndexerAbstractNoOverride); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when an override of an abstract member is removed."); Assert.AreEqual(BreakingChangeKind.RemovedOverrideOfAbstractMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(IndexerAbstractOverride.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.IsNull(breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(IndexerAbstractNoOverride, breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerAbstractOverrideInternalConstructor, IndexerAbstractNoOverride); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when an override of an abstract member is removed and there are no externally visible constructors."); }
public void GenericParameterRenameTest() { var assembly = AssemblyData.FromAssembly(typeof(MiscellaneousTests).Assembly); var typeData1 = TypeDefinitionData.FromType(typeof(GenericParameter1 <>)); var typeData2 = TypeDefinitionData.FromType(typeof(GenericParameter2 <>)); var typeData3 = TypeDefinitionData.FromType(typeof(GenericParameter3 <,>)); var typeData4 = TypeDefinitionData.FromType(typeof(GenericParameter4 <,>)); var breakingChanges = MetadataComparer.CompareTypes(typeData1, typeData2); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes for renaming a class's generic type parameter."); breakingChanges = MetadataComparer.CompareTypes(typeData3, typeData4); Assert.AreEqual(1, breakingChanges.Count, "There should be a breaking changes for using a different generic type parameter position as a return type."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "There should be a breaking changes for using a different generic type parameter position as a return type."); typeData1 = TypeDefinitionData.FromType(typeof(GenericMethodParameter1)); typeData2 = TypeDefinitionData.FromType(typeof(GenericMethodParameter2)); typeData3 = TypeDefinitionData.FromType(typeof(GenericMethodParameter3)); typeData4 = TypeDefinitionData.FromType(typeof(GenericMethodParameter4)); breakingChanges = MetadataComparer.CompareTypes(typeData1, typeData2); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes for renaming a class's generic type parameter."); breakingChanges = MetadataComparer.CompareTypes(typeData3, typeData4); Assert.AreEqual(1, breakingChanges.Count, "There should be a breaking changes for using a different generic type parameter position as a return type."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "There should be a breaking changes for using a different generic type parameter position as a return type."); }
public void TestProofOfConceptScenario() { var examineeAssemblyReference = new FileSystemAssemblyReference( @"C:\Src\Tfs\MobiControl\Common\DeploymentServerExtensions.Facade\v1\DeploymentServerExtensions.Facade\bin\Debug\Soti.MobiControl.DeploymentServerExtensions.Facade.dll"); var comparandAssemblyPaths = new[] { @"C:\Src\Tfs\MobiControl\DEV\MobiControl\Lib\Soti.MobiControl.Entities.dll", @"C:\Src\Tfs\MobiControl\DEV\MobiControl\Lib\Soti.MobiControl.Api.dll", @"C:\Src\Tfs\MobiControl\DEV\MobiControl\Lib\Soti.MobiControl.CoreFeatures.dll", @"C:\Src\Tfs\MobiControl\DEV\MobiControl\Lib\Soti.MobiControl.DeviceConfiguration.dll", @"C:\Src\Tfs\MobiControl\DEV\MobiControl\Lib\Soti.MobiControl.Entities.Providers.dll", @"C:\Src\Tfs\MobiControl\DEV\MobiControl\Lib\Soti.MobiControl.WindowsModern.Service.dll", @"C:\Src\Tfs\MobiControl\DEV\MobiControl\Lib\Soti.MobiControl.DeploymentServerExtensions.dll" }; var comparandAssemblyReferences = comparandAssemblyPaths .Select(path => new FileSystemAssemblyReference(path)) .ToArray(); var dependencyReferences = new DependencyReference[] { new DirectoryDependencyReference(@"C:\Src\Tfs\MobiControl\DEV\MobiControl\Packages", true) }; var parameters = new MetadataComparisonParameters(dependencyReferences: dependencyReferences); var comparer = new MetadataComparer(examineeAssemblyReference, comparandAssemblyReferences, parameters); var comparisonResult = comparer.Compare(); Assert.That(comparisonResult, Is.Not.Null); }
public void SerializeDeserializePropertyContainer() { var initialContainer = CreateTestContainer(); var propertyContainerContract = initialContainer.ToContract(new DefaultMapperSettings()); propertyContainerContract.Should().NotBeNull(); var contractJson = propertyContainerContract.ToJsonWithSystemTextJson(); var json1 = initialContainer.ToJsonWithSystemTextJson(); var jsonOptions = new JsonSerializerOptions().ConfigureJsonOptions(); DeserializeAndCompare <IPropertyContainer>(); DeserializeAndCompare <PropertyContainer>(); DeserializeAndCompare <IMutablePropertyContainer>(); DeserializeAndCompare <MutablePropertyContainer>(); DeserializeAndCompare <PropertyContainer <TestMeta> >(); var json2 = initialContainer.ToJsonWithNewtonsoftJson(); var container2 = json2.DeserializeWithNewtonsoftJson <IPropertyContainer>(); ObjectDiff objectDiff = MetadataComparer.GetDiff(initialContainer, container2); objectDiff.Diffs.Should().BeEmpty(); void DeserializeAndCompare <TContainer>() where TContainer : IPropertyContainer { TContainer?restored = JsonSerializer.Deserialize <TContainer>(json1, jsonOptions); ObjectDiff objectDiff = MetadataComparer.GetDiff(restored, initialContainer); objectDiff.Diffs.Should().BeEmpty(); } }
public void TypeTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(ChangedAccessibilityFromPublicToProtectedTests)); var derivedFromBase = context.GetTypeDefinitionData(typeof(DerivedFromBase)); var derivedFromSpecializedBase = context.GetTypeDefinitionData(typeof(DerivedFromSpecializedBase)); var derivedFromOtherBase = context.GetTypeDefinitionData(typeof(DerivedFromOtherBase)); var breakingChanges = MetadataComparer.CompareTypes(derivedFromBase, derivedFromSpecializedBase); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when the new type derives from a more specialized base class."); breakingChanges = MetadataComparer.CompareTypes(derivedFromBase, derivedFromOtherBase); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the new type derives from a different base class."); AssertX.Equal(BreakingChangeKind.IncompatibleClassHierarchy, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(derivedFromBase, breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(derivedFromOtherBase, breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(derivedFromSpecializedBase, derivedFromBase); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the new type derives from a less specialized base class."); AssertX.Equal(BreakingChangeKind.IncompatibleClassHierarchy, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(derivedFromSpecializedBase, breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(derivedFromBase, breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(derivedFromSpecializedBase, derivedFromOtherBase); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the new type derives from a different base class."); AssertX.Equal(BreakingChangeKind.IncompatibleClassHierarchy, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(derivedFromSpecializedBase, breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(derivedFromOtherBase, breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void TypeTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(ChangedClassToStaticTests)); var Class = context.GetTypeDefinitionData(typeof(Class)); var ClassWithInternalConstructor = context.GetTypeDefinitionData(typeof(ClassWithInternalConstructor)); var ClassWithProtectedConstructor = context.GetTypeDefinitionData(typeof(ClassWithProtectedConstructor)); var StaticClass = context.GetTypeDefinitionData(typeof(StaticClass)); var breakingChanges = MetadataComparer.CompareTypes(Class, StaticClass).Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedClassToStatic).ToList(); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when a class is made static."); AssertX.Equal(BreakingChangeKind.ChangedClassToStatic, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(Class, breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(StaticClass, breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(ClassWithInternalConstructor, StaticClass); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when a class with no public constructors is made abstract."); breakingChanges = MetadataComparer.CompareTypes(ClassWithProtectedConstructor, StaticClass).Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedClassToStatic).ToList(); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when a class is made static."); AssertX.Equal(BreakingChangeKind.ChangedClassToStatic, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(ClassWithProtectedConstructor, breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(StaticClass, breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void IndexerTests() { var assembly = AssemblyData.FromAssembly(typeof(AddedAbstractMemberTests).Assembly); var IndexerNonVirtual = TypeDefinitionData.FromType(typeof(IndexerNonVirtual)); var IndexerVirtual = TypeDefinitionData.FromType(typeof(IndexerVirtual)); var IndexerAbstract = TypeDefinitionData.FromType(typeof(IndexerAbstract)); var breakingChanges = MetadataComparer.CompareTypes(IndexerVirtual, IndexerNonVirtual); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when a virtual member changes to non-virtual."); Assert.AreEqual(BreakingChangeKind.ChangedMemberToNonVirtual, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(IndexerVirtual.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(IndexerNonVirtual.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerAbstract, IndexerNonVirtual); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when an abstract member changes to non-virtual."); Assert.AreEqual(BreakingChangeKind.ChangedMemberToNonVirtual, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(IndexerAbstract.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(IndexerNonVirtual.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerNonVirtual, IndexerVirtual); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when a non-virtual member changes to virtual."); }
public void ReadWithSchemaFirst() { string json = @"{ 'StringProperty': 'Text', 'IntProperty': 42, 'DoubleProperty': 10.2, 'NullableIntProperty': null, 'BoolProperty': true, 'DateProperty': '2020-12-26', 'StringArray':['a1','a2'], 'IntArray':[1,2], '$metadata.schema.compact': [ 'StringProperty@type=string', 'IntProperty@type=int', 'DoubleProperty@type=double', 'NullableIntProperty@type=int?', 'BoolProperty @type = bool', 'DateProperty@type=LocalDate', 'StringArray@type=string[]', 'IntArray@type=int[]' ] }"; var initialContainer = CreateTestContainer(); var restoredContainer = json.DeserializeWithNewtonsoftJson <IPropertyContainer>(configureSerialization: options => options.ReadSchemaFirst = true); ObjectDiff objectDiff = MetadataComparer.GetDiff(restoredContainer, initialContainer); objectDiff.Diffs.Should().BeEmpty(); // container will lose types var restoredContainer2 = json.DeserializeWithNewtonsoftJson <IPropertyContainer>(configureSerialization: options => options.ReadSchemaFirst = false); ObjectDiff objectDiff2 = MetadataComparer.GetDiff(restoredContainer2, initialContainer); objectDiff2.Diffs.Should().NotBeNullOrEmpty(); }
public void OperatorTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(ChangedParameterNameTests)); var OperatorWithOldParameterName = context.GetTypeDefinitionData(typeof(OperatorWithOldParameterName)); var OperatorWithNewParameterName = context.GetTypeDefinitionData(typeof(OperatorWithNewParameterName)); var breakingChanges = MetadataComparer.CompareTypes(OperatorWithOldParameterName, OperatorWithNewParameterName); AssertX.Equal(0, breakingChanges.Count, "There should be one breaking change when the parameter name changes."); }
public void OperatorTests() { var assembly = AssemblyData.FromAssembly(typeof(ChangedParameterNameTests).Assembly); var OperatorWithOldParameterName = TypeDefinitionData.FromType(typeof(OperatorWithOldParameterName)); var OperatorWithNewParameterName = TypeDefinitionData.FromType(typeof(OperatorWithNewParameterName)); var breakingChanges = MetadataComparer.CompareTypes(OperatorWithOldParameterName, OperatorWithNewParameterName); Assert.AreEqual(0, breakingChanges.Count, "There should be one breaking change when the parameter name changes."); }
public void EventTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(SealedMemberTests)); var EventVirtual = context.GetTypeDefinitionData(typeof(EventVirtual)); var EventAbstract = context.GetTypeDefinitionData(typeof(EventAbstract)); var EventVirtualOverride = context.GetTypeDefinitionData(typeof(EventVirtualOverride)); var EventAbstractOverride = context.GetTypeDefinitionData(typeof(EventAbstractOverride)); var EventVirtualNoOverride = context.GetTypeDefinitionData(typeof(EventVirtualNoOverride)); var EventAbstractNoOverride = context.GetTypeDefinitionData(typeof(EventAbstractNoOverride)); var EventVirtualSealedOverride = context.GetTypeDefinitionData(typeof(EventVirtualSealedOverride)); var EventAbstractSealedOverride = context.GetTypeDefinitionData(typeof(EventAbstractSealedOverride)); var EventVirtualSealedOverrideSealed = context.GetTypeDefinitionData(typeof(EventVirtualSealedOverrideSealed)); var EventAbstractSealedOverrideSealed = context.GetTypeDefinitionData(typeof(EventAbstractSealedOverrideSealed)); var breakingChanges = MetadataComparer.CompareTypes(EventVirtualOverride, EventVirtualSealedOverride); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when a sealed override is added to an unsealed class."); AssertX.Equal(BreakingChangeKind.SealedMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(EventVirtualOverride.GetMember("Event"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(EventVirtualSealedOverride.GetMember("Event"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(EventVirtualOverride, EventVirtualSealedOverrideSealed); AssertX.Equal(1, breakingChanges.Count, "There should be no breaking changes when a sealed override is added to a sealed class."); breakingChanges = MetadataComparer.CompareTypes(EventAbstractOverride, EventAbstractSealedOverride); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when a sealed override is added to an unsealed class."); AssertX.Equal(BreakingChangeKind.SealedMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(EventAbstractOverride.GetMember("Event"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(EventAbstractSealedOverride.GetMember("Event"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(EventAbstractOverride, EventAbstractSealedOverrideSealed); AssertX.Equal(1, breakingChanges.Count, "There should be no breaking changes when a sealed override is added to a sealed class."); breakingChanges = MetadataComparer.CompareTypes(EventVirtualNoOverride, EventVirtualSealedOverride); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when a sealed override is added to an unsealed class."); AssertX.Equal(BreakingChangeKind.SealedMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(EventVirtual.GetMember("Event"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(EventVirtualSealedOverride.GetMember("Event"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(EventVirtualNoOverride, EventVirtualSealedOverrideSealed); AssertX.Equal(1, breakingChanges.Count, "There should be no breaking changes when a sealed override is added to a sealed class."); breakingChanges = MetadataComparer.CompareTypes(EventAbstractNoOverride, EventAbstractSealedOverride); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when a sealed override is added to an unsealed class."); AssertX.Equal(BreakingChangeKind.SealedMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(EventAbstract.GetMember("Event"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(EventAbstractSealedOverride.GetMember("Event"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(EventAbstractNoOverride, EventAbstractSealedOverrideSealed); AssertX.Equal(1, breakingChanges.Count, "There should be no breaking changes when a sealed override is added to a sealed class."); }
public void IndexerTests() { var assembly = AssemblyData.FromAssembly(typeof(SealedMemberTests).Assembly); var IndexerVirtual = TypeDefinitionData.FromType(typeof(IndexerVirtual)); var IndexerAbstract = TypeDefinitionData.FromType(typeof(IndexerAbstract)); var IndexerVirtualOverride = TypeDefinitionData.FromType(typeof(IndexerVirtualOverride)); var IndexerAbstractOverride = TypeDefinitionData.FromType(typeof(IndexerAbstractOverride)); var IndexerVirtualNoOverride = TypeDefinitionData.FromType(typeof(IndexerVirtualNoOverride)); var IndexerAbstractNoOverride = TypeDefinitionData.FromType(typeof(IndexerAbstractNoOverride)); var IndexerVirtualSealedOverride = TypeDefinitionData.FromType(typeof(IndexerVirtualSealedOverride)); var IndexerAbstractSealedOverride = TypeDefinitionData.FromType(typeof(IndexerAbstractSealedOverride)); var IndexerVirtualSealedOverrideSealed = TypeDefinitionData.FromType(typeof(IndexerVirtualSealedOverrideSealed)); var IndexerAbstractSealedOverrideSealed = TypeDefinitionData.FromType(typeof(IndexerAbstractSealedOverrideSealed)); var breakingChanges = MetadataComparer.CompareTypes(IndexerVirtualOverride, IndexerVirtualSealedOverride); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when a sealed override is added to an unsealed class."); Assert.AreEqual(BreakingChangeKind.SealedMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(IndexerVirtualOverride.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(IndexerVirtualSealedOverride.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerVirtualOverride, IndexerVirtualSealedOverrideSealed); Assert.AreEqual(1, breakingChanges.Count, "There should be no breaking changes when a sealed override is added to a sealed class."); breakingChanges = MetadataComparer.CompareTypes(IndexerAbstractOverride, IndexerAbstractSealedOverride); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when a sealed override is added to an unsealed class."); Assert.AreEqual(BreakingChangeKind.SealedMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(IndexerAbstractOverride.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(IndexerAbstractSealedOverride.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerAbstractOverride, IndexerAbstractSealedOverrideSealed); Assert.AreEqual(1, breakingChanges.Count, "There should be no breaking changes when a sealed override is added to a sealed class."); breakingChanges = MetadataComparer.CompareTypes(IndexerVirtualNoOverride, IndexerVirtualSealedOverride); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when a sealed override is added to an unsealed class."); Assert.AreEqual(BreakingChangeKind.SealedMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(IndexerVirtual.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(IndexerVirtualSealedOverride.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerVirtualNoOverride, IndexerVirtualSealedOverrideSealed); Assert.AreEqual(1, breakingChanges.Count, "There should be no breaking changes when a sealed override is added to a sealed class."); breakingChanges = MetadataComparer.CompareTypes(IndexerAbstractNoOverride, IndexerAbstractSealedOverride); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when a sealed override is added to an unsealed class."); Assert.AreEqual(BreakingChangeKind.SealedMember, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(IndexerAbstract.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(IndexerAbstractSealedOverride.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerAbstractNoOverride, IndexerAbstractSealedOverrideSealed); Assert.AreEqual(1, breakingChanges.Count, "There should be no breaking changes when a sealed override is added to a sealed class."); }
public void ReturnTypeCovarianceTests() { var assembly = AssemblyData.FromAssembly(typeof(ChangedMemberTypeTests).Assembly); var methodWithReturnBase = TypeDefinitionData.FromType(typeof(MethodWithReturnBase)); var methodWithReturnDerived = TypeDefinitionData.FromType(typeof(MethodWithReturnDerived)); var breakingChanges = MetadataComparer.CompareTypes(methodWithReturnDerived, methodWithReturnBase); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(methodWithReturnDerived.GetMember("Method"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(methodWithReturnBase.GetMember("Method"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(methodWithReturnBase, methodWithReturnDerived); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when the Return type changes to a base type."); // Read/write fields cannot change type at all because they can be used in out or ref parameters var FieldWithReturnBase = TypeDefinitionData.FromType(typeof(FieldWithReturnBase)); var FieldWithReturnDerived = TypeDefinitionData.FromType(typeof(FieldWithReturnDerived)); var FieldWithReadonlyReturnBase = TypeDefinitionData.FromType(typeof(FieldWithReadonlyReturnBase)); breakingChanges = MetadataComparer.CompareTypes(FieldWithReturnDerived, FieldWithReturnBase); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(FieldWithReturnDerived.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(FieldWithReturnBase.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithReturnBase, FieldWithReturnDerived); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(FieldWithReturnBase.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(FieldWithReturnDerived.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithReadonlyReturnBase, FieldWithReturnDerived); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when the read-only field type changes to a base type."); var EventWithReturnBase = TypeDefinitionData.FromType(typeof(EventWithReturnBase)); var EventWithReturnDerived = TypeDefinitionData.FromType(typeof(EventWithReturnDerived)); breakingChanges = MetadataComparer.CompareTypes(EventWithReturnDerived, EventWithReturnBase); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(EventWithReturnDerived.GetMember("Event"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(EventWithReturnBase.GetMember("Event"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(EventWithReturnBase, EventWithReturnDerived); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(EventWithReturnBase.GetMember("Event"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(EventWithReturnDerived.GetMember("Event"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void FieldTests() { var assembly = AssemblyData.FromAssembly(typeof(ChangedMemberTypeTests).Assembly); var FieldWithIntReturn = TypeDefinitionData.FromType(typeof(FieldWithIntReturn)); var FieldWithStringReturn = TypeDefinitionData.FromType(typeof(FieldWithStringReturn)); var FieldWithDynamicReturn = TypeDefinitionData.FromType(typeof(FieldWithDynamicReturn)); var breakingChanges = MetadataComparer.CompareTypes(FieldWithIntReturn, FieldWithStringReturn); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(FieldWithIntReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(FieldWithStringReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithStringReturn, FieldWithIntReturn); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(FieldWithStringReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(FieldWithIntReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithIntReturn, FieldWithDynamicReturn); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(FieldWithIntReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(FieldWithDynamicReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithDynamicReturn, FieldWithIntReturn); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(FieldWithDynamicReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(FieldWithIntReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithStringReturn, FieldWithDynamicReturn); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(FieldWithStringReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(FieldWithDynamicReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithDynamicReturn, FieldWithStringReturn); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(FieldWithDynamicReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(FieldWithStringReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void ConstructorTests() { var assembly = AssemblyData.FromAssembly(typeof(ChangedParameterModifierTests).Assembly); var ConstructorWithUnmodifiedParameter = TypeDefinitionData.FromType(typeof(ConstructorWithUnmodifiedParameter)); var ConstructorWithRefParameter = TypeDefinitionData.FromType(typeof(ConstructorWithRefParameter)); var ConstructorWithOutParameter = TypeDefinitionData.FromType(typeof(ConstructorWithOutParameter)); var breakingChanges = MetadataComparer.CompareTypes(ConstructorWithUnmodifiedParameter, ConstructorWithRefParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithUnmodifiedParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithRefParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(ConstructorWithRefParameter.GetMember(".ctor"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(ConstructorWithRefParameter, ConstructorWithUnmodifiedParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithRefParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithUnmodifiedParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(ConstructorWithUnmodifiedParameter.GetMember(".ctor"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(ConstructorWithUnmodifiedParameter, ConstructorWithOutParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithUnmodifiedParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithOutParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(ConstructorWithOutParameter.GetMember(".ctor"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(ConstructorWithOutParameter, ConstructorWithUnmodifiedParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithOutParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithUnmodifiedParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(ConstructorWithUnmodifiedParameter.GetMember(".ctor"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(ConstructorWithRefParameter, ConstructorWithOutParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithRefParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithOutParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(ConstructorWithOutParameter.GetMember(".ctor"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(ConstructorWithOutParameter, ConstructorWithRefParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithOutParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(((IParameterizedItem)ConstructorWithRefParameter.GetMember(".ctor")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(ConstructorWithRefParameter.GetMember(".ctor"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void FieldTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(ChangedMemberTypeTests)); var FieldWithIntReturn = context.GetTypeDefinitionData(typeof(FieldWithIntReturn)); var FieldWithStringReturn = context.GetTypeDefinitionData(typeof(FieldWithStringReturn)); var FieldWithDynamicReturn = context.GetTypeDefinitionData(typeof(FieldWithDynamicReturn)); var breakingChanges = MetadataComparer.CompareTypes(FieldWithIntReturn, FieldWithStringReturn); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); AssertX.Equal(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(FieldWithIntReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(FieldWithStringReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithStringReturn, FieldWithIntReturn); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); AssertX.Equal(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(FieldWithStringReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(FieldWithIntReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithIntReturn, FieldWithDynamicReturn); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); AssertX.Equal(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(FieldWithIntReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(FieldWithDynamicReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithDynamicReturn, FieldWithIntReturn); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); AssertX.Equal(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(FieldWithDynamicReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(FieldWithIntReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithStringReturn, FieldWithDynamicReturn); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); AssertX.Equal(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(FieldWithStringReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(FieldWithDynamicReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(FieldWithDynamicReturn, FieldWithStringReturn); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); AssertX.Equal(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(FieldWithDynamicReturn.GetMember("Field"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(FieldWithStringReturn.GetMember("Field"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void NestedTypeTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(ChangedParameterModifierTests)); var NestedDelegateWithUnmodifiedParameter = context.GetTypeDefinitionData(typeof(NestedDelegateWithUnmodifiedParameter)); var NestedDelegateWithRefParameter = context.GetTypeDefinitionData(typeof(NestedDelegateWithRefParameter)); var NestedDelegateWithOutParameter = context.GetTypeDefinitionData(typeof(NestedDelegateWithOutParameter)); var breakingChanges = MetadataComparer.CompareTypes(NestedDelegateWithUnmodifiedParameter, NestedDelegateWithRefParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(NestedDelegateWithUnmodifiedParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(NestedDelegateWithRefParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(NestedDelegateWithRefParameter.GetNestedType("Delegate"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(NestedDelegateWithRefParameter, NestedDelegateWithUnmodifiedParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(NestedDelegateWithRefParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(NestedDelegateWithUnmodifiedParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(NestedDelegateWithUnmodifiedParameter.GetNestedType("Delegate"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(NestedDelegateWithUnmodifiedParameter, NestedDelegateWithOutParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(NestedDelegateWithUnmodifiedParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(NestedDelegateWithOutParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(NestedDelegateWithOutParameter.GetNestedType("Delegate"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(NestedDelegateWithOutParameter, NestedDelegateWithUnmodifiedParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(NestedDelegateWithOutParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(NestedDelegateWithUnmodifiedParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(NestedDelegateWithUnmodifiedParameter.GetNestedType("Delegate"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(NestedDelegateWithRefParameter, NestedDelegateWithOutParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(NestedDelegateWithRefParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(NestedDelegateWithOutParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(NestedDelegateWithOutParameter.GetNestedType("Delegate"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(NestedDelegateWithOutParameter, NestedDelegateWithRefParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(NestedDelegateWithOutParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(NestedDelegateWithRefParameter.GetNestedType("Delegate").DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(NestedDelegateWithRefParameter.GetNestedType("Delegate"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void MethodTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(ChangedParameterModifierTests)); var MethodWithUnmodifiedParameter = context.GetTypeDefinitionData(typeof(MethodWithUnmodifiedParameter)); var MethodWithRefParameter = context.GetTypeDefinitionData(typeof(MethodWithRefParameter)); var MethodWithOutParameter = context.GetTypeDefinitionData(typeof(MethodWithOutParameter)); var breakingChanges = MetadataComparer.CompareTypes(MethodWithUnmodifiedParameter, MethodWithRefParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithUnmodifiedParameter.GetMember("Method")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithRefParameter.GetMember("Method")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(MethodWithRefParameter.GetMember("Method"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(MethodWithRefParameter, MethodWithUnmodifiedParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithRefParameter.GetMember("Method")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithUnmodifiedParameter.GetMember("Method")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(MethodWithUnmodifiedParameter.GetMember("Method"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(MethodWithUnmodifiedParameter, MethodWithOutParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithUnmodifiedParameter.GetMember("Method")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithOutParameter.GetMember("Method")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(MethodWithOutParameter.GetMember("Method"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(MethodWithOutParameter, MethodWithUnmodifiedParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithOutParameter.GetMember("Method")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithUnmodifiedParameter.GetMember("Method")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(MethodWithUnmodifiedParameter.GetMember("Method"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(MethodWithRefParameter, MethodWithOutParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithRefParameter.GetMember("Method")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithOutParameter.GetMember("Method")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(MethodWithOutParameter.GetMember("Method"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(MethodWithOutParameter, MethodWithRefParameter); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithOutParameter.GetMember("Method")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)MethodWithRefParameter.GetMember("Method")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(MethodWithRefParameter.GetMember("Method"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void TypeTests() { var assembly = AssemblyData.FromAssembly(typeof(ChangedParameterModifierTests).Assembly); var DelegateWithUnmodifiedParameter = TypeDefinitionData.FromType(typeof(DelegateWithUnmodifiedParameter)); var DelegateWithRefParameter = TypeDefinitionData.FromType(typeof(DelegateWithRefParameter)); var DelegateWithOutParameter = TypeDefinitionData.FromType(typeof(DelegateWithOutParameter)); var breakingChanges = MetadataComparer.CompareTypes(DelegateWithUnmodifiedParameter, DelegateWithRefParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(DelegateWithUnmodifiedParameter.DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(DelegateWithRefParameter.DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(DelegateWithRefParameter, breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(DelegateWithRefParameter, DelegateWithUnmodifiedParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(DelegateWithRefParameter.DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(DelegateWithUnmodifiedParameter.DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(DelegateWithUnmodifiedParameter, breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(DelegateWithUnmodifiedParameter, DelegateWithOutParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(DelegateWithUnmodifiedParameter.DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(DelegateWithOutParameter.DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(DelegateWithOutParameter, breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(DelegateWithOutParameter, DelegateWithUnmodifiedParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(DelegateWithOutParameter.DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(DelegateWithUnmodifiedParameter.DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(DelegateWithUnmodifiedParameter, breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(DelegateWithRefParameter, DelegateWithOutParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(DelegateWithRefParameter.DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(DelegateWithOutParameter.DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(DelegateWithOutParameter, breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(DelegateWithOutParameter, DelegateWithRefParameter); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the parameter modifier changes."); Assert.AreEqual(BreakingChangeKind.ChangedParameterModifier, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(DelegateWithOutParameter.DelegateParameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(DelegateWithRefParameter.DelegateParameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.AreEqual(DelegateWithRefParameter, breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void OperatorTests() { var assembly = AssemblyData.FromAssembly(typeof(ChangedMemberTypeTests).Assembly); var OperatorWithIntReturn = TypeDefinitionData.FromType(typeof(OperatorWithIntReturn)); var OperatorWithStringReturn = TypeDefinitionData.FromType(typeof(OperatorWithStringReturn)); var OperatorWithDynamicReturn = TypeDefinitionData.FromType(typeof(OperatorWithDynamicReturn)); var breakingChanges = MetadataComparer.CompareTypes(OperatorWithIntReturn, OperatorWithStringReturn); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedMemberType).ToList(); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(OperatorWithIntReturn.GetMember("op_Addition"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(OperatorWithStringReturn.GetMember("op_Addition"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithStringReturn, OperatorWithIntReturn); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedMemberType).ToList(); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(OperatorWithStringReturn.GetMember("op_Addition"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(OperatorWithIntReturn.GetMember("op_Addition"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithIntReturn, OperatorWithDynamicReturn); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedMemberType).ToList(); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when the Return type changes to dynamic."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithDynamicReturn, OperatorWithIntReturn); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedMemberType).ToList(); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(OperatorWithDynamicReturn.GetMember("op_Addition"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(OperatorWithIntReturn.GetMember("op_Addition"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithStringReturn, OperatorWithDynamicReturn); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedMemberType).ToList(); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when the Return type changes to dynamic."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithDynamicReturn, OperatorWithStringReturn); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedMemberType).ToList(); Assert.AreEqual(1, breakingChanges.Count, "There should be one breaking change when the Return type changes."); Assert.AreEqual(BreakingChangeKind.ChangedMemberType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); Assert.AreEqual(OperatorWithDynamicReturn.GetMember("op_Addition"), breakingChanges[0].OldItem, "The OldItem is incorrect."); Assert.AreEqual(OperatorWithStringReturn.GetMember("op_Addition"), breakingChanges[0].NewItem, "The NewItem is incorrect."); Assert.IsNull(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void OperatorTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(ChangedParameterTypeTests)); var OperatorWithIntParameter = context.GetTypeDefinitionData(typeof(OperatorWithIntParameter)); var OperatorWithStringParameter = context.GetTypeDefinitionData(typeof(OperatorWithStringParameter)); var OperatorWithDynamicParameter = context.GetTypeDefinitionData(typeof(OperatorWithDynamicParameter)); var breakingChanges = MetadataComparer.CompareTypes(OperatorWithIntParameter, OperatorWithStringParameter); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedParameterType).ToList(); AssertX.Equal(2, breakingChanges.Count, "There should be one breaking change when the parameter type changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)OperatorWithIntParameter.GetMember("op_Addition")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)OperatorWithStringParameter.GetMember("op_Addition")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(OperatorWithStringParameter.GetMember("op_Addition"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithStringParameter, OperatorWithIntParameter); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedParameterType).ToList(); AssertX.Equal(2, breakingChanges.Count, "There should be one breaking change when the parameter type changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)OperatorWithStringParameter.GetMember("op_Addition")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)OperatorWithIntParameter.GetMember("op_Addition")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(OperatorWithIntParameter.GetMember("op_Addition"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithIntParameter, OperatorWithDynamicParameter); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedParameterType).ToList(); AssertX.Equal(1, breakingChanges.Count, "There should be no breaking changes when the Parameter type changes to dynamic."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithDynamicParameter, OperatorWithIntParameter); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedParameterType).ToList(); AssertX.Equal(2, breakingChanges.Count, "There should be one breaking change when the Parameter type changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)OperatorWithDynamicParameter.GetMember("op_Addition")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)OperatorWithIntParameter.GetMember("op_Addition")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(OperatorWithIntParameter.GetMember("op_Addition"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithStringParameter, OperatorWithDynamicParameter); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedParameterType).ToList(); AssertX.Equal(1, breakingChanges.Count, "There should be no breaking changes when the Parameter type changes to dynamic."); breakingChanges = MetadataComparer.CompareTypes(OperatorWithDynamicParameter, OperatorWithStringParameter); breakingChanges = breakingChanges.Where(b => b.BreakingChangeKind == BreakingChangeKind.ChangedParameterType).ToList(); AssertX.Equal(2, breakingChanges.Count, "There should be one breaking change when the Parameter type changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterType, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(((IParameterizedItem)OperatorWithDynamicParameter.GetMember("op_Addition")).Parameters[0], breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(((IParameterizedItem)OperatorWithStringParameter.GetMember("op_Addition")).Parameters[0], breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Equal(OperatorWithStringParameter.GetMember("op_Addition"), breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }
public void TypeForwardingTest() { var foo = typeof(older::TypeForwardingOld.SourceType).Assembly.FullName; var oldFamily = new AssemblyFamily { AssemblyData.FromAssembly(typeof(older::TypeForwardingOld.SourceType).Assembly) }; var newFamily = new AssemblyFamily { AssemblyData.FromAssembly(typeof(newer::TypeForwardingOld.SourceType).Assembly), AssemblyData.FromAssembly(typeof(newer::TypeForwardingOld.TargetType1).Assembly) }; var breakingChanges = MetadataComparer.CompareAssemblyFamilies(oldFamily, newFamily); Assert.AreEqual(0, breakingChanges.Count, "There should be no breaking changes when the removed type is forwarded."); }
public void IndexerTests() { var context = MetadataResolutionContext.CreateFromTypes(typeof(ChangedParameterCountTests)); var IndexerWithFewerParameters = context.GetTypeDefinitionData(typeof(IndexerWithFewerParameters)); var IndexerWithMoreParameters = context.GetTypeDefinitionData(typeof(IndexerWithMoreParameters)); var IndexerWithOptionalParameter = context.GetTypeDefinitionData(typeof(IndexerWithOptionalParameter)); var IndexerWithParamsParameter = context.GetTypeDefinitionData(typeof(IndexerWithParamsParameter)); var breakingChanges = MetadataComparer.CompareTypes(IndexerWithFewerParameters, IndexerWithMoreParameters); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the required parameter count changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterCount, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(IndexerWithFewerParameters.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(IndexerWithMoreParameters.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerWithMoreParameters, IndexerWithFewerParameters); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the required parameter count changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterCount, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(IndexerWithMoreParameters.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(IndexerWithFewerParameters.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerWithMoreParameters, IndexerWithOptionalParameter); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when a required parameter is made optional."); breakingChanges = MetadataComparer.CompareTypes(IndexerWithFewerParameters, IndexerWithOptionalParameter); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when an optional parameter is added."); breakingChanges = MetadataComparer.CompareTypes(IndexerWithOptionalParameter, IndexerWithMoreParameters); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the required parameter count changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterCount, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(IndexerWithOptionalParameter.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(IndexerWithMoreParameters.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); breakingChanges = MetadataComparer.CompareTypes(IndexerWithFewerParameters, IndexerWithParamsParameter); AssertX.Equal(0, breakingChanges.Count, "There should be no breaking changes when an params parameter is added."); breakingChanges = MetadataComparer.CompareTypes(IndexerWithParamsParameter, IndexerWithMoreParameters); AssertX.Equal(1, breakingChanges.Count, "There should be one breaking change when the required parameter count changes."); AssertX.Equal(BreakingChangeKind.ChangedParameterCount, breakingChanges[0].BreakingChangeKind, "The BreakingChangeKind is incorrect."); AssertX.Equal(IndexerWithParamsParameter.GetMember("Item"), breakingChanges[0].OldItem, "The OldItem is incorrect."); AssertX.Equal(IndexerWithMoreParameters.GetMember("Item"), breakingChanges[0].NewItem, "The NewItem is incorrect."); AssertX.Null(breakingChanges[0].AssociatedData, "The AssociatedData is incorrect."); }