Esempio n. 1
0
        /// <summary>
        /// Creates a set of interesting entity instances along with metadata.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use.</param>
        /// <param name="model">If non-null, the method creates complex types for the complex values and adds them to the model.</param>
        /// <param name="withTypeNames">true if the payloads should specify type names.</param>
        /// <returns>List of test descriptors with interesting entity instances as payload.</returns>
        public static IEnumerable<PayloadTestDescriptor> CreateEntityInstanceTestDescriptors(
            EdmModel model,
            bool withTypeNames)
        {
            IEnumerable<PrimitiveValue> primitiveValues = TestValues.CreatePrimitiveValuesWithMetadata(fullSet: false);
            IEnumerable<ComplexInstance> complexValues = TestValues.CreateComplexValues(model, withTypeNames, fullSet: false);
            IEnumerable<NamedStreamInstance> streamReferenceValues = TestValues.CreateStreamReferenceValues(fullSet: false);
            IEnumerable<PrimitiveMultiValue> primitiveMultiValues = TestValues.CreatePrimitiveCollections(withTypeNames, fullSet: false);
            IEnumerable<ComplexMultiValue> complexMultiValues = TestValues.CreateComplexCollections(model, withTypeNames, fullSet: false);
            IEnumerable<NavigationPropertyInstance> navigationProperties = TestValues.CreateDeferredNavigationLinks();

            // NOTE we have to copy the EntityModelTypeAnnotation on the primitive value to the NullPropertyInstance for null values since the 
            //      NullPropertyInstance does not expose a value. We will later copy it back to the value we generate for the null property.
            IEnumerable<PropertyInstance> primitiveProperties =
                primitiveValues.Select((pv, ix) => PayloadBuilder.Property("PrimitiveProperty" + ix, pv).CopyAnnotation<PropertyInstance, EntityModelTypeAnnotation>(pv));
            IEnumerable<PropertyInstance> complexProperties = complexValues.Select((cv, ix) => PayloadBuilder.Property("ComplexProperty" + ix, cv));
            IEnumerable<PropertyInstance> primitiveMultiValueProperties = primitiveMultiValues.Select((pmv, ix) => PayloadBuilder.Property("PrimitiveMultiValueProperty" + ix, pmv));
            IEnumerable<PropertyInstance> complexMultiValueProperties = complexMultiValues.Select((cmv, ix) => PayloadBuilder.Property("ComplexMultiValueProperty" + ix, cmv));

            PropertyInstance[][] propertyMatrix = new PropertyInstance[6][];
            propertyMatrix[0] = primitiveProperties.ToArray();
            propertyMatrix[1] = complexProperties.ToArray();
            propertyMatrix[2] = streamReferenceValues.ToArray();
            propertyMatrix[3] = primitiveMultiValueProperties.ToArray();
            propertyMatrix[4] = complexMultiValueProperties.ToArray();
            propertyMatrix[5] = navigationProperties.ToArray();

            IEnumerable<PropertyInstance[]> propertyCombinations = propertyMatrix.ColumnCombinations(0, 1, 6);

            int count = 0;
            foreach (PropertyInstance[] propertyCombination in propertyCombinations)
            {
                // build the entity type, add it to the model
                EdmEntityType generatedEntityType = null;
                string typeName = "PGEntityType" + count;
                EdmEntityContainer container = null;
                EdmEntitySet entitySet = null;
                if (model != null)
                {
                    // generate a new type with the auto-generated name, check that no type with this name exists and add the default key property to it.
                    Debug.Assert(model.FindDeclaredType(typeName) == null, "Entity type '" + typeName + "' already exists.");
                    generatedEntityType = new EdmEntityType("TestModel", typeName);
                    generatedEntityType.AddKeys(generatedEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    model.AddElement(generatedEntityType);
                    container = model.EntityContainer as EdmEntityContainer;

                    if (container == null)
                    {
                        container = new EdmEntityContainer("TestModel", "DefaultNamespace");
                        model.AddElement(container);
                    }

                    entitySet = container.AddEntitySet(typeName, generatedEntityType);
                }

                EntityInstance entityInstance = PayloadBuilder.Entity("TestModel." + typeName)
                    .Property("Id", PayloadBuilder.PrimitiveValue(count).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false)));

                for (int i = 0; i < propertyCombination.Length; ++i)
                {
                    PropertyInstance currentProperty = propertyCombination[i];
                    entityInstance.Add(currentProperty);

                    if (model != null)
                    {
                        if (entitySet == null)
                        {
                            entitySet = container.FindEntitySet(typeName) as EdmEntitySet;
                        }

                        switch (currentProperty.ElementType)
                        {
                            case ODataPayloadElementType.ComplexProperty:
                                ComplexProperty complexProperty = (ComplexProperty)currentProperty;
                                generatedEntityType.AddStructuralProperty(complexProperty.Name,
                                    complexProperty.Value.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType);
                                break;

                            case ODataPayloadElementType.PrimitiveProperty:
                                PrimitiveProperty primitiveProperty = (PrimitiveProperty)currentProperty;
                                if (primitiveProperty.Value == null)
                                {
                                    generatedEntityType.AddStructuralProperty(
                                       primitiveProperty.Name,
                                       PayloadBuilder.PrimitiveValueType(null));
                                }
                                else
                                {
                                    generatedEntityType.AddStructuralProperty(primitiveProperty.Name,
                                        primitiveProperty.Value.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType);
                                }
                                break;
                            case ODataPayloadElementType.NamedStreamInstance:
                                NamedStreamInstance streamProperty = (NamedStreamInstance)currentProperty;
                                generatedEntityType.AddStructuralProperty(streamProperty.Name, EdmPrimitiveTypeKind.Stream);
                                break;

                            case ODataPayloadElementType.EmptyCollectionProperty:
                                throw new NotImplementedException();

                            case ODataPayloadElementType.NavigationPropertyInstance:
                                NavigationPropertyInstance navigationProperty = (NavigationPropertyInstance)currentProperty;
                                var navProperty = generatedEntityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
                                {
                                    ContainsTarget = false,
                                    Name = navigationProperty.Name,
                                    Target = generatedEntityType,
                                    TargetMultiplicity = EdmMultiplicity.One
                                });
                                entitySet.AddNavigationTarget(navProperty, entitySet);
                                break;

                            case ODataPayloadElementType.ComplexMultiValueProperty:
                                ComplexMultiValueProperty complexMultiValueProperty = (ComplexMultiValueProperty)currentProperty;
                                generatedEntityType.AddStructuralProperty(complexMultiValueProperty.Name,
                                    complexMultiValueProperty.Value.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType);
                                break;

                            case ODataPayloadElementType.PrimitiveMultiValueProperty:
                                PrimitiveMultiValueProperty primitiveMultiValueProperty = (PrimitiveMultiValueProperty)currentProperty;
                                generatedEntityType.AddStructuralProperty(primitiveMultiValueProperty.Name,
                                     primitiveMultiValueProperty.Value.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType);
                                break;

                            default:
                                throw new NotSupportedException("Unsupported element type found : " + propertyCombination[i].ElementType);
                        }
                    }
                }

                if (generatedEntityType != null)
                {
                    entityInstance.AddAnnotation(new EntityModelTypeAnnotation(generatedEntityType.ToTypeReference(true)));
                }

                yield return new PayloadTestDescriptor() { PayloadElement = entityInstance, PayloadEdmModel = model };

                count++;
            }
        }
        private static IEdmModel GetEnumModel()
        {
            EdmModel model = new EdmModel();

            EdmEnumType enumType = new EdmEnumType("TestModel", "TestEnum");
            enumType.AddMember(new EdmEnumMember(enumType, "FirstValue", new EdmIntegerConstant(0)));
            enumType.AddMember(new EdmEnumMember(enumType, "FirstValue", new EdmIntegerConstant(1)));
            model.AddElement(enumType);

            model.SetAnnotationValue(model.FindDeclaredType("TestModel.TestEnum"), new ClrTypeAnnotation(typeof(TestEnum)));

            return model;
        }
