public void Compare_DetectsNewMembersInThePresenceOfTheSameNumberOfRemovedAndAddedMembers() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); // Act var breakingChanges = comparer.GetDifferences(); // Assert var interfaceBreakingChanges = breakingChanges .Where(b => b.TypeId == "public interface ComparisonScenarios.IInterfaceWithSameNumberOfRemovedAndAddedMembers") .ToList(); Assert.Single(interfaceBreakingChanges, b => b.MemberId == "System.Void FirstMemberToRemove()" && b.Kind == ChangeKind.Removal); Assert.Single(interfaceBreakingChanges, b => b.MemberId == "System.Void SecondMemberToRemove()" && b.Kind == ChangeKind.Removal); Assert.Single(interfaceBreakingChanges, b => b.MemberId == "System.Void ThirdMemberToRemove()" && b.Kind == ChangeKind.Removal); Assert.Single(interfaceBreakingChanges, b => b.MemberId == "System.Void FirstAddedMember()" && b.Kind == ChangeKind.Addition); Assert.Single(interfaceBreakingChanges, b => b.MemberId == "System.Void SecondAddedMember()" && b.Kind == ChangeKind.Addition); Assert.Single(interfaceBreakingChanges, b => b.MemberId == "System.Void ThirdAddedMember()" && b.Kind == ChangeKind.Addition); }
public void Compare_AllowsExclusionsOnNewInterfaceMembers() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); var knownBreakingChanges = new List <BreakingChange> { new BreakingChange( "public interface ComparisonScenarios.IInterfaceToAddMembersTo", "System.Int32 get_NewMember()", ChangeKind.Addition), new BreakingChange( "public interface ComparisonScenarios.IInterfaceToAddMembersTo", "System.Void set_NewMember(System.Int32 value)", ChangeKind.Addition) }; // Act var breakingChanges = comparer.GetDifferences().Except(knownBreakingChanges); // Assert Assert.DoesNotContain( breakingChanges, bc => bc.TypeId == "public interface ComparisonScenarios.IInterfaceToAddMembersTo"); }
public void Compare_DetectsAbstractPropertyAdditions() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); var typeToCheck = "public abstract class ComparisonScenarios.AbstractClassToAddPropertiesTo"; var expected = new List <BreakingChange> { new BreakingChange( typeToCheck, "public abstract System.Int32 get_NewAbstractProperty()", ChangeKind.Addition), new BreakingChange( typeToCheck, "public abstract System.Void set_PropertyToAddSetterTo(System.Int32 value)", ChangeKind.Addition), }; // Act var breakingChanges = comparer.GetDifferences(); // Assert var breakingChangesInType = breakingChanges .Where(change => string.Equals(change.TypeId, typeToCheck, StringComparison.Ordinal)) .OrderBy(change => change.MemberId); Assert.Equal(expected, breakingChangesInType); }
public void Compare_DetectsAllFieldRemovals(string typeToCheck) { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); // Oops. The NewInternalProperty addition is a breaking change; makes it impossible to subclass type in // another assembly. var expected = new List <BreakingChange> { // Changing a const's value doesn't cause a binary incompatibility but often causes problems. new BreakingChange( typeToCheck, "public const System.Int32 ConstToChangeValue = 1", ChangeKind.Removal), // Removing a const doesn't cause a binary incompatibilty but often causes problems. new BreakingChange( typeToCheck, "public const System.Int32 ConstToMakeField = 2", ChangeKind.Removal), // Oops. Making a field writable is not technically a breaking change. new BreakingChange( typeToCheck, "public readonly System.Int32 FieldToMakeWritable", ChangeKind.Removal), new BreakingChange( typeToCheck, "public static readonly System.Int32 StaticFieldToMakeConst", ChangeKind.Removal), // Oops. Making a field writable is not technically a breaking change. new BreakingChange( typeToCheck, "public static readonly System.Int32 StaticFieldToMakeWritable", ChangeKind.Removal), new BreakingChange( typeToCheck, "public static System.Int32 StaticFieldToMakeReadonly", ChangeKind.Removal), new BreakingChange( typeToCheck, "public System.Int32 FieldToMakeReadonly", ChangeKind.Removal), new BreakingChange( typeToCheck, "public System.Int32 FieldToRemove", ChangeKind.Removal), }; // Act var breakingChanges = comparer.GetDifferences(); // Assert var breakingChanginesInType = breakingChanges .Where(change => string.Equals(change.TypeId, typeToCheck, StringComparison.Ordinal)) .OrderBy(change => change.MemberId); Assert.Equal(expected, breakingChanginesInType); }
public void Compare_DoesNotFailForTypeAddingAnInterface() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); // Act var breakingChanges = comparer.GetDifferences(); // Assert Assert.Null(breakingChanges.FirstOrDefault( bc => bc.TypeId == "public ComparisonScenarios.TypeWithExtraInterface")); }
public void Compare_AllowsTypeToBeForwarded() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); var typeToCheck = "public class ComparisonScenarios.TypeToBeForwarded"; // Act var breakingChanges = comparer.GetDifferences(); // Assert Assert.DoesNotContain(breakingChanges, bc => bc.TypeId == typeToCheck); }
public void Compare_Detects_TypeRenames_as_removal() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); // Act var breakingChanges = comparer.GetDifferences(); // Assert var expected = new BreakingChange( "public interface ComparisonScenarios.TypeToRename", memberId: null, kind: ChangeKind.Removal); Assert.Contains(expected, breakingChanges); }
public void Compare_Detects_ChangesInTypeVisibility_as_removal() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); // Act var breakingChanges = comparer.GetDifferences(); // Assert var expected = new BreakingChange( "public class ComparisonScenarios.PublicToInternalClass", memberId: null, kind: ChangeKind.Removal); Assert.Contains(expected, breakingChanges); }
public void Compare_Detects_MethodParametersBeingAdded_as_removal() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); // Act var breakingChanges = comparer.GetDifferences(); // Assert var expected = new BreakingChange( "public class ComparisonScenarios.ClassWithMethods", "public System.Void MethodToAddParameters()", kind: ChangeKind.Removal); Assert.Contains(expected, breakingChanges); }
public void Compare_Detects_GenericTypeConstraintsBeingAdded_as_removal() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); // Act var breakingChanges = comparer.GetDifferences(); // Assert var expected = new BreakingChange( "public class ComparisonScenarios.GenericTypeWithConstraintsToBeAdded<T0>", memberId: null, kind: ChangeKind.Removal); Assert.Contains(expected, breakingChanges); }
public void Compare_Detects_ClassBeingUnnested_as_removal() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); // Act var breakingChanges = comparer.GetDifferences(); // Assert var expected = new BreakingChange( "public class ComparisonScenarios.ClassToUnnestContainer+ClassToUnnest", memberId: null, kind: ChangeKind.Removal); Assert.Contains(expected, breakingChanges); }
public void Compare_DetectsAbstractMethodAdditions() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); var typeToCheck = "public abstract class ComparisonScenarios.AbstractClassToAddMethodsTo"; // Act var breakingChanges = comparer.GetDifferences(); // Assert var breakingChangesInType = breakingChanges .Where(change => string.Equals(change.TypeId, typeToCheck, StringComparison.Ordinal)); var breakingChange = Assert.Single(breakingChangesInType); Assert.Equal(ChangeKind.Addition, breakingChange.Kind); Assert.Equal("public abstract System.Void NewAbstractMethod()", breakingChange.MemberId); }
public void Compare_DetectsNewMembersBeingAddedToAnInterface_as_addition() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); // Act var breakingChanges = comparer.GetDifferences(); // Assert var interfaceBreakingChanges = breakingChanges .Where(b => b.TypeId == "public interface ComparisonScenarios.IInterfaceToAddMembersTo") .ToList(); Assert.Single(interfaceBreakingChanges, b => b.MemberId == "System.Int32 get_NewMember()" && b.Kind == ChangeKind.Addition); Assert.Single(interfaceBreakingChanges, b => b.MemberId == "System.Void set_NewMember(System.Int32 value)" && b.Kind == ChangeKind.Addition); }
public void Compare_DetectsChangesInForwardedType() { // Arrange var v1ApiListing = CreateApiListingDocument(V1Assembly); var v2ApiListing = CreateApiListingDocument(V2Assembly); var comparer = new ApiListingComparer(v1ApiListing, v2ApiListing); var typeToCheck = "public class ComparisonScenarios.TypeToBeForwardedAndChanged"; var getterRemoval = new BreakingChange( typeToCheck, "public System.String get_PropertyToBeRemoved()", ChangeKind.Removal); var setterRemoval = new BreakingChange( typeToCheck, "public System.Void set_PropertyToBeRemoved(System.String value)", ChangeKind.Removal); // Act var breakingChanges = comparer.GetDifferences(); // Assert Assert.Equal(2, breakingChanges.Count(bc => bc.TypeId == typeToCheck)); Assert.Contains(getterRemoval, breakingChanges); Assert.Contains(setterRemoval, breakingChanges); }