public void ExerciseBadtypes()
        {
            IEdmModel model = new EdmModel();

            IEdmEntityType entityDef = new EdmEntityType("MyNamespace", "BadEntity");
            IEdmEntityTypeReference entityRef = new EdmEntityTypeReference(entityDef, false);
            IEdmComplexType complexDef = new EdmComplexType("MyNamespace", "BadComplex");
            IEdmComplexTypeReference complexRef = new EdmComplexTypeReference(complexDef, false);

            IEdmCollectionTypeReference badCollectionRef = entityRef.AsCollection();
            IEdmEntityTypeReference badEntityRef = complexRef.AsEntity();
            IEdmComplexTypeReference badComplexRef = entityRef.AsComplex();
            IEdmEntityReferenceTypeReference badEntityRefRef = entityRef.AsEntityReference();
            IEdmPrimitiveTypeReference badTemporal = entityRef.AsTemporal();
            IEdmPrimitiveTypeReference badDecimal = entityRef.AsDecimal();
            IEdmPrimitiveTypeReference badString = entityRef.AsString();
            IEdmPrimitiveTypeReference badSpatial = entityRef.AsSpatial();
            IEdmPrimitiveTypeReference badBinary = entityRef.AsBinary();
            IEdmPrimitiveTypeReference badPrimitive = entityRef.AsPrimitive();
            IEdmEnumTypeReference badEnum = entityRef.AsEnum();

            Assert.IsTrue(badCollectionRef.IsCollection(), "Bad collection is collection");

            Assert.IsTrue(badEntityRef.IsEntity(), "Bad Entity is Entity");
            Assert.AreEqual(0, badEntityRef.Key().Count(), "Bad Entity has no key");
            Assert.AreEqual("MyNamespace.BadComplex", badEntityRef.FullName(), "Bad named refs keep name");
            Assert.AreEqual(EdmSchemaElementKind.TypeDefinition, badEntityRef.EntityDefinition().SchemaElementKind, "Bad named type definitions are still type definitions");
            Assert.IsNull(badEntityRef.EntityDefinition().BaseType, "Bad Entity has no base type");
            Assert.AreEqual(Enumerable.Empty<IEdmProperty>(), badEntityRef.EntityDefinition().DeclaredProperties, "Bad structured types have no properties");
            Assert.IsFalse(badEntityRef.EntityDefinition().IsAbstract, "Bad structured types are not abstract");
            Assert.IsFalse(badEntityRef.EntityDefinition().IsOpen, "Bad structured types are not open");
            model.SetAnnotationValue(badEntityRef.Definition, "foo", "bar", new EdmStringConstant(new EdmStringTypeReference(EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.String), false), "baz"));
            Assert.AreEqual(1, model.DirectValueAnnotations(badEntityRef.Definition).Count(), "Bad Entity can hold annotations");
            Assert.IsNotNull(model.GetAnnotationValue(badEntityRef.Definition, "foo", "bar"), "Bad Entity can find annotations");
            Assert.AreEqual(EdmTermKind.Type, badEntityRef.EntityDefinition().TermKind, "EntityType has correct term kind");

            Assert.IsTrue(badComplexRef.IsComplex(), "Bad Complex is Bad");
            Assert.IsNull(badComplexRef.ComplexDefinition().FindProperty("PropertyName"), "Bad structured types return null for find property");

            Assert.AreEqual(EdmTypeKind.EntityReference, badEntityRefRef.TypeKind(), "Bad Entity Reference is Entity Reference");
            Assert.AreEqual(String.Empty, badEntityRefRef.EntityType().Name, "Bad Entity Reference has empty named EntityType");
            model.SetAnnotationValue(badEntityRefRef.Definition, "foo", "bar", new EdmStringConstant(new EdmStringTypeReference(EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.String), false), "baz"));
            Assert.AreEqual(1, model.DirectValueAnnotations(badEntityRefRef.Definition).Count(), "Bad Entity Reference can hold annotations");
            Assert.IsNotNull(model.GetAnnotationValue(badEntityRefRef.Definition, "foo", "bar"), "Bad Entity Reference can find annotations");

            Assert.AreEqual(EdmPrimitiveTypeKind.None, badPrimitive.PrimitiveKind(), "Bad Primitive has no primitive kind");
            Assert.AreEqual(EdmTypeKind.Primitive, badPrimitive.TypeKind(), "Bad Primitive has primitive type kind");
            Assert.AreEqual(EdmSchemaElementKind.TypeDefinition, badPrimitive.PrimitiveDefinition().SchemaElementKind, "Bad Primitive is still Type Definition");
            Assert.AreEqual("BadEntity", badPrimitive.PrimitiveDefinition().Name, "Bad Primitive retains name");
            Assert.AreEqual("MyNamespace", badPrimitive.PrimitiveDefinition().Namespace, "Bad Primitive retains namespace name");

            Assert.AreEqual(EdmTypeKind.Enum, badEnum.TypeKind(), "Bad enum has right kind.");
            Assert.AreEqual(EdmPrimitiveTypeKind.Int32, badEnum.EnumDefinition().UnderlyingType.PrimitiveKind, "Underlying type has correct kind.");
            Assert.AreEqual(0, badEnum.EnumDefinition().Members.Count(), "bad enum has no members.");
            Assert.AreEqual(false, badEnum.EnumDefinition().IsFlags, "bad enum not treated as bits.");
            Assert.AreEqual(EdmSchemaElementKind.TypeDefinition, badEnum.EnumDefinition().SchemaElementKind, "bad enum is type definition.");
            Assert.AreEqual("BadEntity", badEnum.EnumDefinition().Name, "Bad enum retains name");
            Assert.AreEqual("MyNamespace", badEnum.EnumDefinition().Namespace, "Bad enum retains namespace name");

            Assert.AreEqual(EdmErrorCode.TypeSemanticsCouldNotConvertTypeReference, badSpatial.Definition.Errors().First().ErrorCode, "Bad spatial has correct error code.");
        }
        public void CsdlWriterShouldFailWithGoodMessageWhenWritingInvalidXml()
        {
            var model = new EdmModel();
            model.SetEdmVersion(Microsoft.OData.Edm.Library.EdmConstants.EdmVersion4);
            var fredFlintstone = new EdmComplexType("Flintstones", "Fred");
            fredFlintstone.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
            model.AddElement(fredFlintstone);

            // set annotation which will be serialzed (because the value is an IEdmValue) with a name that doesn't match the xml spec for NCName.
            model.SetAnnotationValue(fredFlintstone, "sap", "-contentversion", new EdmStringConstant(EdmCoreModel.Instance.GetString(false), "hello"));

            Assert.AreEqual(1, model.DirectValueAnnotations(fredFlintstone).Count(), "Wrong # of Annotations on {0}.", fredFlintstone);

            var stringWriter = new StringWriter();
            var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings() { Indent = true });

            try
            {
                IEnumerable<EdmError> errors;
                model.TryWriteCsdl(xmlWriter, out errors);
                Assert.Fail("Excepted an exception when trying to serialize a direct value annotation which does not match the xml naming spec.");
            }
            catch (ArgumentException e)
            {
                Assert.AreEqual(e.Message, "Invalid name character in '-contentversion'. The '-' character, hexadecimal value 0x2D, cannot be included in a name.", "Expected exception message did not match.");
            }

            xmlWriter.Close();
        }
        public void ValidationShouldFailOnNonXmlValidAnnotation()
        {
            var model = new EdmModel();
            var fredFlintstone = new EdmComplexType("Flintstones", "Fred");
            fredFlintstone.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
            model.AddElement(fredFlintstone);

            // Set annnotation which would be serialized as an attribute to be a value that is invalid per the xml spec.
            model.SetAnnotationValue(fredFlintstone, "sap", "-content-version", new EdmStringConstant(EdmCoreModel.Instance.GetString(false), "hello"));

            Assert.AreEqual(1, model.DirectValueAnnotations(fredFlintstone).Count(), "Wrong # of Annotations on {0}.", fredFlintstone);

            IEnumerable<EdmError> errors;
            model.Validate(out errors);
            Assert.AreEqual(1, errors.Count(), "Model expected to be invalid.");
            EdmError error = errors.Single();
            Assert.AreEqual(error.ErrorCode, EdmErrorCode.InvalidName, "Unexpected error code");
            Assert.AreEqual(error.ErrorMessage, "The specified name is not allowed: '-content-version'.", "Unexpected error message");
        }
        public void ValidationShouldFailOnNonXmlValidAnnotationWhichWontBeSerialized()
        {
            var model = new EdmModel();
            var fredFlintstone = new EdmComplexType("Flintstones", "Fred");
            fredFlintstone.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
            model.AddElement(fredFlintstone);

            // Making the value of the annotation not an IEdmValue means that it won't be serialized out as an attribute annotation.
            // We should still fail on this anyway, since being strict now has fewer consequences than trying to introduce strictness later.
            model.SetAnnotationValue(fredFlintstone, "sap", "-content-version", 1);

            Assert.AreEqual(1, model.DirectValueAnnotations(fredFlintstone).Count(), "Wrong # of Annotations on {0}.", fredFlintstone);

            IEnumerable<EdmError> errors;
            model.Validate(out errors);
            Assert.AreEqual(1, errors.Count(), "Model expected to be invalid.");
            EdmError error = errors.Single();
            Assert.AreEqual(error.ErrorCode, EdmErrorCode.InvalidName, "Unexpected error code");
            Assert.AreEqual(error.ErrorMessage, "The specified name is not allowed: '-content-version'.", "Unexpected error message");
        }
        public void AnnotationNameWhichIsNotSimpleIdentifierShouldPassValidation()
        {
            var model = new EdmModel();
            model.SetEdmVersion(Microsoft.OData.Edm.Library.EdmConstants.EdmVersion4);
            var fredFlintstone = new EdmComplexType("Flintstones", "Fred");
            fredFlintstone.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
            model.AddElement(fredFlintstone);

            // set the annotation name to a value which is valid XML, but not a valid SimpleIdentifier.
            model.SetAnnotationValue(fredFlintstone, "sap", "content-version", new EdmStringConstant(EdmCoreModel.Instance.GetString(false), "hello"));

            Assert.AreEqual(1, model.DirectValueAnnotations(fredFlintstone).Count(), "Wrong # of Annotations on {0}.", fredFlintstone);

            IEnumerable<EdmError> errors;
            model.Validate(out errors);
            Assert.AreEqual(0, errors.Count(), "Model expected to be valid.");
        }