Esempio n. 3
0
        private static ComplexInstanceCollection GetComplexInstanceCollection(IRandomNumberGenerator random, EdmModel model = null, ODataVersion version = ODataVersion.V4)
        {
            var complex = GetComplexInstance(random, model, version);
            int numinstances = random.ChooseFrom(new[] { 0, 1, 3 });
            var payload = new ComplexInstanceCollection(GenerateSimilarComplexInstances(random, complex, numinstances).ToArray());
            if (model != null)
            {
                var container = model.EntityContainersAcrossModels().Single() as EdmEntityContainer;
                var collectionType = new EdmCollectionType((model.FindDeclaredType(complex.FullTypeName) as EdmComplexType).ToTypeReference());

                var function = new EdmFunction(container.Namespace, "GetComplexInstances", collectionType.ToTypeReference());
                var functionImport = container.AddFunctionImport("GetComplexInstances", function);

                payload.AddAnnotation(new FunctionAnnotation() { FunctionImport = functionImport });
                payload.AddAnnotation(new DataTypeAnnotation() { EdmDataType = collectionType });
            }

            return payload;
        }
 internal static EdmModel OnModelExtending(EdmModel model)
 {
     var ns = model.DeclaredNamespaces.First();
     var product = model.FindDeclaredType(ns + "." + "Product");
     var products = EdmCoreModel.GetCollection(product.GetEdmTypeReference(isNullable: false));
     var mostExpensive = new EdmFunction(ns, "MostExpensive",
         EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Double, isNullable: false), isBound: true,
         entitySetPathExpression: null, isComposable: false);
     mostExpensive.AddParameter("bindingParameter", products);
     model.AddElement(mostExpensive);
     return model;
 }
Esempio n. 5
0
 private static ComplexProperty GetComplexProperty(IRandomNumberGenerator random, EdmModel model = null, ODataVersion version = ODataVersion.V4)
 {
     var instance = GetComplexInstance(random, model, version);
     var property = new ComplexProperty(instance.FullTypeName, instance);
     property.WithTypeAnnotation(model.FindDeclaredType(instance.FullTypeName));
     return property;
 }
Esempio n. 6
0
        private static PrimitiveValue GetPrimitiveValue(IRandomNumberGenerator random, EdmModel model = null)
        {
            var payload = random.ChooseFrom(TestValues.CreatePrimitiveValuesWithMetadata(true));
            
            if (model != null)
            {
                EdmEntityType entity = model.FindDeclaredType("AllPrimitiveTypesEntity") as EdmEntityType; 
                if (entity == null)
                {
                    entity = new EdmEntityType("TestModel", "AllPrimitiveTypesEntity");
                    entity.AddStructuralProperty("StringPropNullable", EdmPrimitiveTypeKind.String, true);
                    entity.AddStructuralProperty("StringProp", EdmPrimitiveTypeKind.String, false);
                    entity.AddStructuralProperty("Int32PropNullable", EdmPrimitiveTypeKind.Int32, true);
                    entity.AddStructuralProperty("Int32Prop", EdmPrimitiveTypeKind.Int32, false);
                    entity.AddStructuralProperty("BooleanPropNullable", EdmPrimitiveTypeKind.Boolean, true);
                    entity.AddStructuralProperty("BooleanProp", EdmPrimitiveTypeKind.Boolean, false);
                    entity.AddStructuralProperty("BytePropNullable", EdmPrimitiveTypeKind.Byte, true);
                    entity.AddStructuralProperty("ByteProp", EdmPrimitiveTypeKind.Byte, false);
                    entity.AddStructuralProperty("SBytePropNullable", EdmPrimitiveTypeKind.SByte, true);
                    entity.AddStructuralProperty("SByteProp", EdmPrimitiveTypeKind.SByte, false);
                    entity.AddStructuralProperty("Int16PropNullable", EdmPrimitiveTypeKind.Int16, true);
                    entity.AddStructuralProperty("Int16Prop", EdmPrimitiveTypeKind.Int16, false);
                    entity.AddStructuralProperty("DecimalPropNullable", EdmPrimitiveTypeKind.Decimal, true);
                    entity.AddStructuralProperty("DecimalProp", EdmPrimitiveTypeKind.Decimal, false);
                    entity.AddStructuralProperty("SinglePropNullable", EdmPrimitiveTypeKind.Single, true);
                    entity.AddStructuralProperty("SingleProp", EdmPrimitiveTypeKind.Single, false);
                    entity.AddStructuralProperty("Int64PropNullable", EdmPrimitiveTypeKind.Int64, true);
                    entity.AddStructuralProperty("Int64Prop", EdmPrimitiveTypeKind.Int64, false);
                    entity.AddStructuralProperty("DoublePropNullable", EdmPrimitiveTypeKind.Double, true);
                    entity.AddStructuralProperty("DoubleProp", EdmPrimitiveTypeKind.Double, false);
                    entity.AddStructuralProperty("BinaryPropNullable", EdmPrimitiveTypeKind.Binary, true);
                    entity.AddStructuralProperty("BinaryProp", EdmPrimitiveTypeKind.Binary, false);
                    entity.AddStructuralProperty("GuidPropNullable", EdmPrimitiveTypeKind.Guid, true);
                    entity.AddStructuralProperty("GuidProp", EdmPrimitiveTypeKind.Guid, false);
                    model.AddElement(entity);
                }

                payload.WithTypeAnnotation(entity);
            }

            return payload;
        }
Esempio n. 7
0
        /// <summary>
        /// Creates a set of interesting entity set instances along with metadata.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use.</param>
        /// <param name="model">If non-null, the method creates types as needed and adds them to the model.</param>
        /// <param name="withTypeNames">true if the payloads should specify type names.</param>
        /// <returns>List of test descriptors with interesting entity instances as payload.</returns>
        public static IEnumerable<PayloadTestDescriptor> CreateEntitySetTestDescriptors(
            EdmModel model, 
            bool withTypeNames)
        {
            EdmEntityType personType = null;
            EdmComplexType carType = null;
            var container = model.EntityContainer as EdmEntityContainer;
            if (container == null)
            {
                container = new EdmEntityContainer("TestModel", "DefaultNamespace");
                model.AddElement(container);
            }

            if (model != null)
            {
                personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType;
                carType = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType;
                
                // Create the metadata types for the entity instance used in the entity set
                if (carType == null)
                {
                    carType = new EdmComplexType("TestModel", "TFCar");
                    carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String);
                    carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String);
                    model.AddElement(carType);
                }
                
                if (personType == null)
                {
                    personType = new EdmEntityType("TestModel", "TFPerson");
                    var keyProperty = personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);
                    personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
                    personType.AddStructuralProperty("Car", carType.ToTypeReference());
                    personType.AddKeys(keyProperty);
                    model.AddElement(personType);
                    container.AddEntitySet("TFPerson", personType);
                }
            }

            ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null)
                .Property("Make", PayloadBuilder.PrimitiveValue("Ford"))
                .Property("Color", PayloadBuilder.PrimitiveValue("Blue"));

            EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null)
                .Property("Id", PayloadBuilder.PrimitiveValue(1))
                .Property("Name", PayloadBuilder.PrimitiveValue("John Doe"))
                .Property("Car", carInstance);

            // empty feed
            yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.EntitySet().WithTypeAnnotation(personType), PayloadEdmModel = model };
            // entity set with a single entity
            yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.EntitySet().Append(personInstance).WithTypeAnnotation(personType), PayloadEdmModel = model };
            // entity set with the person instance in the middle
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.EntitySet()
                    .Append(personInstance.GenerateSimilarEntries(2))
                    .Append(personInstance)
                    .Append(personInstance.GenerateSimilarEntries(1))
                    .WithTypeAnnotation(personType),
                PayloadEdmModel = model
            };
            // entity set with a single entity and a next link
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.EntitySet().Append(personInstance).NextLink(nextLink).WithTypeAnnotation(personType),
                PayloadEdmModel = model,
                SkipTestConfiguration = tc => tc.IsRequest
            };
            // entity set with a single entity and inline count
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.EntitySet().Append(personInstance).InlineCount(1).WithTypeAnnotation(personType),
                PayloadEdmModel = model,
                SkipTestConfiguration = tc => tc.IsRequest
            };
            // entity set with a single entity, a next link and inline count
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.EntitySet().Append(personInstance).NextLink(nextLink).InlineCount(1).WithTypeAnnotation(personType),
                PayloadEdmModel = model,
                SkipTestConfiguration = tc => tc.IsRequest
            };
            // entity set with a single entity, a next link and a negative inline count
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.EntitySet().Append(personInstance).NextLink(nextLink).InlineCount(-1).WithTypeAnnotation(personType),
                PayloadEdmModel = model,
                SkipTestConfiguration = tc => tc.IsRequest
            };
            // entity set containing many entities of types derived from the same base
            //yield return new PayloadTestDescriptor()
            //{
            //    PayloadElement = CreateDerivedEntitySetInstance(model, withTypeNames),
            //    PayloadEdmModel = model,
            //};
        }
