public void GetFromTypes_WithNullInput_ShouldThrowNullArgumentException()
        {
            // Arrange

            // Act
            var exception = Record.Exception(() => UpconverterCompiler.GetFrom(null));

            // Assert
            exception.Should().NotBeNull();
            exception.Should().BeOfType <ArgumentNullException>();
        }
        public void GetFromTypes_WithwithOneMultiEventUpconverter_ShouldReturnDictionaryWithOneUpconvert()
        {
            var types = new[] { typeof(UpconverterAToBAndC) };
            Dictionary <Type, UpconvertFunc> upconverters = null;

            // Act
            upconverters = UpconverterCompiler.GetFrom(types);

            // Assert
            upconverters.Count.Should().Be(1);
            upconverters.Single().Key.Should().Be <EventA>();
        }
        public void GetFromTypes_WithwithTwoUpconverterInChain_ShouldReturnDictionaryWithTwoEntries()
        {
            // Arrange
            var types = new[] { typeof(UpconverterAToB), typeof(UpconverterBToE) };
            Dictionary <Type, UpconvertFunc> upconverters = null;

            // Act
            upconverters = UpconverterCompiler.GetFrom(types);

            // Assert
            upconverters.Count.Should().Be(2);
        }
        public void GetFromTypes_WithNoUpconverters_ShouldReturnEmptyDictionary()
        {
            // Arrange
            Dictionary <Type, UpconvertFunc> upconverters = null;

            // Act
            var exception = Record.Exception((Action)(() => upconverters = UpconverterCompiler.GetFrom(new List <Type>())));

            // Assert
            exception.Should().BeNull();
            upconverters.Should().BeEmpty();
        }
        public void GetFromTypes_WithwithSingleEventUpconverter_ShouldReturnDictionaryWithOneEntry()
        {
            // Arrange
            var types = new[] { typeof(UpconverterAToB) };
            Dictionary <Type, UpconvertFunc> upconverters = null;

            // Act
            upconverters = UpconverterCompiler.GetFrom(types);

            // Assert
            upconverters.Count.Should().Be(1);
            upconverters.FirstOrDefault().Key.Should().Be <EventA>();
        }
        public void GetFromTypes_WithUpconverterWithNoPublicDefaultCtor_ShouldThrowCannotInstantiateUpconverterException()
        {
            // Arrange

            // Act
            var exception = Record.Exception(() => UpconverterCompiler.GetFrom(new [] { typeof(
                                                                                            UpconverterWithNonPublicCtor) }));

            // Assert
            exception.Should().NotBeNull();
            exception.Should().BeOfType <CannotInstantiateUpconverterException>();
            exception.As <CannotInstantiateUpconverterException>().upconverterType.Should().Be <UpconverterWithNonPublicCtor>();
        }
        public void GetFromTypes_WithTypesButNoUpconverter_ShouldReturnEmptyDictionary()
        {
            // Arrange
            var types = new[] { this.GetType() };
            Dictionary <Type, UpconvertFunc> upconverters = null;

            // Act
            var exception =
                Record.Exception((Action)(() => upconverters = UpconverterCompiler.GetFrom(types)));

            // Assert
            exception.Should().BeNull();
            upconverters.Should().BeEmpty();
        }
        public void GetFromTypes_WithwithTwoUpconverterInChainFromEventAToEventBToEventE_ShouldReturnDictionaryWithUpconvertFromEventBToEventE()
        {
            // Arrange
            var           types           = new[] { typeof(UpconverterAToB), typeof(UpconverterBToE) };
            UpconvertFunc upconverter     = null;
            var           originalEvent   = new EventB("Mr. Silly Name", 5);
            var           wrappedOriginal = new ItemWithType(originalEvent);
            var           expectedEvent   = new EventE("Mr. Silly Name-5");

            // Act
            upconverter = UpconverterCompiler.GetFrom(types)[typeof(EventB)];

            // Assert
            upconverter.Should().NotBeNull();
            upconverter(wrappedOriginal).isSingleItem.Should().BeTrue();
            upconverter(wrappedOriginal).single.type.Should().Be <EventE>();
            upconverter(wrappedOriginal).single.instance.As <EventE>().Formatted.Should().Be(expectedEvent.Formatted);
        }
        GetFromTypes_WithwithOneUpconverterInChainFromEventAToEventB_ShouldReturnDictionaryWithOneUpconvertFromEventAToEventB()
        {
            // Arrange
            var           types         = new[] { typeof(UpconverterAToB) };
            UpconvertFunc upconverter   = null;
            var           originalEvent = new EventA("Mr. Silly Name", 5);
            var           expectedEvent = new EventB(originalEvent.Name, originalEvent.Count);

            // Act
            upconverter = UpconverterCompiler.GetFrom(types)[typeof(EventA)];

            // Assert
            upconverter.Should().NotBeNull();
            upconverter(new ItemWithType(originalEvent)).isSingleItem.Should().BeTrue();
            upconverter(new ItemWithType(originalEvent)).single.type.Should().Be <EventB>();
            upconverter(new ItemWithType(originalEvent)).single.instance.As <EventB>().MyName.Should().Be(expectedEvent.MyName);
            upconverter(new ItemWithType(originalEvent)).single.instance.As <EventB>().Count.Should().Be(expectedEvent.Count);
        }
        public void GetFromTypes_WithUpconvertersWithSameSourceEvent_ShouldThrowPreflightUpconverterConflictException()
        {
            // Arrange

            // Act
            var exception = Record.Exception(() => UpconverterCompiler.GetFrom(new []
            {
                typeof(UpconverterAToB),
                typeof(UpconverterAToBAndC),
            }));

            // Assert
            exception.Should().NotBeNull();
            exception.Should().BeOfType <AggregateException>();
            exception.As <AggregateException>().Flatten().InnerExceptions.Count.Should().Be(1);
            var innerException = exception.As <AggregateException>().Flatten().InnerExceptions.ToArray()[0];

            innerException.Should().BeOfType <PreflightUpconverterConflictException>();
            innerException.As <PreflightUpconverterConflictException>().SourceEventType.Should().Be <EventA>();
        }
        public void GetFromTypes_WithwithOneMultiEventUpconverterFromAToBAndC_ShouldReturnDictionaryWithUpconvertFromAToEnumerableWithBAndC()
        {
            var           types         = new[] { typeof(UpconverterAToBAndC) };
            UpconvertFunc upconverter   = null;
            var           originalEvent = new EventA("Mr. Silly Name", 5);
            var           expectedB     = new EventB(originalEvent.Name, originalEvent.Count);
            var           expectedC     = new EventC(originalEvent.Count);

            // Act
            upconverter = UpconverterCompiler.GetFrom(types)[typeof(EventA)];
            var result = upconverter(new ItemWithType(originalEvent));

            // Assert
            upconverter.Should().NotBeNull();
            result.isSingleItem.Should().BeFalse();
            result.multiple.ToArray()[0].type.Should().Be <EventB>();
            result.multiple.ToArray()[0].instance.As <EventB>().Count.Should().Be(expectedB.Count);
            result.multiple.ToArray()[0].instance.As <EventB>().MyName.Should().Be(expectedB.MyName);
            result.multiple.ToArray()[1].type.Should().Be <EventC>();
            result.multiple.ToArray()[1].instance.As <EventC>().Count.Should().Be(expectedC.Count);
        }