public void AreNotEqual() { ParentChain chain1 = ParentChain.GetGrandFatherSample(); ParentChain chain2 = ParentChain.GetGrandFatherSample(); chain2.Name = "bfff"; Assert.Throws <AssertionException>(() => ObjectComparer.AssertNotEqual(chain1, chain2)); }
private static void AssertCanGenerateCorrectMemberSetter( object source, IFastSerialisationTypeConverter[] typeConverters, int expectedNumberOfMemberSettersGenerated, int expectedNumberOfMemberSettersThatCanNotBeGenerated) { // TryToGenerateMemberSetters will try to return member setters for each type that it encountered while analysing the source type - for example, if // source is an instance of "PersonDetails" and if "PersonDetails" has an int Key property and a "NameDetails" Name property where "NameDetails" is // a class with a single string property "Name" then TryToGenerateMemberSetters will try to generate member setters for both the "PersonDetails" // and "NameDetails" classes (it may not succeed, in which case it may return zero or one member setters, or it may succeed completely and return // two member setters). It won't return member setters for values that have first class IWrite support (primitives, strings, DateTime, etc..) var sourceType = source.GetType(); var deepMemberSetterCache = new ConcurrentDictionary <Type, DeepCompiledMemberSettersGenerationResults>(); var memberSetterDetailsForAllTypesInvolved = GetMemberSettersFor(sourceType, typeConverters, deepMemberSetterCache); Assert.NotNull(memberSetterDetailsForAllTypesInvolved); // We should always get a non-null reference for this (but doesn't hurt to confirm) // Try to get member setter for the source type if (!memberSetterDetailsForAllTypesInvolved.MemberSetters.TryGetValue(sourceType, out var memberSetterDetailsForType)) { memberSetterDetailsForType = null; } Assert.NotNull(memberSetterDetailsForType); // We should know how many member setters we expected to be generated (and how many it's not possible to generate), so let's confirm Assert.Equal(expectedNumberOfMemberSettersGenerated, memberSetterDetailsForAllTypesInvolved.MemberSetters.Count(kvp => kvp.Value != null)); Assert.Equal(expectedNumberOfMemberSettersThatCanNotBeGenerated, memberSetterDetailsForAllTypesInvolved.MemberSetters.Count(kvp => kvp.Value == null)); byte[] serialised; using (var stream = new MemoryStream()) { // See notes in SimpleMemberSetterCompilationTests's "AssertCanGenerateCorrectMemberSetter" method - this code is relying more on implementation // details that I would like but it seems like the least of all evils to do so foreach (var typeName in memberSetterDetailsForAllTypesInvolved.TypeNamesToDeclare) { var typeNameBytes = new[] { (byte)BinarySerialisationDataType.FieldNamePreLoad }.Concat(typeName.AsStringAndReferenceID).ToArray(); stream.Write(typeNameBytes, 0, typeNameBytes.Length); } foreach (var fieldName in memberSetterDetailsForAllTypesInvolved.FieldNamesToDeclare) { var fieldNameBytes = new[] { (byte)BinarySerialisationDataType.FieldNamePreLoad }.Concat(fieldName.AsStringAndReferenceID).ToArray(); stream.Write(fieldNameBytes, 0, fieldNameBytes.Length); } var writer = new BinarySerialisationWriter(stream); writer.ObjectStart(source.GetType()); memberSetterDetailsForType(source, writer); writer.ObjectEnd(); serialised = stream.ToArray(); } var clone = BinarySerialisation.Deserialise <object>(serialised, typeConverters.OfType <IDeserialisationTypeConverter>().ToArray()); if (!ObjectComparer.AreEqual(source, clone, out var differenceSummaryIfNotEqual)) { throw new Exception("Clone failed: " + differenceSummaryIfNotEqual); } }
private static void AssertCanGenerateCorrectMemberSetter(object source) { var memberSetterDetails = TryToGenerateMemberSetter(source.GetType()); Assert.NotNull(memberSetterDetails); byte[] serialised; using (var stream = new MemoryStream()) { // In an ideal world, this wouldn't be so tied to implementation details of the Serialiser and BinarySerialisationWriter classes but I can't // immediately think of a way to fully test this otherwise - one option would be to skip the writing of the FieldNamePreLoad data and to skip // the ObjectStart and ObjectEnd calls and to then read the data back out via a BinarySerialisationReader and manually compare the field and // property names to expected values but I wanted to offload that sort of comparison work to a library like CompareNetObjects! // - "Optimisied member setters" are not usually generated until after an instance of a type has been serialised without, in which case all // field names will have appeared in the serialised data at least once, which is important because the member setters will write out Name // Reference IDs for fields and the reader needs to know what strings those IDs map on to. Since this code won't be serialising an instance // of each type before using the member setter, FieldNamePreLoad data can be injected into the start of the serialised data and then the // reader will be able to refer to use that to map IDs to strings. foreach (var fieldName in memberSetterDetails.FieldsSet) { var fieldNameBytes = new[] { (byte)BinarySerialisationDataType.FieldNamePreLoad }.Concat(fieldName.AsStringAndReferenceID).ToArray(); stream.Write(fieldNameBytes, 0, fieldNameBytes.Length); } var writer = new BinarySerialisationWriter(stream); writer.ObjectStart(source.GetType()); memberSetterDetails.GetCompiledMemberSetter()(source, writer); writer.ObjectEnd(); serialised = stream.ToArray(); } var clone = BinarySerialisation.Deserialise <object>(serialised); if (!ObjectComparer.AreEqual(source, clone, out var differenceSummaryIfNotEqual)) { throw new Exception("Clone failed: " + differenceSummaryIfNotEqual); } }
private static bool ExecuteTest(TestDetails testItemDetails, bool showDetailedInformation, HTMLElement appendSuccessesTo, HTMLElement appendFailuresTo) { try { var testItem = TestItemInstanceCreator.GetInstance(testItemDetails.FullName); var decoder = GetTypedMessagePackSerializerDeserializeCall(testItem.DeserialiseAs, testItem.DecodeOptions); if (testItemDetails.ExpectedError is null) { var clone = decoder(testItemDetails.Serialised); var expectedResult = (testItemDetails.AlternateResultJson is null) ? testItem.Value : DeserialiseAlternateResultJson(testItemDetails.AlternateResultJson); if (ObjectComparer.AreEqual(expectedResult, clone, out var messageIfNotEqual)) { RenderSuccess($"Expected and received: {JsonSerialiserForComparison.ToJson(expectedResult)}"); return(true); } RenderFailure(messageIfNotEqual); return(false); } else { try { decoder(testItemDetails.Serialised); RenderFailure("No exception was thrown but expected: " + testItemDetails.ExpectedError.ExceptionType.FullName); return(false); } catch (Exception deserialisationException) { if (deserialisationException.GetType() != testItemDetails.ExpectedError.ExceptionType) { var additionalInfo = $"Expected exception {testItemDetails.ExpectedError.ExceptionType.FullName} but {deserialisationException.GetType().FullName} was thrown"; if (showDetailedInformation) { additionalInfo += "\n\n" + deserialisationException.ToString(); } RenderFailure(additionalInfo); return(false); } if (deserialisationException.Message != testItemDetails.ExpectedError.Message) { var additionalInfo = $"Expected exception message \"{testItemDetails.ExpectedError.Message}\" but received \"{deserialisationException.Message}\""; if (showDetailedInformation) { additionalInfo += "\n\n" + deserialisationException.ToString(); } RenderFailure(additionalInfo); return(false); } RenderSuccess($"Expected and received error: {deserialisationException.Message}"); return(true); } } } catch (Exception e) { RenderFailure(e.Message, e.ToString()); } return(false); void RenderSuccess(string extendedAdditionalInfo) { appendSuccessesTo.appendChild( GetMessage(testItemDetails.DisplayName, hrefIfTextShouldLink: GetHrefForFilteringToTest(testItemDetails.DisplayName), isSuccess: true, additionalInfo: showDetailedInformation ? extendedAdditionalInfo : null) ); } void RenderFailure(string summary, string extendedAdditionalInfo = null) { appendFailuresTo.appendChild( GetMessage(testItemDetails.DisplayName, hrefIfTextShouldLink: GetHrefForFilteringToTest(testItemDetails.DisplayName), isSuccess: false, additionalInfo: showDetailedInformation ? (extendedAdditionalInfo ?? summary) : summary) ); } }