Esempio n. 8
0
        /// <summary>
        /// Creates several PayloadTestDescriptors containing Batch Requests
        /// </summary>
        /// <param name="requestManager">Used for building the requests</param>
        /// <param name="model">The model to use for adding additional types.</param>
        /// <param name="withTypeNames">Whether or not to use full type names.</param>
        /// <returns>PayloadTestDescriptors</returns>
        public static IEnumerable<PayloadTestDescriptor> CreateBatchRequestTestDescriptors(
            IODataRequestManager requestManager,
            EdmModel model,
            bool withTypeNames = false)
        {
            ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager");
            EdmEntityType personType = null;
            EdmComplexType carType = null;
            EdmEntitySet personsEntitySet = null;
            EdmEntityContainer container = model.EntityContainer as EdmEntityContainer;

            if (model != null)
            {
                //TODO: Clone EdmModel
                //model = model.Clone();

                if (container == null)
                {
                    container = new EdmEntityContainer("TestModel", "DefaultContainer");
                    model.AddElement(container);
                }

                personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType;
                carType = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType;

                // Create the metadata types for the entity instance used in the entity set
                if (carType == null)
                {
                    carType = new EdmComplexType("TestModel", "TFCar");
                    model.AddElement(carType);
                    carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true);
                    carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true);
                }

                if (personType == null)
                {
                    personType = new EdmEntityType("TestModel", "TFPerson");
                    model.AddElement(personType);
                    personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true);
                    personType.AddStructuralProperty("Car", carType.ToTypeReference());
                    container.AddEntitySet("Customers", personType);
                }
                
                personsEntitySet = container.AddEntitySet("People", personType);
            }

            ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null)
                .Property("Make", PayloadBuilder.PrimitiveValue("Ford"))
                .Property("Color", PayloadBuilder.PrimitiveValue("Blue"));
            ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance)
                .WithTypeAnnotation(personType);

            EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null)
                .Property("Id", PayloadBuilder.PrimitiveValue(1))
                .Property("Name", PayloadBuilder.PrimitiveValue("John Doe"))
                .Property("Car", carInstance)
                .WithTypeAnnotation(personType);
                
            var carPropertyPayload = new PayloadTestDescriptor()
            {
                PayloadElement = carProperty,
                PayloadEdmModel = model
            };

            var emptyPayload = new PayloadTestDescriptor()
            {
                PayloadEdmModel = CreateEmptyEdmModel()
            };

            var personPayload = new PayloadTestDescriptor()
            {
                PayloadElement = personInstance,
                PayloadEdmModel = model
            };

            var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc"));
            var entityset = ODataUriBuilder.EntitySet(personsEntitySet);

            // Get operations
            var queryOperation1 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager);
            var queryOperation2 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager);

            // Post operation containing a complex property
            var postOperation = carPropertyPayload.InRequestOperation(HttpVerb.Post, new ODataUri(new ODataUriSegment[] {root, entityset}) , requestManager, MimeTypes.ApplicationJsonLight);
            // Delete operation with no payload
            var deleteOperation = emptyPayload.InRequestOperation(HttpVerb.Delete, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager);
            // Put operation where the payload is an EntityInstance
            var putOperation = personPayload.InRequestOperation(HttpVerb.Put, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager);

            // A changeset containing a delete with no payload and a put
            var twoOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { postOperation, deleteOperation }, requestManager);
            // A changeset containing a delete with no payload
            var oneOperationChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { deleteOperation }, requestManager);
            // A changeset containing a put, post and delete
            var threeOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { putOperation, postOperation, deleteOperation }, requestManager);
            // A changeset containing no operations
            var emptyChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { }, requestManager);

            // Empty Batch
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload()
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")),
                PayloadEdmModel = emptyPayload.PayloadEdmModel,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };

            // Single Operation
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1)
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };

            // Multiple Operations
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2)
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };

            // Single Changeset
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset)
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };

            // Multiple Changesets (different content types)
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, oneOperationChangeset, emptyChangeset)
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };

            // Operations and changesets
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, queryOperation1, oneOperationChangeset)
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };

            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, oneOperationChangeset, queryOperation2)
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };

            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2, twoOperationsChangeset, oneOperationChangeset)
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };

            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, threeOperationsChangeset, queryOperation2, twoOperationsChangeset, queryOperation1, oneOperationChangeset)
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };

            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, emptyChangeset, queryOperation1, threeOperationsChangeset, queryOperation2, oneOperationChangeset)
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_5")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            };
        }
Esempio n. 9
0
        /// <summary>
        /// Creates a set of interesting collections with complex items.
        /// </summary>
        /// <param name="model">The model to add complex types to.</param>
        /// <param name="withTypeNames">true if the complex value payloads should specify type names.</param>
        /// <param name="fullSet">true if all available complex collections should be returned, false if only the most interesting subset should be returned.</param>
        /// <returns>List of interesting collections.</returns>
        public static IEnumerable<ComplexMultiValue> CreateComplexCollections(EdmModel model, bool withTypeNames, bool fullSet = true)
        {
            List<ComplexMultiValue> results = new List<ComplexMultiValue>();

            string typeName;
            ComplexMultiValue complexCollection;
            EdmComplexType complexType = null;

            // Empty complex collection without model or typename cannot be recognized and will be treated as a primitive collection
            // (note that this is done by test infrastructure, not by the product, the product will simply report empty collection).
            // TODO: What about empty complex collection with type name but without model?
            typeName = "ComplexTypeForEmptyCollection";
            if (model != null)
            {
                complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                if (complexType == null)
                {
                    complexType = new EdmComplexType(NamespaceName, typeName);
                    model.AddElement(complexType);
                }

                complexCollection = PayloadBuilder.ComplexMultiValue(withTypeNames ? EntityModelUtils.GetCollectionTypeName(GetFullTypeName(typeName)) : null);
                complexCollection.WithTypeAnnotation(EdmCoreModel.GetCollection(complexType.ToTypeReference()).CollectionDefinition());
                if (!withTypeNames)
                {
                    complexCollection.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                }

                results.Add(complexCollection);
            }

            // Collection with multiple complex items with property
            typeName = "ComplexTypeForMultipleItemsCollection";
            if (model != null)
            {
                complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                if (complexType == null)
                {
                    complexType = new EdmComplexType(NamespaceName, typeName);
                    complexType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
                    model.AddElement(complexType);
                }
            }

            List<ComplexInstance> instanceList = new List<ComplexInstance>()
            {
                PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                    .PrimitiveProperty("Name", "Bart")
                    .WithTypeAnnotation(complexType),
                PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                    .PrimitiveProperty("Name", "Homer")
                    .WithTypeAnnotation(complexType),
                PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                    .PrimitiveProperty("Name", "Marge")
                    .WithTypeAnnotation(complexType)
            };

            if (!withTypeNames)
            {
                foreach (var item in instanceList)
                {
                    item.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                }
            }

            complexCollection = PayloadBuilder.ComplexMultiValue(withTypeNames ? EntityModelUtils.GetCollectionTypeName(GetFullTypeName(typeName)) : null);
            complexCollection.Items(instanceList);
            complexCollection.WithTypeAnnotation(complexType == null ? null : EdmCoreModel.GetCollection(new EdmComplexTypeReference(complexType, false)));
            if (!withTypeNames)
            {
                complexCollection.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
            }

            results.Add(complexCollection);

            // Collection with multiple complex items with properties of various types
            if (fullSet)
            {
                typeName = "ComplexTypeForMultipleComplexItemsCollection";
                string innerTypeName = "InnerComplexTypeForMultipleComplexItemsCollection";

                EdmComplexType innerComplexType = null;
                if (model != null)
                {
                    innerComplexType = model.FindDeclaredType(GetFullTypeName(innerTypeName)) as EdmComplexType;
                    if (innerComplexType == null)
                    {
                        innerComplexType = new EdmComplexType(NamespaceName, innerTypeName);
                        innerComplexType.AddStructuralProperty("Include", EdmPrimitiveTypeKind.Boolean);
                        model.AddElement(innerComplexType);
                    }

                    complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                    if (complexType == null)
                    {
                        complexType = new EdmComplexType(NamespaceName, typeName);
                        complexType.AddStructuralProperty("Rating", EdmPrimitiveTypeKind.Int32);
                        complexType.AddStructuralProperty("Complex", new EdmComplexTypeReference(innerComplexType, true));
                        model.AddElement(complexType);
                    }
                }

                instanceList = new List<ComplexInstance>()
                {
                    PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                        .PrimitiveProperty("Rating", 1)
                        .Property("Complex", (withTypeNames ? 
                                                PayloadBuilder.ComplexValue(GetFullTypeName(innerTypeName))
                                                : PayloadBuilder.ComplexValue(null).AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null }))
                                        .PrimitiveProperty("Include", false)
                                        .WithTypeAnnotation(innerComplexType))
                        .WithTypeAnnotation(complexType),
                    PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                        .PrimitiveProperty("Rating", 2)
                        .Property("Complex", (withTypeNames ? 
                                                PayloadBuilder.ComplexValue(GetFullTypeName(innerTypeName))
                                                : PayloadBuilder.ComplexValue(null).AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null }))
                                        .PrimitiveProperty("Include", true)
                                        .WithTypeAnnotation(innerComplexType))
                        .WithTypeAnnotation(complexType),
                    PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                        .PrimitiveProperty("Rating", 1)
                        .Property("Complex", new ComplexInstance(null, true))
                        .WithTypeAnnotation(complexType)
                };
                if (!withTypeNames)
                {
                    foreach (var item in instanceList)
                    {
                        item.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                    }
                }

                complexCollection = PayloadBuilder.ComplexMultiValue(withTypeNames ? EntityModelUtils.GetCollectionTypeName(GetFullTypeName(typeName)) : null)
                    .Items(instanceList);
                complexCollection.WithTypeAnnotation(complexType == null ? null : new EdmCollectionType(complexType.ToTypeReference()));
                if (!withTypeNames)
                {
                    complexCollection.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                }

                results.Add(complexCollection);
            }

            return results;
        }
