/// <summary>
 /// Initialises an instance of <see cref="ModelValueToManifestValueConverter"/>.
 /// </summary>
 /// <param name="accessorFactory">A factory for accessor functions.</param>
 /// <param name="validatedTypeProvider">A service that gets the validated type.</param>
 /// <param name="contextToItemConverter">A converter service for model conversion contexts.</param>
 public ModelValueToManifestValueConverter(IGetsAccessorFunction accessorFactory,
                                           IGetsValidatedType validatedTypeProvider,
                                           IGetsManifestItemFromModelToManifestConversionContext contextToItemConverter)
 {
     this.validatedTypeProvider  = validatedTypeProvider ?? throw new ArgumentNullException(nameof(validatedTypeProvider));
     this.contextToItemConverter = contextToItemConverter ?? throw new ArgumentNullException(nameof(contextToItemConverter));
     this.accessorFactory        = accessorFactory ?? throw new ArgumentNullException(nameof(accessorFactory));
 }
        public void ConvertAllValuesShouldSuccessfullyConvertAMultiLevelValueHierarchy([Frozen] IGetsAccessorFunction accessorFactory,
                                                                                       [Frozen] IGetsValidatedType validatedTypeProvider,
                                                                                       [Frozen] IGetsManifestItemFromModelToManifestConversionContext itemFactory,
                                                                                       ModelValueToManifestValueConverter sut,
                                                                                       [ManifestModel] ModelToManifestConversionContext context,
                                                                                       IManifestItem item,
                                                                                       AccessorFunctionAndType accessor)
        {
            Mock.Get(accessorFactory)
            .Setup(x => x.GetAccessorFunction(It.IsAny <Type>(), It.IsAny <string>()))
            .Returns(accessor);
            Mock.Get(validatedTypeProvider)
            .Setup(x => x.GetValidatedType(It.IsAny <Type>(), It.IsAny <bool>()))
            .Returns((Type t, bool b) => t);
            Mock.Get(itemFactory)
            .Setup(x => x.GetManifestItem(It.IsAny <ModelToManifestConversionContext>())).Returns(item);

            context.CurrentValue = new Value
            {
                Children = new Dictionary <string, Value>
                {
                    { "Foo", new Value
                      {
                          Children = new Dictionary <string, Value>
                          {
                              { "Foo", new Value() },
                              { "Bar", new Value {
                                    ValidateRecursivelyAsAncestor = 1
                                } },
                              { "Baz", new Value
                                {
                                    CollectionItemValue = new CollectionItemValue(),
                                } },
                          },
                          PolymorphicValues = new Dictionary <string, PolymorphicValue>
                          {
                              { "System.String", new PolymorphicValue() },
                          }
                      } },
                    { "Bar", new Value() },
                }
            };

            sut.ConvertAllValues(context);

            Assert.Multiple(() =>
            {
                Mock.Get(itemFactory)
                .Verify(x => x.GetManifestItem(It.Is <ModelToManifestConversionContext>(c => c.ConversionType == ModelToManifestConversionType.Manifest)),
                        Times.Exactly(5));
                Mock.Get(itemFactory)
                .Verify(x => x.GetManifestItem(It.Is <ModelToManifestConversionContext>(c => c.ConversionType == ModelToManifestConversionType.PolymorphicType)),
                        Times.Exactly(1));
                Mock.Get(itemFactory)
                .Verify(x => x.GetManifestItem(It.Is <ModelToManifestConversionContext>(c => c.ConversionType == ModelToManifestConversionType.CollectionItem)),
                        Times.Exactly(1));
                Mock.Get(itemFactory)
                .Verify(x => x.GetManifestItem(It.Is <ModelToManifestConversionContext>(c => c.ConversionType == ModelToManifestConversionType.RecursiveManifestValue)),
                        Times.Exactly(1));
            });

            Mock.Get(itemFactory)
            .Verify(x => x.GetManifestItem(It.IsAny <ModelToManifestConversionContext>()), Times.Exactly(8));
        }