예제 #1
0
        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);
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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)
                    );
            }
        }