Esempio n. 10
0
        /// <summary>
        /// Creates a set of interesting homogeneous collection values with primitive and complex items.
        /// </summary>
        /// <param name="model">The model to add complex types to.</param>
        /// <param name="withTypeNames">true if the collection and complex value payloads should specify type names.</param>
        /// <param name="withExpectedType">true if an expected type annotation should be added to the generated payload element; otherwise false.</param>
        /// <param name="withcollectionName">true if the collection is not in the top level, otherwise false</param>
        /// <param name="fullSet">true if all available collection values should be returned, false if only the most interesting subset should be returned.</param>
        /// <returns>List of interesting collection values.</returns>
        public static IEnumerable<ODataPayloadElementCollection> CreateHomogeneousCollectionValues(
            EdmModel model,
            bool withTypeNames,
            bool withExpectedType,
            bool withcollectionName,
            bool fullset = true)
        {
            IEdmTypeReference itemTypeAnnotationType = null;
            IEdmTypeReference collectionTypeAnnotationType = null;
            EdmOperationImport primitiveCollectionFunctionImport = null;
            EdmEntityContainer defaultContainer = null;

            if (model != null)
            {
                defaultContainer = model.FindEntityContainer("TestModel.TestContainer") as EdmEntityContainer;
                if (defaultContainer == null)
                {
                    defaultContainer = new EdmEntityContainer("TestModel", "TestContainer");
                    model.AddElement(defaultContainer);
                }

                itemTypeAnnotationType = EdmCoreModel.Instance.GetString(true);
                collectionTypeAnnotationType = EdmCoreModel.GetCollection(itemTypeAnnotationType);

                var function = new EdmFunction("TestModel", "PrimitiveCollectionFunctionImport", collectionTypeAnnotationType);
                model.AddElement(function);
                primitiveCollectionFunctionImport = defaultContainer.AddFunctionImport("PrimitiveCollectionFunctionImport", function);
            }

            // primitive collection with single null item
            yield return new PrimitiveCollection(PayloadBuilder.PrimitiveValue(null).WithTypeAnnotation(itemTypeAnnotationType))
                .WithTypeAnnotation(collectionTypeAnnotationType)
                .ExpectedCollectionItemType(withExpectedType ? itemTypeAnnotationType : null)
                .ExpectedFunctionImport(withExpectedType ? primitiveCollectionFunctionImport : null)
                .CollectionName(withcollectionName ? "PrimitiveCollectionFunctionImport" : null);

            // primitive collection with multiple items (same type)
            yield return new PrimitiveCollection(
                PayloadBuilder.PrimitiveValue("Vienna").WithTypeAnnotation(itemTypeAnnotationType),
                PayloadBuilder.PrimitiveValue("Prague").WithTypeAnnotation(itemTypeAnnotationType),
                PayloadBuilder.PrimitiveValue("Redmond").WithTypeAnnotation(itemTypeAnnotationType)
                )
                .WithTypeAnnotation(collectionTypeAnnotationType)
                .ExpectedCollectionItemType(withExpectedType ? itemTypeAnnotationType : null)
                .ExpectedFunctionImport(withExpectedType ? primitiveCollectionFunctionImport : null)
                .CollectionName(withcollectionName ? "PrimitiveCollectionFunctionImport" : null);

            if (fullset)
            {
                // empty primitive collection
                yield return new PrimitiveCollection()
                    .WithTypeAnnotation(collectionTypeAnnotationType)
                    .ExpectedCollectionItemType(withExpectedType ? itemTypeAnnotationType : null)
                    .ExpectedFunctionImport(withExpectedType ? primitiveCollectionFunctionImport : null)
                    .CollectionName(withcollectionName ? "PrimitiveCollectionFunctionImport" : null);

                // primitive collection with a single item
                yield return new PrimitiveCollection(
                    PayloadBuilder.PrimitiveValue("Vienna").WithTypeAnnotation(itemTypeAnnotationType)
                    ).WithTypeAnnotation(collectionTypeAnnotationType)
                    .ExpectedCollectionItemType(withExpectedType ? itemTypeAnnotationType : null)
                    .ExpectedFunctionImport(withExpectedType ? primitiveCollectionFunctionImport : null)
                    .CollectionName(withcollectionName ? "PrimitiveCollectionFunctionImport" : null);

                // primitive collection with multiple null items
                yield return new PrimitiveCollection(
                    PayloadBuilder.PrimitiveValue(null).WithTypeAnnotation(itemTypeAnnotationType),
                    PayloadBuilder.PrimitiveValue(null).WithTypeAnnotation(itemTypeAnnotationType),
                    PayloadBuilder.PrimitiveValue(null).WithTypeAnnotation(itemTypeAnnotationType)
                    ).WithTypeAnnotation(collectionTypeAnnotationType)
                    .ExpectedCollectionItemType(withExpectedType ? itemTypeAnnotationType : null)
                    .ExpectedFunctionImport(withExpectedType ? primitiveCollectionFunctionImport : null)
                    .CollectionName(withcollectionName ? "PrimitiveCollectionFunctionImport" : null);
            }

            string localPersonTypeName = "ComplexCollectionPersonItemType";
            string personTypeName = GetFullTypeName(localPersonTypeName);
            EdmOperationImport complexCollectionFunctionImport = null;
            if (model != null)
            {
                EdmComplexType complexItemType = model.FindDeclaredType(personTypeName) as EdmComplexType;
                if (complexItemType == null)
                {
                    complexItemType = new EdmComplexType(NamespaceName, localPersonTypeName);
                    complexItemType.AddStructuralProperty("FirstName", EdmCoreModel.Instance.GetString(true));
                    complexItemType.AddStructuralProperty("LastName", EdmCoreModel.Instance.GetString(true));
                    model.AddElement(complexItemType);
                }

                itemTypeAnnotationType = complexItemType.ToTypeReference();
                collectionTypeAnnotationType = EdmCoreModel.GetCollection(itemTypeAnnotationType);
                complexCollectionFunctionImport = defaultContainer.FindOperationImports("ComplexCollectionFunctionImport").SingleOrDefault() as EdmOperationImport;
                if (complexCollectionFunctionImport == null)
                {
                    var complexCollectionFunction = new EdmFunction("TestModel", "ComplexCollectionFunctionImport", collectionTypeAnnotationType);
                    model.AddElement(complexCollectionFunction);
                    complexCollectionFunctionImport = defaultContainer.AddFunctionImport("ComplexCollectionFunctionImport", complexCollectionFunction);
                }
            }

            // complex collection with multiple complex values
            var complexInstance1 = PayloadBuilder.ComplexValue(withTypeNames ? personTypeName : null).Property("FirstName", PayloadBuilder.PrimitiveValue("Clemens")).Property("LastName", PayloadBuilder.PrimitiveValue("Kerer")).WithTypeAnnotation(itemTypeAnnotationType);
            var complexInstance2 = PayloadBuilder.ComplexValue(withTypeNames ? personTypeName : null).Property("FirstName", PayloadBuilder.PrimitiveValue("Vitek")).Property("LastName", PayloadBuilder.PrimitiveValue("Karas")).WithTypeAnnotation(itemTypeAnnotationType);
            if (!withTypeNames && model != null)
            {
                complexInstance1.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                complexInstance2.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
            }
            var complexInstanceCollection = new ComplexInstanceCollection(
                complexInstance1,
                complexInstance2
                ).WithTypeAnnotation(collectionTypeAnnotationType)
                .ExpectedCollectionItemType(withExpectedType ? itemTypeAnnotationType : null)
                .ExpectedFunctionImport(withExpectedType ? complexCollectionFunctionImport : null)
                .CollectionName(withcollectionName ? "ComplexCollectionFunctionImport" : null);

            yield return complexInstanceCollection;

            if (fullset)
            {
                // complex collection with a single complex value
                complexInstance1 = PayloadBuilder.ComplexValue(withTypeNames ? personTypeName : null)
                    .Property("FirstName", PayloadBuilder.PrimitiveValue("Clemens"))
                    .Property("LastName", PayloadBuilder.PrimitiveValue("Kerer"))
                    .WithTypeAnnotation(itemTypeAnnotationType);
                if (!withTypeNames && model != null)
                {
                    complexInstance1.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                }

                yield return new ComplexInstanceCollection(
                    complexInstance1
                    ).WithTypeAnnotation(collectionTypeAnnotationType)
                    .ExpectedCollectionItemType(withExpectedType ? itemTypeAnnotationType : null)
                    .ExpectedFunctionImport(withExpectedType ? complexCollectionFunctionImport : null)
                    .CollectionName(withcollectionName ? "ComplexCollectionFunctionImport" : null);

                string localCityTypeName = "ComplexCollectionCityItemType";
                IEdmTypeReference cityItemTypeAnnotation = null;
                if (model != null)
                {
                    EdmComplexType complexItemType = model.FindDeclaredType(GetFullTypeName(localCityTypeName)) as EdmComplexType;
                    if (complexItemType == null)
                    {
                        complexItemType = new EdmComplexType(NamespaceName, localCityTypeName);
                        complexItemType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true));
                        model.AddElement(complexItemType);
                    }
                    cityItemTypeAnnotation = complexItemType.ToTypeReference();
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Creates a set of interesting complex values along with metadata.
        /// </summary>
        /// <param name="model">If non-null, the method creates complex types for the complex values and adds them to the model.</param>
        /// <param name="withTypeNames">true if the complex value payloads should specify type names.</param>
        /// <param name="fullSet">true if all available complex values should be returned, false if only the most interesting subset should be returned.</param>
        /// <returns>List of interesting complex values.</returns>
        public static IEnumerable<ComplexInstance> CreateComplexValues(EdmModel model, bool withTypeNames, bool fullSet = true)
        {
            var complexValuesList = new List<ComplexInstance>();

            EdmComplexType complexType = null;
            EdmComplexType innerComplexType = null;
            string typeName;
            ComplexInstance complexValue;

            // Null complex value
            if (fullSet)
            {
                typeName = "NullComplexType";

                // Can't specify type name for a null complex value since the reader will not read it (in JSON it's not even in the payload anywhere)
                complexValue = new ComplexInstance(null, true);
                complexValuesList.Add(complexValue);
                if (model != null)
                {

                    complexType = (EdmComplexType)model.FindDeclaredType(GetFullTypeName(typeName));
                    if (complexType == null)
                    {
                        complexType = new EdmComplexType(NamespaceName, typeName);
                        model.AddElement(complexType);
                    }

                    complexValue.WithTypeAnnotation(new EdmComplexTypeReference(complexType, true));
                }
            }

            if (fullSet)
            {
                // Complex value with one number property
                typeName = "ComplexTypeWithNumberProperty";
                complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                        .PrimitiveProperty("numberProperty", 42);
                complexValuesList.Add(complexValue);
                if (model != null)
                {
                    complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                    if (complexType == null)
                    {
                        complexType = new EdmComplexType(NamespaceName, typeName);
                        complexType.AddStructuralProperty("numberProperty", EdmPrimitiveTypeKind.Int32);
                        model.AddElement(complexType);
                    }
                    complexValue.WithTypeAnnotation(complexType);
                }
            }

            // Complex value with three properties
            typeName = "ComplexTypeWithNumberStringAndNullProperty";
            complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                .PrimitiveProperty("number", 42)
                .PrimitiveProperty("string", "some")
                .PrimitiveProperty("null", null);
            complexValuesList.Add(complexValue);
            if (model != null)
            {
                complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                if (complexType == null)
                {
                    complexType = new EdmComplexType(NamespaceName, typeName);
                    complexType.AddStructuralProperty("number", EdmPrimitiveTypeKind.Int32);
                    complexType.AddStructuralProperty("string", EdmPrimitiveTypeKind.String);
                    complexType.AddStructuralProperty("null", EdmPrimitiveTypeKind.String);
                    model.AddElement(complexType);
                }

                complexValue.WithTypeAnnotation(complexType);
            }

            // Complex value with primitive and complex property
            typeName = "ComplexTypeWithPrimitiveAndComplexProperty";
            if (model != null)
            {
                innerComplexType = model.FindDeclaredType(GetFullTypeName("InnerComplexTypeWithStringProperty")) as EdmComplexType;
                if (innerComplexType == null)
                {
                    innerComplexType = new EdmComplexType(NamespaceName, "InnerComplexTypeWithStringProperty");
                    innerComplexType.AddStructuralProperty("foo", EdmPrimitiveTypeKind.String);
                    model.AddElement(innerComplexType);
                }
                complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                if (complexType == null)
                {
                    complexType = new EdmComplexType(NamespaceName, typeName);
                    complexType.AddStructuralProperty("number", EdmPrimitiveTypeKind.Int32);
                    complexType.AddStructuralProperty("complex", innerComplexType.ToTypeReference());
                    model.AddElement(complexType);
                }

            }

            complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                .PrimitiveProperty("number", 42)
                .Property("complex", (withTypeNames ?
                                        PayloadBuilder.ComplexValue("TestModel.InnerComplexTypeWithStringProperty")
                                        : (model != null ?
                                                PayloadBuilder.ComplexValue(null).AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null })
                                                : PayloadBuilder.ComplexValue(null)))
                    .PrimitiveProperty("foo", "bar")
                    .WithTypeAnnotation(innerComplexType));
            complexValuesList.Add(complexValue);
            complexValue.WithTypeAnnotation(complexType);

            // Complex value with spatial properties
            typeName = "ComplexTypeWithSpatialProperties";
            if (model != null)
            {
                complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                if (complexType == null)
                {
                    complexType = new EdmComplexType(NamespaceName, typeName);
                    complexType.AddStructuralProperty("geographyPoint", EdmPrimitiveTypeKind.GeographyPoint);
                    complexType.AddStructuralProperty("geometryPoint", EdmPrimitiveTypeKind.GeometryPoint);
                    model.AddElement(complexType);
                }
            }

            complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null)
                .PrimitiveProperty("geographyPoint", GeographyFactory.Point(32.0, -200.0).Build())
                .PrimitiveProperty("geometryPoint", GeometryFactory.Point(60.5, -50.0).Build());
            complexValuesList.Add(complexValue);
            complexValue.WithTypeAnnotation(complexType);

            // Complex value with deeply nested complex types
            if (fullSet)
            {
                int nesting = 7;
                var nestedComplexTypes = new List<EdmComplexType>();
                string typeNameBase = "NestedComplexType";

                if (model != null)
                {
                    for (int i = 0; i < nesting; ++i)
                    {
                        typeName = typeNameBase + i;
                        complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                        if (complexType == null)
                        {
                            complexType = new EdmComplexType(NamespaceName, typeName);
                            complexType.AddStructuralProperty("Property1", EdmPrimitiveTypeKind.Int32);
                            if (nestedComplexTypes.Any())
                            {
                                complexType.AddStructuralProperty("complex", nestedComplexTypes.Last().ToTypeReference());
                            }
                            model.AddElement(complexType);
                        }

                        nestedComplexTypes.Add(complexType);
                    }
                }

                complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeNameBase) + "0" : null)
                    .PrimitiveProperty("Property1", 0)
                    .WithTypeAnnotation(nestedComplexTypes.ElementAt(0));

                for (int j = 1; j < nesting; ++j)
                {
                    if (!withTypeNames && model != null)
                    {
                        complexValue.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                    }

                    complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeNameBase) + j : null)
                        .PrimitiveProperty("Property1", 0)
                        .Property("complex", complexValue);
                    complexValue.WithTypeAnnotation(nestedComplexTypes.ElementAt(j));
                }
                complexValuesList.Add(complexValue);
            }

            // Complex value with many primitive properties
            if (fullSet)
            {
                var primitiveValues = TestValues.CreatePrimitiveValuesWithMetadata(true);

                typeName = "ComplexTypeWithManyPrimitiveProperties";
                if (model != null)
                {
                    complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                    if (complexType == null)
                    {
                        complexType = new EdmComplexType(NamespaceName, typeName);
                        for (int i = 0; i < primitiveValues.Count; ++i)
                        {
                            complexType.AddStructuralProperty("property" + i, primitiveValues[i].GetAnnotation<EntityModelTypeAnnotation>().EdmModelType);
                        }

                        model.AddElement(complexType);
                    }
                }

                complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null).WithTypeAnnotation(complexType);
                for (int j = 0; j < primitiveValues.Count; ++j)
                {
                    complexValue.PrimitiveProperty("property" + j, primitiveValues[j].ClrValue);
                }

                complexValuesList.Add(complexValue);
            }

            // Complex value with collection properties
            if (fullSet)
            {
                var primitiveCollections = TestValues.CreatePrimitiveCollections(withTypeNames, true);
                var complexPropertyValue = complexValuesList.Last().DeepCopy();
                IEdmTypeReference complexPropertyType = null;

                typeName = "ComplexTypeWithCollectionProperties";
                if (model != null)
                {
                    complexType = model.FindDeclaredType(GetFullTypeName(typeName)) as EdmComplexType;
                    if (complexType == null)
                    {
                        complexType = new EdmComplexType(NamespaceName, typeName);
                        int i = 0;
                        for (; i < primitiveCollections.Count(); ++i)
                        {
                            complexType.AddStructuralProperty("property" + i, primitiveCollections.ElementAt(i).GetAnnotation<EntityModelTypeAnnotation>().EdmModelType);
                        }

                        complexPropertyType = complexPropertyValue.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType;
                        complexType.AddStructuralProperty("property" + i, EdmCoreModel.GetCollection(complexPropertyType));
                        model.AddElement(complexType);
                    }
                }

                complexValue = PayloadBuilder.ComplexValue(withTypeNames ? GetFullTypeName(typeName) : null).WithTypeAnnotation(complexType);
                int k = 0;
                for (; k < primitiveCollections.Count(); ++k)
                {
                    complexValue.Property("property" + k, primitiveCollections.ElementAt(k));
                }

                string complexCollectionTypeName = withTypeNames ? EntityModelUtils.GetCollectionTypeName(complexPropertyValue.FullTypeName) : null;
                var complexCollectionItem = PayloadBuilder.ComplexMultiValue(complexCollectionTypeName)
                        .Item(complexPropertyValue)
                        .WithTypeAnnotation(EdmCoreModel.GetCollection(complexPropertyType));
                if (!withTypeNames && model != null)
                {
                    complexPropertyValue.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                    complexCollectionItem.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                }
                complexValue.Property(
                    "property" + k,
                    complexCollectionItem);
                complexValuesList.Add(complexValue);
            }

            if (model != null)
            {
                if (!withTypeNames)
                {
                    foreach (var item in complexValuesList)
                    {
                        item.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null });
                    }
                }
                if (model.EntityContainer == null)
                {
                    model.AddElement(new EdmEntityContainer(NamespaceName, "DefaultContainer"));
                }
            }

            return complexValuesList;
        }
        public void SpatialPropertyErrorTest()
        {
            EdmModel model = new EdmModel();
            var container = new EdmEntityContainer("TestModel", "DefaultContainer");
            model.AddElement(container);

            var owningType = new EdmEntityType("TestModel", "OwningType");
            owningType.AddKeys(owningType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            owningType.AddStructuralProperty("TopLevelProperty", EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.GeographyPoint, true));
            model.AddElement(owningType);

            IEdmEntityType edmOwningType = (IEdmEntityType)model.FindDeclaredType("TestModel.OwningType");
            IEdmStructuralProperty edmTopLevelProperty = (IEdmStructuralProperty)edmOwningType.FindProperty("TopLevelProperty");

            PayloadReaderTestDescriptor.ReaderMetadata readerMetadata = new PayloadReaderTestDescriptor.ReaderMetadata(edmTopLevelProperty);
            string pointValue = SpatialUtils.GetSpatialStringValue(ODataFormat.Json, GeographyFactory.Point(33.1, -110.0).Build(), "Edm.GeographyPoint");

            var explicitPayloads = new[]
                {
                    new
                    {
                        Description = "Spatial value with type information and odata.type annotation - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.GeographyPoint\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.GeographyPoint\"," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\":" + pointValue +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_ODataTypeAnnotationInPrimitiveValue", JsonLightConstants.ODataTypeAnnotationName)
                    },
                    new
                    {
                        Description = "Spatial value with odata.type annotation - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.GeographyPoint\", " +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\":" + pointValue +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_ODataTypeAnnotationInPrimitiveValue", JsonLightConstants.ODataTypeAnnotationName)
                    },
                };

            var testDescriptors = explicitPayloads.Select(payload =>
            {
                return new NativeInputReaderTestDescriptor()
                {
                    DebugDescription = payload.Description,
                    PayloadKind = ODataPayloadKind.Property,
                    InputCreator = (tc) =>
                    {
                        return payload.Json;
                    },
                    PayloadEdmModel = model,

                    // We use payload expected result just as a convenient way to run the reader for the Property payload kind
                    // since the reading should always fail, we don't need anything to compare the results to.
                    ExpectedResultCallback = (tc) =>
                        new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                        {
                            ReaderMetadata = payload.ReaderMetadata,
                            ExpectedException = payload.ExpectedException,
                        },
                };
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
                {
                    testDescriptor.RunTest(testConfiguration);
                });
        }
        public void TopLevelPropertyTest()
        {
            var injectedProperties = new[]
                {
                    new
                    {
                        InjectedJSON = string.Empty,
                        ExpectedException = (ExpectedException)null
                    },
                    new
                    {
                        InjectedJSON = "\"@custom.annotation\": null",
                        ExpectedException = (ExpectedException)null
                    },
                    new
                    {
                        InjectedJSON = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataAnnotationNamespacePrefix + "unknown\": { }",
                        ExpectedException = (ExpectedException)null
                    },
                    new
                    {
                        InjectedJSON = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\": { }",
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataContextAnnotationName)
                    },
                    new
                    {
                        InjectedJSON = "\"@custom.annotation\": null, \"@custom.annotation\": 42",
                        ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicateAnnotationNotAllowed", "custom.annotation")
                    },
                };

            var payloads = new[]
                {
                    new
                    {
                        Json = "{{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue +
                            "{1}{0}" +
                        "}}",
                    },
                    new
                    {
                        Json = "{{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "{0}{1}" +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                        "}}",
                    },
                    new
                    {
                        Json = "{{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                            "{1}{0}" +
                        "}}",
                    },
                };

            EdmModel model = new EdmModel();
            var container = new EdmEntityContainer("TestModel", "DefaultContainer");
            model.AddElement(container);

            var owningType = new EdmEntityType("TestModel", "OwningType");
            owningType.AddKeys(owningType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            owningType.AddStructuralProperty("TopLevelProperty", EdmCoreModel.Instance.GetInt32(true));
            owningType.AddStructuralProperty("TopLevelSpatialProperty", EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.GeographyPoint, false));
            owningType.AddStructuralProperty("TopLevelCollectionProperty", EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(owningType);

            IEdmEntityType edmOwningType = (IEdmEntityType)model.FindDeclaredType("TestModel.OwningType");
            IEdmStructuralProperty edmTopLevelProperty = (IEdmStructuralProperty)edmOwningType.FindProperty("TopLevelProperty");
            IEdmStructuralProperty edmTopLevelSpatialProperty = (IEdmStructuralProperty)edmOwningType.FindProperty("TopLevelSpatialProperty");
            IEdmStructuralProperty edmTopLevelCollectionProperty = (IEdmStructuralProperty)edmOwningType.FindProperty("TopLevelCollectionProperty");

            PayloadReaderTestDescriptor.ReaderMetadata readerMetadata = new PayloadReaderTestDescriptor.ReaderMetadata(edmTopLevelProperty);
            PayloadReaderTestDescriptor.ReaderMetadata spatialReaderMetadata = new PayloadReaderTestDescriptor.ReaderMetadata(edmTopLevelSpatialProperty);
            PayloadReaderTestDescriptor.ReaderMetadata collectionReaderMetadata = new PayloadReaderTestDescriptor.ReaderMetadata(edmTopLevelCollectionProperty);

            var testDescriptors = payloads.SelectMany(payload => injectedProperties.Select(injectedProperty =>
            {
                return new NativeInputReaderTestDescriptor()
                {
                    PayloadKind = ODataPayloadKind.Property,
                    InputCreator = (tc) =>
                    {
                        string input = string.Format(payload.Json, injectedProperty.InjectedJSON, string.IsNullOrEmpty(injectedProperty.InjectedJSON) ? string.Empty : ",");
                        return input;
                    },
                    PayloadEdmModel = model,

                    // We use payload expected result just as a convenient way to run the reader for the Property payload kind.
                    // We validate whether the reading succeeds or fails, but not the actual read values (at least not here).
                    ExpectedResultCallback = (tc) =>
                        new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                        {
                            ReaderMetadata = readerMetadata,
                            ExpectedException = injectedProperty.ExpectedException,
                        }
                };
            }));

            var explicitPayloads = new[]
                {
                    new
                    {
                        Description = "Custom property annotation - should be ignored.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": null," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = (ExpectedException)null
                    },
                    new
                    {
                        Description = "Duplicate custom property annotation - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": null," +
                            "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": 42," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicateAnnotationForPropertyNotAllowed", "custom.annotation", "value")
                    },
                    new
                    {
                        Description = "Custom property annotation before odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": 42," +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_TopLevelPropertyAnnotationWithoutProperty", "value")
                    },
                    new
                    {
                        Description = "Custom instance annotation before odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"@custom.annotation\": 42," +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataNullAnnotationName)
                    },
                    new
                    {
                        Description = "OData property annotation before odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightUtils.GetPropertyAnnotationName("value", JsonLightConstants.ODataTypeAnnotationName) + "\": 42," +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedODataPropertyAnnotation", JsonLightConstants.ODataTypeAnnotationName)
                    },
                    new
                    {
                        Description = "OData instance annotation before odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataIdAnnotationName + "\": \"SomeId\"," +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataIdAnnotationName)
                    },
                    new
                    {
                        Description = "Regular property before odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"custom\": 42," +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_InvalidTopLevelPropertyName", "custom", JsonLightConstants.ODataValuePropertyName)
                    },
                    new
                    {
                        Description = "Custom instance annotation after odata.null - should work.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue + "," +
                            "\"@custom.annotation\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = (ExpectedException)null,
                    },
                    new
                    {
                        Description = "Custom instance annotation after odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue + "," +
                            "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_TopLevelPropertyAnnotationWithoutProperty", "value")
                    },
                    new
                    {
                        Description = "OData property annotation after odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue + "," +
                            "\"" + JsonLightUtils.GetPropertyAnnotationName("value", JsonLightConstants.ODataTypeAnnotationName) + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedODataPropertyAnnotation", JsonLightConstants.ODataTypeAnnotationName)
                    },
                    new
                    {
                        Description = "OData instance annotation after odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue + "," +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataTypeAnnotationName)
                    },
                    new
                    {
                        Description = "Regular property after odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": " + JsonLightConstants.ODataNullAnnotationTrueValue + "," +
                            "\"custom\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_NoPropertyAndAnnotationAllowedInNullPayload", "custom")
                    },
                    new
                    {
                        Description = "Invalid value (boolean false) for odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": false" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_InvalidValueForODataNullAnnotation", JsonLightConstants.ODataNullAnnotationName, JsonLightConstants.ODataNullAnnotationTrueValue)
                    },
                    new
                    {
                        Description = "Invalid value (integer) for odata.null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\": 2" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_InvalidValueForODataNullAnnotation", JsonLightConstants.ODataNullAnnotationName, JsonLightConstants.ODataNullAnnotationTrueValue)
                    },
                    new
                    {
                        Description = "Unrecognized odata property annotation - should be ignored.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightUtils.GetPropertyAnnotationName("value", JsonLightConstants.ODataAnnotationNamespacePrefix + "unknown") + "\": null," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = (ExpectedException)null
                    },
                    new
                    {
                        Description = "Custom property annotation after the property - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42," +
                            "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": null" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_PropertyAnnotationAfterTheProperty", "custom.annotation", "value")
                    },
                    new
                    {
                        Description = "OData property annotation.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.Int32\"," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = (ExpectedException)null
                    },
                    new
                    {
                        Description = "Duplicate type property.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.Int32\"," +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.String\"," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicateAnnotationNotAllowed", JsonLightConstants.ODataTypeAnnotationName)
                    },
                    new
                    {
                        Description = "Type information for top-level property - correct.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.Int32\"," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = (ExpectedException)null
                    },
                    new
                    {
                        Description = "Type information for top-level property - different kind - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Collection(Edm.Int32)\"," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "Collection(Edm.Int32)", "Primitive", "Collection")
                    },
                    new
                    {
                        Description = "Type information for top-level null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.Int32\"," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": null" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_TopLevelPropertyWithPrimitiveNullValue", JsonLightConstants.ODataNullAnnotationName, JsonLightConstants.ODataNullAnnotationTrueValue)
                    },
                    new
                    {
                        Description = "Unknown type information for top-level null - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Unknown\"," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": null" +
                        "}",
                        ReaderMetadata = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "Unknown", "Primitive", "Complex")
                    },
                    new
                    {
                        Description = "Invalid type information for top-level null - we don't allow null collections - should fail.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(Edm.Int32)\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Collection(Edm.Int32)\"," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\": null" +
                        "}",
                        ReaderMetadata = collectionReaderMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "value", "Collection(Edm.Int32)")
                    },
                    new
                    {
                        Description = "Type information for top-level spatial - should work.",
                        Json = "{ " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.GeographyPoint\", " +
                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.GeographyPoint\"," +
                            "\"" + JsonLightConstants.ODataValuePropertyName + "\":" + SpatialUtils.GetSpatialStringValue(ODataFormat.Json, GeographyFactory.Point(33.1, -110.0).Build()) +
                        "}",
                        ReaderMetadata = spatialReaderMetadata,
                        ExpectedException = (ExpectedException)null
                    },
                };

            testDescriptors = testDescriptors.Concat(explicitPayloads.Select(payload =>
            {
                return new NativeInputReaderTestDescriptor()
                {
                    PayloadKind = ODataPayloadKind.Property,
                    InputCreator = (tc) =>
                    {
                        return payload.Json;
                    },
                    PayloadEdmModel = model,

                    // We use payload expected result just as a convenient way to run the reader for the Property payload kind
                    // since the reading should always fail, we don't need anything to compare the results to.
                    ExpectedResultCallback = (tc) =>
                        new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                        {
                            ReaderMetadata = payload.ReaderMetadata,
                            ExpectedException = payload.ExpectedException,
                        },
                    DebugDescription = payload.Description
                };
            }));

            // Add a test descriptor to verify that we ignore odata.context in requests
            testDescriptors = testDescriptors.Concat(
                new NativeInputReaderTestDescriptor[]
                {
                    new NativeInputReaderTestDescriptor()
                    {
                        DebugDescription = "Top-level property with invalid name.",
                        PayloadKind = ODataPayloadKind.Property,
                        InputCreator = tc =>
                        {
                            return "{ " +
                                "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                "\"TopLevelProperty\": 42" +
                            "}";
                        },
                        PayloadEdmModel = model,
                        ExpectedResultCallback = tc =>
                            new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                            {
                                ReaderMetadata = readerMetadata,
                                ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_InvalidTopLevelPropertyName", "TopLevelProperty", "value")
                            },
                        SkipTestConfiguration = tc => !tc.IsRequest
                    }
                });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
                {
                    testDescriptor.RunTest(testConfiguration);
                });
        }
        private void BuildEntitySetsAndSingletons(InvocationContext context, EdmModel model)
        {
            var configuration = context.ApiContext.Configuration;
            foreach (var property in this.publicProperties)
            {
                if (configuration.IsPropertyIgnored(property.Name))
                {
                    continue;
                }

                var isEntitySet = IsEntitySetProperty(property);
                if (!isEntitySet)
                {
                    if (!IsSingletonProperty(property))
                    {
                        continue;
                    }
                }

                var propertyType = property.PropertyType;
                if (isEntitySet)
                {
                    propertyType = propertyType.GetGenericArguments()[0];
                }

                var entityType = model.FindDeclaredType(propertyType.FullName) as IEdmEntityType;
                if (entityType == null)
                {
                    // Skip property whose entity type has not been declared yet.
                    continue;
                }

                var container = model.EnsureEntityContainer(this.targetType);
                if (isEntitySet)
                {
                    if (container.FindEntitySet(property.Name) == null)
                    {
                        this.entitySetProperties.Add(property);
                        var addedEntitySet = container.AddEntitySet(property.Name, entityType);
                        this.addedNavigationSources.Add(addedEntitySet);
                    }
                }
                else
                {
                    if (container.FindSingleton(property.Name) == null)
                    {
                        this.singletonProperties.Add(property);
                        var addedSingleton = container.AddSingleton(property.Name, entityType);
                        this.addedNavigationSources.Add(addedSingleton);
                    }
                }
            }
        }
