public void DuplicateInstanceCustomAnnotationShouldFail()
 {
     DuplicatePropertyNamesChecker duplicateChecker = new DuplicatePropertyNamesChecker(false, true);
     Action action = () => duplicateChecker.MarkPropertyAsProcessed("custom.name");
     action.ShouldNotThrow();
     action.ShouldThrow<ODataException>().WithMessage(ErrorStrings.DuplicatePropertyNamesChecker_DuplicateAnnotationNotAllowed("custom.name"));
 }
        /// <summary>
        /// Reads the odata.context annotation.
        /// </summary>
        /// <param name="payloadKind">The payload kind for which to read the context URI.</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker.</param>
        /// <param name="failOnMissingContextUriAnnotation">true if the method should fail if the context URI annotation is missing, false if that can be ignored.</param>
        /// <returns>The value of the context URI annotation.</returns>
        internal string ReadContextUriAnnotation(
            ODataPayloadKind payloadKind,
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker,
            bool failOnMissingContextUriAnnotation)
        {
            if (this.JsonReader.NodeType != JsonNodeType.Property)
            {
                if (!failOnMissingContextUriAnnotation || payloadKind == ODataPayloadKind.Unsupported)
                {
                    // Do not fail during payload kind detection
                    return null;
                }

                throw new ODataException(OData.Core.Strings.ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty);
            }

            // Must make sure the input odata.context has a '@' prefix
            string propertyName = this.JsonReader.GetPropertyName();
            if (string.CompareOrdinal(JsonLightConstants.ODataPropertyAnnotationSeparatorChar + ODataAnnotationNames.ODataContext, propertyName) != 0)
            {
                if (!failOnMissingContextUriAnnotation || payloadKind == ODataPayloadKind.Unsupported)
                {
                    // Do not fail during payload kind detection
                    return null;
                }

                throw new ODataException(OData.Core.Strings.ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty);
            }

            if (duplicatePropertyNamesChecker != null)
            {
                duplicatePropertyNamesChecker.MarkPropertyAsProcessed(propertyName);
            }

            // Read over the property name
            this.JsonReader.ReadNext();
            return this.JsonReader.ReadStringValue();
        }
        /// <summary>
        /// Parses JSON object property starting with the current position of the JSON reader.
        /// </summary>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use, it will also store the property annotations found.</param>
        /// <param name="readPropertyAnnotationValue">Function called to read property annotation value.</param>
        /// <param name="handleProperty">Function callback to handle to resule of parse property.</param>
        internal void ProcessProperty(
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker,
            Func<string, object> readPropertyAnnotationValue,
            Action<PropertyParsingResult, string> handleProperty)
        {
            Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null");
            Debug.Assert(readPropertyAnnotationValue != null, "readPropertyAnnotationValue != null");
            Debug.Assert(handleProperty != null, "handleProperty != null");
            this.AssertJsonCondition(JsonNodeType.Property);

            string propertyName;
            PropertyParsingResult propertyParsingResult = this.ParseProperty(duplicatePropertyNamesChecker, readPropertyAnnotationValue, out propertyName);

            while (propertyParsingResult == PropertyParsingResult.CustomInstanceAnnotation && this.ShouldSkipCustomInstanceAnnotation(propertyName))
            {
                // Make sure there's no duplicated instance annotation name even though we are skipping over it.
                duplicatePropertyNamesChecker.MarkPropertyAsProcessed(propertyName);

                // Skip over the instance annotation value and don't report it to the OM.
                this.JsonReader.SkipValue();

                propertyParsingResult = this.ParseProperty(duplicatePropertyNamesChecker, readPropertyAnnotationValue, out propertyName);
            }

            handleProperty(propertyParsingResult, propertyName);
            if (propertyParsingResult != PropertyParsingResult.EndOfObject)
            {
                duplicatePropertyNamesChecker.MarkPropertyAsProcessed(propertyName);
            }
        }
 public void MarkPropertyAsProcessedWithNoPropertyShouldWork()
 {
     DuplicatePropertyNamesChecker duplicateChecker = new DuplicatePropertyNamesChecker(false, true);
     duplicateChecker.MarkPropertyAsProcessed("property");
     Action odataAction = () => duplicateChecker.AddODataPropertyAnnotation("property", JsonLightConstants.ODataAnnotationNamespacePrefix + "name", null);
     odataAction.ShouldThrow<ODataException>().WithMessage(ErrorStrings.DuplicatePropertyNamesChecker_PropertyAnnotationAfterTheProperty(JsonLightConstants.ODataAnnotationNamespacePrefix + "name", "property"));
     Action customAction = () => duplicateChecker.AddCustomPropertyAnnotation("property", "custom.name");
     customAction.ShouldThrow<ODataException>().WithMessage(ErrorStrings.DuplicatePropertyNamesChecker_PropertyAnnotationAfterTheProperty("custom.name", "property"));
 }