public void ShouldThrowIfElementContentIsNotPrimitive()
        {
            // Comment: not the most intuitive error message if a user runs into this scenario.
            Action testSubject = () => ReadAnnotation("<m:annotation term=\"my.namespace.term\" m:type=\"Edm.Decimal\"><m:element>42</m:element></m:annotation>");

            testSubject.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.XmlReaderExtension_InvalidNodeInStringValue("Element"));
        }
        public void AnnotationWithStringAttributeAndElementContentShouldThrow()
        {
            // Note: even if the values specified in the attribute and in the element content are the same, we still throw (since otherwise we have to do a string equality check every time this appears).
            Action testSubject = () => ReadAnnotation("<m:annotation term=\"my.namespace.term\" string=\"value\">value</m:annotation>");

            testSubject.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.AtomInstanceAnnotation_AttributeValueNotationUsedOnNonEmptyElement("string"));
        }
        public void IfTermIsDefinedInMetadataAndWireTypeIsPresentThenIncompatibleTypesShouldThrow()
        {
            var addressType = this.AddMyModelAddressComplexTypeToModel();

            this.model.AddElement(new EdmTerm("Namespace", "DefinedTerm", new EdmComplexTypeReference(addressType, /*isNullable*/ false)));
            this.model.AddElement(new EdmComplexType("Other", "IncompatibleType"));

            // The expected type from the term definition in the model is "MyModel.Address", but the payload type is specified as "Other.IncompatibleType".
            Action testSubject = () => this.ReadAnnotation(
                @"<m:annotation term=""Namespace.DefinedTerm"" m:type=""#Other.IncompatibleType"">
                    <d:StreetNumber>123</d:StreetNumber>
                    <d:StreetName>Main St</d:StreetName>
                 </m:annotation>");

            testSubject.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ValidationUtils_IncompatibleType("Other.IncompatibleType", "MyModel.Address"));
        }
        /// <summary>
        /// Add a custom 'IUriLiteralParser' which will be called to parse a value of the given EdmType during the UriParsing proccess.
        /// </summary>
        /// <param name="edmTypeReference">The EdmType the Uri literal parser can parse.</param>
        /// <param name="customUriLiteralParser">The custom uri type parser to add.</param>
        /// <exception cref="ArgumentNullException"><paramref name="customUriLiteralParser"/> is null.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="edmTypeReference"/> is null.</exception>
        /// <exception cref="ODataException">Another Uri literal parser is already registered for the given EdmType</exception>
        public static void AddCustomUriLiteralParser(IEdmTypeReference edmTypeReference, IUriLiteralParser customUriLiteralParser)
        {
            ExceptionUtils.CheckArgumentNotNull(customUriLiteralParser, "customUriLiteralParser");
            ExceptionUtils.CheckArgumentNotNull(edmTypeReference, "edmTypeReference");

            lock (Locker)
            {
                if (IsEdmTypeAlreadyRegistered(edmTypeReference))
                {
                    throw new ODataException(ODataErrorStrings.UriCustomTypeParsers_AddCustomUriTypeParserEdmTypeExists(edmTypeReference.FullName()));
                }

                customUriLiteralParserPerEdmType.Add(
                    new UriLiteralParserPerEdmType
                {
                    EdmTypeOfUriParser = edmTypeReference,
                    UriLiteralParser   = customUriLiteralParser
                });
            }
        }
        public void AnnotationWithIntAttributeAndNonIntTypeShouldThrow()
        {
            Action testSubject = () => ReadAnnotation("<m:annotation term=\"my.namespace.term\" m:type=\"Edm.Double\" int=\"31\" />");

            testSubject.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.AtomInstanceAnnotation_AttributeValueNotationUsedWithIncompatibleType("Edm.Double", "int"));
        }
        public void ShouldThrowIfEmptyElementWithPrimitiveTypeSpecified()
        {
            Action testSubject = () => ReadAnnotation("<m:annotation term=\"my.namespace.term\" m:type=\"Edm.Decimal\" />");

            testSubject.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ReaderValidationUtils_CannotConvertPrimitiveValue("", "Edm.Decimal"));
        }
        public void ShouldThrowIfPrimitiveValueAttributeNotParseableAsThatType()
        {
            Action testSubject = () => ReadAnnotation("<m:annotation term=\"my.namespace.term\" int=\"42.5\" />");

            testSubject.ShouldThrow <ODataException>().WithMessage(ODataErrorStrings.ReaderValidationUtils_CannotConvertPrimitiveValue(42.5, "Edm.Int32"));
        }