Esempio n. 15
0
        private static ComplexMultiValueProperty GetComplexMultiValueProperty(IRandomNumberGenerator random, EdmModel model = null, ODataVersion version = ODataVersion.V4)
        {
            
            int numinstances = random.ChooseFrom(new[] { 0, 1, 3 });
            var instance = GetComplexInstance(random, model, version);
            var instances = GenerateSimilarComplexInstances(random, instance, numinstances, true);
            var propertyName = "ComplexMultivalue" + instance.FullTypeName;
            var payload = new ComplexMultiValueProperty(propertyName,
                new ComplexMultiValue(propertyName, false, instances.ToArray()));
            if (model != null)
            {
                var entityDataType = instance.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType.Definition as IEdmEntityType;
                ExceptionUtilities.CheckObjectNotNull(entityDataType, "Complex Instance must have an EntityModelTypeAnnotation with an EntityDataType");
                var entityType = model.FindDeclaredType(entityDataType.FullName()) as EdmEntityType;

                ExceptionUtilities.CheckObjectNotNull(entityType, "entityType");
                if (entityType.FindProperty(propertyName) != null)
                {
                    entityType.AddStructuralProperty(propertyName, (model.FindDeclaredType(instance.FullTypeName) as EdmComplexType).ToTypeReference());
                }

                payload.WithTypeAnnotation(entityType);
            }

            return payload;
        }
