Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/aspnetwebstack.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorraghuramn <ranadimi@microsoft.com>2012-09-15 03:37:41 +0400
committerraghuramn <ranadimi@microsoft.com>2012-09-24 21:48:38 +0400
commit062399f30f077caa26947be4ae1d525df8227b97 (patch)
tree114471333216dc47a76d3420f96aa6f51989f1ec
parentbc22f1bdcca80b04fe18abc19df46d2e026edfb8 (diff)
Enabling skipped ODataConventionBuilder test.
The earlier commit adding collection property did not fix the convention model builder fully. we throw a NotSupportedException if a complex type has a collection property. This commit fixes that.
-rw-r--r--src/System.Web.Http.OData/OData/Builder/ODataConventionModelBuilder.cs59
-rw-r--r--src/System.Web.Http.OData/Properties/SRResources.Designer.cs11
-rw-r--r--src/System.Web.Http.OData/Properties/SRResources.resx5
-rw-r--r--test/System.Web.Http.OData.Test/OData/Builder/Conventions/ODataConventionModelBuilderTests.cs159
4 files changed, 189 insertions, 45 deletions
diff --git a/src/System.Web.Http.OData/OData/Builder/ODataConventionModelBuilder.cs b/src/System.Web.Http.OData/OData/Builder/ODataConventionModelBuilder.cs
index 65ab320e..715153ff 100644
--- a/src/System.Web.Http.OData/OData/Builder/ODataConventionModelBuilder.cs
+++ b/src/System.Web.Http.OData/OData/Builder/ODataConventionModelBuilder.cs
@@ -196,17 +196,18 @@ namespace System.Web.Http.OData.Builder
.ToArray();
foreach (NavigationPropertyConfiguration propertyToBeRemoved in propertiesToBeRemoved)
{
+ entityToBePatched.RemoveProperty(propertyToBeRemoved.PropertyInfo);
+
if (propertyToBeRemoved.Multiplicity == EdmMultiplicity.Many)
{
- // complex collections are not supported.
- throw Error.NotSupported(SRResources.CollectionPropertiesNotSupported, propertyToBeRemoved.PropertyInfo.Name, propertyToBeRemoved.PropertyInfo.ReflectedType.FullName);
+ entityToBePatched.AddCollectionProperty(propertyToBeRemoved.PropertyInfo);
+ }
+ else
+ {
+ entityToBePatched.AddComplexProperty(propertyToBeRemoved.PropertyInfo);
}
- entityToBePatched.RemoveProperty(propertyToBeRemoved.PropertyInfo);
- entityToBePatched.AddComplexProperty(propertyToBeRemoved.PropertyInfo);
}
}
-
- AddComplexType(misconfiguredEntityType.ClrType);
}
}
@@ -271,32 +272,26 @@ namespace System.Web.Http.OData.Builder
else
{
// navigation property in a complex type ?
- if (!isCollection)
+ if (mappedType == null)
{
- if (mappedType == null)
- {
- // the user told nothing about this type and this is the first time we are seeing this type.
- // complex types cannot contain entities. So, treat it as complex property.
- complexType.AddComplexProperty(property);
- }
- else
- {
- if (_explicitlyAddedTypes.Contains(mappedType))
- {
- // user told us that this an entity type.
- throw Error.InvalidOperation(SRResources.ComplexTypeRefersToEntityType, complexType.ClrType.FullName, mappedType.ClrType.FullName, property.Name);
- }
- else
- {
- // we tried to be over-smart earlier and made the bad choice. so patch up now.
- ReconfigureEntityTypesAsComplexType(new IEntityTypeConfiguration[] { mappedType as IEntityTypeConfiguration });
- complexType.AddComplexProperty(property);
- }
- }
+ // the user told nothing about this type and this is the first time we are seeing this type.
+ // complex types cannot contain entities. So, treat it as complex property.
+ MapStructuralProperty(complexType, property, PropertyKind.Complex, isCollection);
+ }
+ else if (_explicitlyAddedTypes.Contains(mappedType))
+ {
+ // user told us that this is an entity type.
+ throw Error.InvalidOperation(SRResources.ComplexTypeRefersToEntityType, complexType.ClrType.FullName, mappedType.ClrType.FullName, property.Name);
}
else
{
- throw Error.NotSupported(SRResources.CollectionPropertiesNotSupported, property.Name, property.ReflectedType.FullName);
+ // we tried to be over-smart earlier and made the bad choice. so patch up now.
+ IEntityTypeConfiguration mappedTypeAsEntity = mappedType as IEntityTypeConfiguration;
+ Contract.Assert(mappedTypeAsEntity != null);
+
+ ReconfigureEntityTypesAsComplexType(new IEntityTypeConfiguration[] { mappedTypeAsEntity });
+
+ MapStructuralProperty(complexType, property, PropertyKind.Complex, isCollection);
}
}
}
@@ -306,7 +301,7 @@ namespace System.Web.Http.OData.Builder
{
Contract.Assert(type != null);
Contract.Assert(property != null);
- Contract.Assert(propertyKind == PropertyKind.Complex || propertyKind == PropertyKind.Primitive || propertyKind == PropertyKind.Collection);
+ Contract.Assert(propertyKind == PropertyKind.Complex || propertyKind == PropertyKind.Primitive);
if (!isCollection)
{
@@ -330,7 +325,7 @@ namespace System.Web.Http.OData.Builder
}
}
- // figures out the type of the property (primitive, complex, navigation, collecion) and the corresponding edm type if we have seen this type
+ // figures out the type of the property (primitive, complex, navigation) and the corresponding edm type if we have seen this type
// earlier or the user told us about it.
private PropertyKind GetPropertyType(PropertyInfo property, out bool isCollection, out IStructuralTypeConfiguration mappedType)
{
@@ -379,12 +374,16 @@ namespace System.Web.Http.OData.Builder
}
else
{
+ // if we know nothing about this type we assume it to be an entity
+ // and patch up later
return PropertyKind.Navigation;
}
}
}
else
{
+ // if we know nothing about this type we assume it to be an entity
+ // and patch up later
isCollection = false;
return PropertyKind.Navigation;
}
diff --git a/src/System.Web.Http.OData/Properties/SRResources.Designer.cs b/src/System.Web.Http.OData/Properties/SRResources.Designer.cs
index b9d46ea7..c92fb845 100644
--- a/src/System.Web.Http.OData/Properties/SRResources.Designer.cs
+++ b/src/System.Web.Http.OData/Properties/SRResources.Designer.cs
@@ -196,16 +196,7 @@ namespace System.Web.Http.OData.Properties {
}
/// <summary>
- /// Looks up a localized string similar to The property &apos;{0}&apos; on type &apos;{1}&apos; is a collection property. Collection properties are not supported..
- /// </summary>
- internal static string CollectionPropertiesNotSupported {
- get {
- return ResourceManager.GetString("CollectionPropertiesNotSupported", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The complex type &apos;{0}&apos; refers to the entity type &apos;{1}&apos; through the property &apos;{1}&apos;..
+ /// Looks up a localized string similar to The complex type &apos;{0}&apos; refers to the entity type &apos;{1}&apos; through the property &apos;{2}&apos;..
/// </summary>
internal static string ComplexTypeRefersToEntityType {
get {
diff --git a/src/System.Web.Http.OData/Properties/SRResources.resx b/src/System.Web.Http.OData/Properties/SRResources.resx
index 203d445c..47468f69 100644
--- a/src/System.Web.Http.OData/Properties/SRResources.resx
+++ b/src/System.Web.Http.OData/Properties/SRResources.resx
@@ -318,11 +318,8 @@
<data name="PrimitiveTypeRequired" xml:space="preserve">
<value>The type '{0}' is not a primitive type.</value>
</data>
- <data name="CollectionPropertiesNotSupported" xml:space="preserve">
- <value>The property '{0}' on type '{1}' is a collection property. Collection properties are not supported.</value>
- </data>
<data name="ComplexTypeRefersToEntityType" xml:space="preserve">
- <value>The complex type '{0}' refers to the entity type '{1}' through the property '{1}'.</value>
+ <value>The complex type '{0}' refers to the entity type '{1}' through the property '{2}'.</value>
</data>
<data name="MultipleAttributesFound" xml:space="preserve">
<value>The member '{0}' on type '{1}' contains multiple instances of the attribute '{2}'.</value>
diff --git a/test/System.Web.Http.OData.Test/OData/Builder/Conventions/ODataConventionModelBuilderTests.cs b/test/System.Web.Http.OData.Test/OData/Builder/Conventions/ODataConventionModelBuilderTests.cs
index 6cae7cd2..17b19f32 100644
--- a/test/System.Web.Http.OData.Test/OData/Builder/Conventions/ODataConventionModelBuilderTests.cs
+++ b/test/System.Web.Http.OData.Test/OData/Builder/Conventions/ODataConventionModelBuilderTests.cs
@@ -82,7 +82,7 @@ namespace System.Web.Http.OData.Builder.Conventions
version.AssertHasPrimitiveProperty(model, "Minor", EdmPrimitiveTypeKind.Int32, isNullable: false);
}
- [Theory(Skip = "ODataConventionModelBuilder always treats unknown element types are Entities")]
+ [Theory]
[InlineData(typeof(Version[]))]
[InlineData(typeof(IEnumerable<Version>))]
[InlineData(typeof(List<Version>))]
@@ -375,6 +375,163 @@ namespace System.Web.Http.OData.Builder.Conventions
Assert.NotNull(model);
}
+ [Fact]
+ public void ComplexType_Containing_EntityCollection_Throws()
+ {
+ Type entityType = CreateDynamicType(
+ new DynamicType
+ {
+ TypeName = "EntityType"
+ });
+
+ Type complexType = CreateDynamicType(
+ new DynamicType
+ {
+ TypeName = "ComplexTypeWithEntityCollection",
+ Properties =
+ {
+ new DynamicProperty
+ {
+ Name = "CollectionProperty",
+ Type = CreateCollectionType(entityType)
+ }
+ }
+ });
+
+ var modelBuilder = new ODataConventionModelBuilder();
+ modelBuilder.AddEntity(entityType);
+ modelBuilder.AddComplexType(complexType);
+
+ Assert.Throws<InvalidOperationException>(
+ () => modelBuilder.GetEdmModel(),
+ "The complex type 'SampleNamespace.ComplexTypeWithEntityCollection' refers to the entity type 'SampleNamespace.EntityType' through the property 'CollectionProperty'.");
+ }
+
+ [Fact]
+ public void ComplexType_Containing_ComplexCollection_works()
+ {
+ Type complexType = CreateDynamicType(
+ new DynamicType
+ {
+ TypeName = "ComplexTypeWithComplexCollection",
+ Properties =
+ {
+ new DynamicProperty
+ {
+ Name = "CollectionProperty",
+ Type = typeof(Version[])
+ }
+ }
+ });
+
+ var modelBuilder = new ODataConventionModelBuilder();
+ modelBuilder.AddComplexType(complexType);
+
+ var model = modelBuilder.GetEdmModel();
+
+ IEdmComplexType complexEdmType = model.AssertHasComplexType(complexType);
+ model.AssertHasComplexType(typeof(Version));
+ var collectionProperty = complexEdmType.DeclaredProperties.Where(p => p.Name == "CollectionProperty").SingleOrDefault();
+ Assert.NotNull(collectionProperty);
+ Assert.True(collectionProperty.Type.IsCollection());
+ Assert.Equal(collectionProperty.Type.AsCollection().ElementType().FullName(), "System.Version");
+ }
+
+ [Fact]
+ public void EntityType_Containing_ComplexCollection_Works()
+ {
+ Type entityType = CreateDynamicType(
+ new DynamicType
+ {
+ TypeName = "EntityTypeWithComplexCollection",
+ Properties =
+ {
+ new DynamicProperty
+ {
+ Name = "ID",
+ Type = typeof(int)
+ },
+ new DynamicProperty
+ {
+ Name = "CollectionProperty",
+ Type = typeof(Version[])
+ }
+ }
+ });
+
+ var modelBuilder = new ODataConventionModelBuilder();
+ modelBuilder.AddEntity(entityType);
+
+ var model = modelBuilder.GetEdmModel();
+
+ IEdmEntityType entityEdmType = model.AssertHasEntityType(entityType);
+ model.AssertHasComplexType(typeof(Version));
+ var collectionProperty = entityEdmType.DeclaredProperties.Where(p => p.Name == "CollectionProperty").SingleOrDefault();
+ Assert.NotNull(collectionProperty);
+ Assert.True(collectionProperty.Type.IsCollection());
+ Assert.Equal(collectionProperty.Type.AsCollection().ElementType().FullName(), "System.Version");
+ }
+
+ [Fact]
+ public void EntityType_Containing_ComplexTypeContainingComplexCollection_Works()
+ {
+ Type complexTypeWithComplexCollection = CreateDynamicType(
+ new DynamicType
+ {
+ TypeName = "ComplexType",
+ Properties =
+ {
+ new DynamicProperty
+ {
+ Name = "ComplexCollectionProperty",
+ Type = typeof(Version[])
+ }
+ }
+ });
+
+ Type entityType = CreateDynamicType(
+ new DynamicType
+ {
+ TypeName = "EntityTypeWithComplexCollection",
+ Properties =
+ {
+ new DynamicProperty
+ {
+ Name = "ID",
+ Type = typeof(int)
+ },
+ new DynamicProperty
+ {
+ Name = "ComplexProperty",
+ Type = complexTypeWithComplexCollection
+ }
+ }
+ });
+
+ var modelBuilder = new ODataConventionModelBuilder();
+ modelBuilder.AddEntity(entityType);
+
+ var model = modelBuilder.GetEdmModel();
+
+ IEdmEntityType entityEdmType = model.AssertHasEntityType(entityType);
+ model.AssertHasComplexType(typeof(Version));
+ IEdmComplexType edmComplexType = model.AssertHasComplexType(complexTypeWithComplexCollection);
+
+ var collectionProperty = edmComplexType.DeclaredProperties.Where(p => p.Name == "ComplexCollectionProperty").SingleOrDefault();
+ Assert.NotNull(collectionProperty);
+ Assert.True(collectionProperty.Type.IsCollection());
+ Assert.Equal(collectionProperty.Type.AsCollection().ElementType().FullName(), "System.Version");
+ }
+
+ private static Type CreateCollectionType(Type type)
+ {
+ Mock<Type> collectionType = new Mock<Type>();
+ collectionType.Setup(t => t.Namespace).Returns("SampleNamespace");
+ collectionType.Setup(t => t.FullName).Returns("SampleNamespace." + "CollectionType");
+ collectionType.Setup(t => t.GetInterfaces()).Returns(new Type[] { typeof(IEnumerable<>).MakeGenericType(type) });
+ return collectionType.Object;
+ }
+
private static Type CreateDynamicType(DynamicType dynamicType)
{
Mock<Type> type = new Mock<Type>();