Esempio n. 16
0
        void BuildRelation(EdmModel model)
        {
            string parentName = string.Empty;
            string refrenceName = string.Empty;
            string parentColName = string.Empty;
            string refrenceColName = string.Empty;
            EdmEntityType parent = null;
            EdmEntityType refrence = null;
            EdmNavigationPropertyInfo parentNav = null;
            EdmNavigationPropertyInfo refrenceNav = null;
            List<IEdmStructuralProperty> principalProperties = null;
            List<IEdmStructuralProperty> dependentProperties = null;

            using (DbAccess db = new DbAccess(this.ConnectionString))
            {
                db.ExecuteReader(this.RelationCommand, (reader) =>
                {
                    if (parentName != reader["ParentName"].ToString() || refrenceName != reader["RefrencedName"].ToString())
                    {
                        if (!string.IsNullOrEmpty(refrenceName))
                        {
                            parentNav.PrincipalProperties = principalProperties;
                            parentNav.DependentProperties = dependentProperties;
                            //var np = parent.AddBidirectionalNavigation(refrenceNav, parentNav);
                            //var parentSet = model.EntityContainer.FindEntitySet(parentName) as EdmEntitySet;
                            //var referenceSet = model.EntityContainer.FindEntitySet(refrenceName) as EdmEntitySet;
                            //parentSet.AddNavigationTarget(np, referenceSet);
                            var np = refrence.AddBidirectionalNavigation(parentNav, refrenceNav);
                            var parentSet = model.EntityContainer.FindEntitySet(parentName) as EdmEntitySet;
                            var referenceSet = model.EntityContainer.FindEntitySet(refrenceName) as EdmEntitySet;
                            referenceSet.AddNavigationTarget(np, parentSet);

                        }
                        parentName = reader["ParentName"].ToString();
                        refrenceName = reader["RefrencedName"].ToString();
                        parent = model.FindDeclaredType(string.Format("ns.{0}", parentName)) as EdmEntityType;
                        refrence = model.FindDeclaredType(string.Format("ns.{0}", refrenceName)) as EdmEntityType;
                        parentNav = new EdmNavigationPropertyInfo();
                        parentNav.Name = parentName;
                        parentNav.TargetMultiplicity = EdmMultiplicity.Many;
                        parentNav.Target = parent;
                        refrenceNav = new EdmNavigationPropertyInfo();
                        refrenceNav.Name = refrenceName;
                        refrenceNav.TargetMultiplicity = EdmMultiplicity.Many;
                        //refrenceNav.Target = refrence;
                        principalProperties = new List<IEdmStructuralProperty>();
                        dependentProperties = new List<IEdmStructuralProperty>();
                    }
                    principalProperties.Add(parent.FindProperty(reader["ParentColumnName"].ToString()) as IEdmStructuralProperty);
                    dependentProperties.Add(refrence.FindProperty(reader["RefreancedColumnName"].ToString()) as IEdmStructuralProperty);
                }, null, CommandType.Text);
                if (refrenceNav != null)
                {
                    parentNav.PrincipalProperties = principalProperties;
                    parentNav.DependentProperties = dependentProperties;

                    //var np1 = parent.AddBidirectionalNavigation(refrenceNav, parentNav);
                    //var parentSet1 = model.EntityContainer.FindEntitySet(parentName) as EdmEntitySet;
                    //var referenceSet1 = model.EntityContainer.FindEntitySet(refrenceName) as EdmEntitySet;
                    //parentSet1.AddNavigationTarget(np1, referenceSet1);

                    var np1 = refrence.AddBidirectionalNavigation(parentNav, refrenceNav);
                    var parentSet1 = model.EntityContainer.FindEntitySet(parentName) as EdmEntitySet;
                    var referenceSet1 = model.EntityContainer.FindEntitySet(refrenceName) as EdmEntitySet;
                    referenceSet1.AddNavigationTarget(np1, parentSet1);
                }

            }
        }
Esempio n. 17
0
        /// <summary>
        /// Creates several PayloadTestDescriptors containing Batch Responses
        /// </summary>
        /// <param name="requestManager">Used for building the requests/responses.</param>
        /// <param name="model">The model to use for adding additional types.</param>
        /// <param name="withTypeNames">Whether or not to use full type names.</param>
        /// <returns>PayloadTestDescriptors</returns>
        public static IEnumerable<PayloadTestDescriptor> CreateBatchResponseTestDescriptors(
            IODataRequestManager requestManager,
            EdmModel model,
            bool withTypeNames = false)
        {
            EdmEntityType personType = null;
            EdmComplexType carType = null;

            if (model != null)
            {
                //TODO: CLONE for EdmModel
                //model = model.Clone();

                personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType;
                carType = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType;

                // Create the metadata types for the entity instance used in the entity set
                if (carType == null)
                {
                    carType = new EdmComplexType("TestModel", "TFCar");
                    model.AddElement(carType);
                    carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true);
                    carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true);
                }

                if (personType == null)
                {
                    personType = new EdmEntityType("TestModel", "TFPerson");
                    model.AddElement(personType);
                    personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true);
                    personType.AddStructuralProperty("Car", carType.ToTypeReference());

                    EdmEntityContainer container = (EdmEntityContainer) model.EntityContainer;
                    if (container == null)
                    {
                        container = new EdmEntityContainer("TestModel", "DefaultContainer");
                        model.AddElement(container);
                        container.AddEntitySet("Customers", personType);
                        container.AddEntitySet("TFPerson", personType);
                    }
                }
            }

            ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null)
                .Property("Make", PayloadBuilder.PrimitiveValue("Ford"))
                .Property("Color", PayloadBuilder.PrimitiveValue("Blue"));
            ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance)
                .WithTypeAnnotation(carType);

            EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null)
                .Property("Id", PayloadBuilder.PrimitiveValue(1))
                .Property("Name", PayloadBuilder.PrimitiveValue("John Doe"))
                .Property("Car", carInstance)
                .WithTypeAnnotation(personType);

            ODataErrorPayload errorInstance = PayloadBuilder.Error("ErrorCode")
                .Message("ErrorValue")
                .InnerError(
                    PayloadBuilder.InnerError().Message("InnerErrorMessage").StackTrace("InnerErrorStackTrace").TypeName("InnerErrorTypeName"));
            
            var carPropertyPayload = new PayloadTestDescriptor()
            {
                PayloadElement = carProperty,
                PayloadEdmModel = model
            };

            var emptyPayload = new PayloadTestDescriptor()
            {
                PayloadEdmModel = CreateEmptyEdmModel()
            };

            var personPayload = new PayloadTestDescriptor()
            {
                // This payload will be serialised to JSON so we need the annotation to mark it as a response.
                PayloadElement = personInstance.AddAnnotation(new PayloadFormatVersionAnnotation() { Response = true, ResponseWrapper = true }),
                PayloadEdmModel = model
            };

            var errorPayload = new PayloadTestDescriptor()
            {
                PayloadElement = errorInstance,
                PayloadEdmModel = model,
            };

            // response operation with a status code of 5 containing a complex instance
            var carPropertyPayloadOperation = carPropertyPayload.InResponseOperation(5, requestManager);
            // response operation with no payload and a status code of 200
            var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager);
            // response operation with a status code of 418 containing an entity instance
            var personPayloadOperation = personPayload.InResponseOperation(418, requestManager, MimeTypes.ApplicationJsonLight);
            // response operation with a status code of 404 containing an error instance
            var errorPayloadOperation = errorPayload.InResponseOperation(404, requestManager);
            
            // changeset with multiple operations
            var twoOperationsChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation }, requestManager);
            // changesets with a single operation
            var oneOperationChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { personPayloadOperation }, requestManager);
            var oneErrorChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { errorPayloadOperation }, requestManager);
            // empty changeset
            var emptyChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { }, requestManager);
           
            // Empty Batch
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] {  })
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")),
                PayloadEdmModel = emptyPayload.PayloadEdmModel,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            };

            // Single Operation
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation })
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            };

            // Multiple Operations
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation, errorPayloadOperation, personPayloadOperation })
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            };

            // Single Changeset
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset })
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            };

            // Multiple Changesets
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, oneOperationChangeset })
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            };

            // Operations and changesets
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, carPropertyPayloadOperation, oneOperationChangeset })
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            };

            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, oneOperationChangeset, emptyPayloadOperation })
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            };

            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { errorPayloadOperation, carPropertyPayloadOperation, emptyPayloadOperation, twoOperationsChangeset, oneOperationChangeset })
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            };
            
            yield return new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(
                        new IMimePart[] { oneErrorChangeset, carPropertyPayloadOperation, emptyChangeset, emptyPayloadOperation, twoOperationsChangeset, personPayloadOperation, oneOperationChangeset, errorPayloadOperation })
                    .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            };   
        }