/// <summary>
        /// Examines input json string to ensure that it compiles with the JsonSchema definition. Any errors in the
        /// validation of the schema are returned via the errors out parameter.
        /// </summary>
        /// <param name="schema">Schemas definition used as a reference.</param>
        /// <param name="inputJson">Input json example to be validated</param>
        /// <param name="errors">Out parameter that provides any errors, warnings, or messages that were generated</param>
        /// <param name="expectedJson"></param>
        /// <returns></returns>
        public bool ValidateJsonCompilesWithSchema(JsonSchema schema, JsonExample inputJson, out ValidationError[] errors, JsonExample expectedJson = null, ValidationOptions options = null)
        {
            if (null == schema)
                throw new ArgumentNullException("schema");
            if (null == inputJson)
                throw new ArgumentNullException("inputJson");

            string collectionPropertyName = "value";
            if (null != inputJson.Annotation && null != inputJson.Annotation.CollectionPropertyName)
            {
                collectionPropertyName = inputJson.Annotation.CollectionPropertyName;
            }

            // If we didn't get an options, create a new one with some defaults provided by the annotation
            options = options ?? new ValidationOptions();
            options.AllowTruncatedResponses = (inputJson.Annotation ?? new CodeBlockAnnotation()).TruncatedResult;
            options.CollectionPropertyName = collectionPropertyName;

            return schema.ValidateJson(inputJson, out errors, this.registeredSchema, options, expectedJson);
        }
示例#2
0
        /// <summary>
        /// Validate the input json against the defined scehma when the instance was created.
        /// </summary>
        /// <param name="jsonInput">Input json to validate against schema</param>
        /// <param name="errors">Array of errors if the validation fails</param>
        /// <param name="otherSchemas"></param>
        /// <param name="options"></param>
        /// <param name="expectedJson"></param>
        /// <returns>True if validation was successful, otherwise false.</returns>
        public bool ValidateJson(JsonExample jsonInput, out ValidationError[] errors, Dictionary<string, JsonSchema> otherSchemas, ValidationOptions options, JsonExample expectedJson = null)
        {
            JContainer obj;
            try
            {
                var settings = new JsonSerializerSettings { DateParseHandling = DateParseHandling.None, NullValueHandling = NullValueHandling.Include, DefaultValueHandling = DefaultValueHandling.Include };
                obj = (JContainer)JsonConvert.DeserializeObject(jsonInput.JsonData, settings);
            }
            catch (Exception ex)
            {
                errors = new ValidationError[] { new ValidationError(ValidationErrorCode.JsonParserException, null, "Failed to parse json string: {0}. Json: {1}", ex.Message, jsonInput.JsonData) };
                return false;
            }

            var annotation = jsonInput.Annotation ?? new CodeBlockAnnotation();

            List<ValidationError> detectedErrors = new List<ValidationError>();

            bool expectErrorObject = (jsonInput.Annotation != null) && jsonInput.Annotation.ExpectError;

            // Check for an error response
            dynamic errorObject = obj["error"];
            if (null != errorObject && !expectErrorObject)
            {
                string code = errorObject.code;
                string message = errorObject.message;

                detectedErrors.Clear();
                detectedErrors.Add(new ValidationError(ValidationErrorCode.JsonErrorObject, null, "Error response received. Code: {0}, Message: {1}", code, message));
                errors = detectedErrors.ToArray();
                return false;
            }
            else if (expectErrorObject && null == errorObject)
            {
                detectedErrors.Clear();
                detectedErrors.Add(new ValidationError(ValidationErrorCode.JsonErrorObjectExpected, null, "Expected an error object response, but didn't receive one."));
                errors = detectedErrors.ToArray();
                return false;
            }

            // Check to see if this is a "collection" instance
            if (null != annotation && annotation.IsCollection)
            {
                this.ValidateCollectionObject(obj, annotation, otherSchemas, options.CollectionPropertyName, detectedErrors);
            }
            // otherwise verify the object matches this schema
            else
            {
                options = options ?? new ValidationOptions(annotation);
                if (null != expectedJson)
                {
                    var expectedJsonSchema = new JsonSchema(expectedJson.JsonData, expectedJson.Annotation);
                    options.ExpectedJsonSchema = expectedJsonSchema;
                    options.RequiredPropertyNames = expectedJsonSchema.ExpectedProperties.Keys.ToArray();
                }
                this.ValidateContainerObject(obj, options, otherSchemas, detectedErrors);
            }

            errors = detectedErrors.ToArray();
            return detectedErrors.Count == 0;
        }
示例#3
0
        /// <summary>
        /// Checks that the expected response of a method definition is valid with this resource.
        /// </summary>
        /// <param name="method"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        public bool ValidateExpectedResponse(MethodDefinition method, out ValidationError[] errors)
        {
            HttpParser parser = new HttpParser();
            var response = parser.ParseHttpResponse(method.ExpectedResponse);

            JsonExample example = new JsonExample(response.Body, method.ExpectedResponseMetadata);
            var otherSchemas = new Dictionary<string, JsonSchema>();
            return this.ValidateJson(example, out errors, otherSchemas, null);
        }
        /// <summary>
        /// Verify that the body of the actual response is consistent with the method definition and expected response parameters
        /// </summary>
        /// <param name="method">The MethodDefinition that generated the response.</param>
        /// <param name="actualResponse">The actual response from the service to validate.</param>
        /// <param name="expectedResponse">The prototype expected response from the service.</param>
        /// <param name="detectedErrors">A collection of errors that will be appended with any detected errors</param>
        private void VerifyResponseBody(HttpResponse actualResponse, HttpResponse expectedResponse, out ValidationError[] errors, ValidationOptions options = null)
        {
            List<ValidationError> detectedErrors = new List<ValidationError>();

            if (string.IsNullOrEmpty(actualResponse.Body) &&
                (expectedResponse != null && !string.IsNullOrEmpty(expectedResponse.Body)))
            {
                detectedErrors.Add(new ValidationError(ValidationErrorCode.HttpBodyExpected, null, "Body missing from response (expected response includes a body or a response type was provided)."));
            }
            else if (!string.IsNullOrEmpty(actualResponse.Body))
            {
                ValidationError[] schemaErrors;
                if (this.ExpectedResponseMetadata == null ||
                    (string.IsNullOrEmpty(this.ExpectedResponseMetadata.ResourceType) &&
                     (expectedResponse != null && !string.IsNullOrEmpty(expectedResponse.Body))))
                {
                    detectedErrors.Add(new ValidationError(ValidationErrorCode.ResponseResourceTypeMissing, null, "Expected a response, but resource type on method is missing: {0}", this.Identifier));
                }
                else
                {
                    var otherResources = this.SourceFile.Parent.ResourceCollection;
                    if (
                        !otherResources.ValidateResponseMatchesSchema(
                            this,
                            actualResponse,
                            expectedResponse,
                            out schemaErrors, 
                            options))
                    {
                        detectedErrors.AddRange(schemaErrors);
                    }
                }

                var responseValidation = actualResponse.IsResponseValid(
                    this.SourceFile.DisplayName,
                    this.SourceFile.Parent.Requirements);
                detectedErrors.AddRange(responseValidation.Messages);
            }

            errors = detectedErrors.ToArray();
        }
示例#5
0
 public bool ValidateNoBrokenLinks(bool includeWarnings, out ValidationError[] errors)
 {
     string[] files;
     return this.ValidateNoBrokenLinks(includeWarnings, out errors, out files);
 }
 public void AddResults(string actionName, ValidationError[] errors, ValidationOutcome? outcome = null)
 {
     this[actionName].AddResults(errors, outcome);
 }
        /// <summary>
        /// Validates the value of json according to an implicit schmea defined by expectedJson
        /// </summary>
        /// <param name="expectedResponseAnnotation"></param>
        /// <param name="actualResponseBodyJson"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        public bool ValidateJsonExample(CodeBlockAnnotation expectedResponseAnnotation, string actualResponseBodyJson, out ValidationError[] errors, ValidationOptions options = null)
        {
            List<ValidationError> newErrors = new List<ValidationError>();

            var resourceType = expectedResponseAnnotation.ResourceType;
            if (resourceType == "stream")
            {
                // No validation since we're streaming data
                errors = null;
                return true;
            }
            else
            {
                JsonSchema schema;
                if (string.IsNullOrEmpty(resourceType))
                {
                    schema = JsonSchema.EmptyResponseSchema;
                }
                else if (!this.registeredSchema.TryGetValue(resourceType, out schema))
                {
                    newErrors.Add(new ValidationWarning(ValidationErrorCode.ResponseResourceTypeMissing, null, "Missing required resource: {0}. Validation limited to basics only.", resourceType));
                    // Create a new schema based on what's avaiable in the json
                    schema = new JsonSchema(actualResponseBodyJson, new CodeBlockAnnotation { ResourceType = expectedResponseAnnotation.ResourceType });
                }

                ValidationError[] validationJsonOutput;
                this.ValidateJsonCompilesWithSchema(schema, new JsonExample(actualResponseBodyJson, expectedResponseAnnotation), out validationJsonOutput, options: options);

                newErrors.AddRange(validationJsonOutput);
                errors = newErrors.ToArray();
                return errors.Length == 0;
            }
        }
示例#8
0
 public void RecordError(ValidationError error)
 {
     if (null != error)
         System.Diagnostics.Debug.WriteLine(error.ErrorText);
 }
 public new bool Scan(out ValidationError[] errors)
 {
     this.HasScanRun = true;
     this.TransformMarkdownIntoBlocksAndLinks(this.Markdown);
     return this.ParseMarkdownBlocks(out errors);
 }
 public ValidationMessageEventArgs(ValidationError message)
 {
     this.Message = message;
 }
 /// <summary>
 /// Logs out a validation message.
 /// </summary>
 /// <param name="message">Message.</param>
 protected void LogMessage(ValidationError message)
 {
     var eventHandler = this.NewMessage;
     if (null != eventHandler)
     {
         eventHandler(this, new ValidationMessageEventArgs(message));
     }
     this.Messages.Add(message);
 }
示例#12
0
        /// <summary>
        /// Run post processing on the collection of elements found inside this doc file.
        /// </summary>
        /// <param name="elements"></param>
        /// <param name="postProcessingErrors"></param>
        private void PostProcessFoundElements(List<object> elements, out ValidationError[] postProcessingErrors)
        {
            /*
            if FoundMethods == 1 then
              Attach all tables found in the document to the method.

            else if FoundMethods > 1 then
              Table.Type == ErrorCodes
                - Attach errors to all methods in the file
              Table.Type == PathParameters
                - Find request with matching parameters
              Table.Type == Query String Parameters
                - Request may not have matching parameters, because query string parameters may not be part of the request
              Table.Type == Header Parameters
                - Find request with matching parameters
              Table.Type == Body Parameters
                - Find request with matching parameters
             */

            List<ValidationError> detectedErrors = new List<ValidationError>();

            var elementsFoundInDocument = elements as IList<object> ?? elements.ToList();

            var foundMethods = from s in elementsFoundInDocument
                               where s is MethodDefinition
                               select (MethodDefinition)s;

            var foundResources = from s in elementsFoundInDocument
                                 where s is ResourceDefinition
                                 select (ResourceDefinition)s;

            var foundTables = from s in elementsFoundInDocument
                                   where s is TableDefinition
                                   select (TableDefinition)s;

            this.PostProcessAuthScopes(elementsFoundInDocument);
            PostProcessResources(foundResources, foundTables);
            this.PostProcessMethods(foundMethods, foundTables, detectedErrors);

            postProcessingErrors = detectedErrors.ToArray();
        }
示例#13
0
        /// <summary>
        /// Convert blocks of text found inside the markdown file into things we know how to work
        /// with (methods, resources, examples, etc).
        /// </summary>
        /// <param name="errors"></param>
        /// <returns></returns>
        protected bool ParseMarkdownBlocks(out ValidationError[] errors)
        {
            List<ValidationError> detectedErrors = new List<ValidationError>();

            string methodTitle = null;
            string methodDescription = null;

            Block previousHeaderBlock = null;

            List<object> foundElements = new List<object>();

            Stack<Config.DocumentHeader> headerStack = new Stack<Config.DocumentHeader>();
            for (int i = 0; i < this.OriginalMarkdownBlocks.Length; i++)
            {
                var block = this.OriginalMarkdownBlocks[i];

                this.ContentOutline.Add(string.Format("{0} - {1}", block.BlockType, this.PreviewOfBlockContent(block)));

                // Capture GitHub Flavored Markdown Bookmarks
                if (IsHeaderBlock(block, 6))
                {
                    this.AddBookmarkForHeader(block.Content);
                    this.AddHeaderToHierarchy(headerStack, block);
                }

                // Capture h1 and/or p element to be used as the title and description for items on this page
                if (IsHeaderBlock(block))
                {
                    methodTitle = block.Content;
                    methodDescription = null;       // Clear this because we don't want new title + old description
                    detectedErrors.Add(new ValidationMessage(null, "Found title: {0}", methodTitle));
                }
                else if (block.BlockType == BlockType.p)
                {
                    if (null == previousHeaderBlock)
                    {
                        detectedErrors.Add(new ValidationWarning(ValidationErrorCode.MissingHeaderBlock, null, "Paragraph text found before a valid header: {0}", this.DisplayName));
                    }
                    else if (IsHeaderBlock(previousHeaderBlock))
                {
                    methodDescription = block.Content;
                    detectedErrors.Add(new ValidationMessage(null, "Found description: {0}", methodDescription));
                }
                }
                else if (block.BlockType == BlockType.html)
                {
                    // If the next block is a codeblock we've found a metadata + codeblock pair
                    Block nextBlock = null;
                    if (i + 1 < this.OriginalMarkdownBlocks.Length)
                    {
                        nextBlock = this.OriginalMarkdownBlocks[i + 1];
                    }
                    if (null != nextBlock && nextBlock.BlockType == BlockType.codeblock)
                    {
                        // html + codeblock = likely request or response!
                        ItemDefinition definition = null;
                        try
                        {
                            definition = this.ParseCodeBlock(block, nextBlock);
                        }
                        catch (Exception ex)
                        {
                            detectedErrors.Add(new ValidationError(ValidationErrorCode.MarkdownParserError, this.DisplayName, ex.Message));
                        }

                        if (null != definition)
                        {
                            detectedErrors.Add(new ValidationMessage(null, "Found code block: {0} [{1}]", definition.Title, definition.GetType().Name));
                            definition.Title = methodTitle;
                            definition.Description = methodDescription;

                            if (!foundElements.Contains(definition))
                            {
                                foundElements.Add(definition);
                            }
                        }
                    }
                    else if (null == this.Annotation)
                    {
                        // See if this is the page-level annotation
                        var annotation = this.ParsePageAnnotation(block);
                        if (null != annotation)
                        {
                            this.Annotation = annotation;
                            if (string.IsNullOrEmpty(this.Annotation.Title))
                            {
                                this.Annotation.Title = (from b in this.OriginalMarkdownBlocks where IsHeaderBlock(b, 1) select b.Content).FirstOrDefault();
                            }
                        }
                    }
                }
                else if (block.BlockType == BlockType.table_spec)
                {
                    Block blockBeforeTable = (i - 1 >= 0) ? this.OriginalMarkdownBlocks[i - 1] : null;
                    if (null == blockBeforeTable) continue;

                    ValidationError[] parseErrors;
                    var table = TableSpecConverter.ParseTableSpec(block, previousHeaderBlock, out parseErrors);
                    if (null != parseErrors) detectedErrors.AddRange(parseErrors);

                    detectedErrors.Add(new ValidationMessage(null, "Found table: {0}. Rows:\r\n{1}", table.Type,
                        (from r in table.Rows select JsonConvert.SerializeObject(r, Formatting.Indented)).ComponentsJoinedByString(" ,\r\n")));

                    foundElements.Add(table);
                }

                if (block.IsHeaderBlock())
                {
                    previousHeaderBlock = block;
                }
            }

            ValidationError[] postProcessingErrors;
            this.PostProcessFoundElements(foundElements, out postProcessingErrors);
            detectedErrors.AddRange(postProcessingErrors);

            errors = detectedErrors.ToArray();
            return !detectedErrors.Any(x => x.IsError);
        }
示例#14
0
        /// <summary>
        /// Checks all links detected in the source document to make sure they are valid.
        /// </summary>
        /// <param name="includeWarnings"></param>
        /// <param name="errors">Information about broken links</param>
        /// <param name="linkedDocFiles"></param>
        /// <returns>True if all links are valid. Otherwise false</returns>
        public bool ValidateNoBrokenLinks(bool includeWarnings, out ValidationError[] errors, out string[] linkedDocFiles)
        {
            if (!this.HasScanRun)
                throw new InvalidOperationException("Cannot validate links until Scan() is called.");

            List<string> linkedPages = new List<string>();

            var foundErrors = new List<ValidationError>();
            foreach (var link in this.MarkdownLinks)
            {
                if (null == link.def)
                {
                    foundErrors.Add(new ValidationError(ValidationErrorCode.MissingLinkSourceId, this.DisplayName, "Link specifies ID '{0}' which was not found in the document.", link.link_text));
                    continue;
                }

                string relativeFileName;
                var result = this.VerifyLink(this.FullPath, link.def.url, this.BasePath, out relativeFileName);
                switch (result)
                {
                    case LinkValidationResult.BookmarkSkipped:
                    case LinkValidationResult.ExternalSkipped:
                        if (includeWarnings)
                            foundErrors.Add(new ValidationWarning(ValidationErrorCode.LinkValidationSkipped, this.DisplayName, "Skipped validation of link '{1}' to URL '{0}'", link.def.url, link.link_text));
                        break;
                    case LinkValidationResult.FileNotFound:
                        foundErrors.Add(new ValidationError(ValidationErrorCode.LinkDestinationNotFound, this.DisplayName, "Destination missing for link '{1}' to URL '{0}'", link.def.url, link.link_text));
                        break;
                    case LinkValidationResult.ParentAboveDocSetPath:
                        foundErrors.Add(new ValidationError(ValidationErrorCode.LinkDestinationOutsideDocSet, this.DisplayName, "Destination outside of doc set for link '{1}' to URL '{0}'", link.def.url, link.link_text));
                        break;
                    case LinkValidationResult.UrlFormatInvalid:
                        foundErrors.Add(new ValidationError(ValidationErrorCode.LinkFormatInvalid, this.DisplayName, "Invalid URL format for link '{1}' to URL '{0}'", link.def.url, link.link_text));
                        break;
                    case LinkValidationResult.Valid:
                        foundErrors.Add(new ValidationMessage(this.DisplayName, "Link to URL '{0}' is valid.", link.def.url, link.link_text));
                        if (null != relativeFileName)
                        {
                            linkedPages.Add(relativeFileName);
                        }
                        break;
                    default:
                        foundErrors.Add(new ValidationError(ValidationErrorCode.Unknown, this.DisplayName, "{2}: for link '{1}' to URL '{0}'", link.def.url, link.link_text, result));
                        break;

                }

            }
            errors = foundErrors.ToArray();
            linkedDocFiles = linkedPages.Distinct().ToArray();
            return !(errors.WereErrors() || errors.WereWarnings());
        }
示例#15
0
        private bool ValidateCustomObject(JsonProperty[] properties, out ValidationError[] errors, Dictionary<string, JsonSchema> otherSchemas, ValidationOptions options)
        {
            List<string> missingProperties = new List<string>(this.ExpectedProperties.Keys);
            List<ValidationError> detectedErrors = new List<ValidationError>();
            foreach (var inputProperty in properties)
            {
                missingProperties.Remove(inputProperty.Name);
                this.ValidateProperty(inputProperty, otherSchemas, detectedErrors, new ValidationOptions());
            }

            this.CleanMissingProperties(options, missingProperties);

            errors = detectedErrors.ToArray();
            return detectedErrors.Count == 0;
        }
示例#16
0
 public static void LogMessage(ValidationError error)
 {
     var helper = GetLogger();
     helper.RecordError(error);
 }
示例#17
0
        public static ValidationError NewConsolidatedError(ValidationErrorCode code, ValidationError[] errors, string message, params object[] parameters)
        {
            var error = errors.All(err => err.IsWarning) ? new ValidationWarning(code, null, message, parameters) : new ValidationError(code, null, message, parameters);

            error.InnerErrors = errors;
            return error;
        }
        /// <summary>
        /// Validates that the actual response body matches the schema defined for the response and any additional constraints
        /// from the expected request (e.g. properties that are included in the expected response are required in the actual 
        /// response even if the metadata defines that the response is truncated)
        /// </summary>
        /// <param name="method"></param>
        /// <param name="actualResponse"></param>
        /// <param name="expectedResponse"></param>
        /// <param name="schemaErrors"></param>
        /// <returns></returns>
        internal bool ValidateResponseMatchesSchema(MethodDefinition method, HttpResponse actualResponse, HttpResponse expectedResponse, out ValidationError[] schemaErrors)
        {
            List<ValidationError> newErrors = new List<ValidationError>();

            var expectedResourceType = method.ExpectedResponseMetadata.ResourceType;

            switch (expectedResourceType)
            {
                case "stream":
                case "Stream":
                    // No validation since we're streaming data
                    schemaErrors = new ValidationError[0];
                    return true;
                case "string":
                case "String":
                case "Edm.String":
                case" Edm.string":
                    schemaErrors = new ValidationError[0];
                    return true;
            }

            // Get a reference of our JsonSchema that we're checking the response with
            var expectedResponseJson = (null != expectedResponse) ? expectedResponse.Body : null;
            JsonSchema schema = this.GetJsonSchema(expectedResourceType, newErrors, expectedResponseJson);

            if (null == schema)
            {
                newErrors.Add(new ValidationError(ValidationErrorCode.ResourceTypeNotFound, null, "Unable to locate a definition for resource type: {0}", expectedResourceType));
            }
            else
            {
                ValidationError[] validationJsonOutput;
                this.ValidateJsonCompilesWithSchema(schema, new JsonExample(actualResponse.Body, method.ExpectedResponseMetadata), out validationJsonOutput, (null != expectedResponseJson) ? new JsonExample(expectedResponseJson) : null);
                newErrors.AddRange(validationJsonOutput);
            }

            schemaErrors = newErrors.ToArray();
            return !schemaErrors.WereWarningsOrErrors();
        }
        /// <summary>
        /// Convert a tablespec block into one of our internal object model representations
        /// </summary>
        /// <param name="tableSpecBlock"></param>
        /// <param name="lastHeaderBlock"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        public TableDefinition ParseTableSpec(Block tableSpecBlock, Block lastHeaderBlock, out ValidationError[] errors)
        {
            List<ValidationError> discoveredErrors = new List<ValidationError>();
            List<ItemDefinition> items = new List<ItemDefinition>();

            var tableShape = tableSpecBlock.Table;

            TableDecoder decoder = new TableDecoder { Type = TableBlockType.Unknown };
            string headerText = null;
            // Try matching based on header
            if (null != lastHeaderBlock && null != lastHeaderBlock.Content)
            {
                headerText = lastHeaderBlock.Content;
                var matchingDecoder = FindDecoderFromHeaderText(headerText);
                if (null != matchingDecoder)
                    decoder = matchingDecoder;
            }

            // Try matching based on shape
            if (decoder.Type == TableBlockType.Unknown && null != tableSpecBlock.Table)
            {
                var matchingDecoder = FindDecoderFromShape(tableShape);
                if (null != matchingDecoder)
                    decoder = matchingDecoder;
            }

            switch (decoder.Type)
            {
                case TableBlockType.ErrorCodes:
                    items.AddRange(ParseErrorTable(tableShape, decoder));
                    break;

                case TableBlockType.PathParameters:
                    items.AddRange(ParseParameterTable(tableShape, ParameterLocation.Path, decoder));
                    break;

                case TableBlockType.ResourcePropertyDescriptions:
                case TableBlockType.RequestObjectProperties:
                case TableBlockType.ResponseObjectProperties:
                    items.AddRange(ParseParameterTable(tableShape, ParameterLocation.JsonObject, decoder));
                    break;
                case TableBlockType.ResourceNavigationPropertyDescriptions:
                    items.AddRange(ParseParameterTable(tableShape, ParameterLocation.JsonObject, decoder, true));
                    break;

                case TableBlockType.HttpHeaders:
                    items.AddRange(ParseParameterTable(tableShape, ParameterLocation.Header, decoder));
                    break;

                case TableBlockType.QueryStringParameters:
                    items.AddRange(ParseParameterTable(tableShape, ParameterLocation.QueryString, decoder));
                    break;

                case TableBlockType.EnumerationValues:
                    items.AddRange(ParseEnumerationTable(tableShape, decoder));
                    break;

                case TableBlockType.AuthScopes:
                    items.AddRange(ParseAuthScopeTable(tableShape, decoder));
                    break;

                case TableBlockType.Unknown:
                    discoveredErrors.Add(new ValidationMessage(null, "Ignored unclassified table: headerText='{0}', tableHeaders='{1}'", headerText, tableShape.ColumnHeaders != null ? tableShape.ColumnHeaders.ComponentsJoinedByString(",") : "null"));
                    break;
                default:
                    discoveredErrors.Add(new ValidationMessage(null, "Ignored table: classification='{2}', headerText='{0}', tableHeaders='{1}'", headerText, tableShape.ColumnHeaders != null ? tableShape.ColumnHeaders.ComponentsJoinedByString(",") : "null", decoder.Type));
                    break;
            }

            errors = discoveredErrors.ToArray();

            return new TableDefinition(decoder.Type, items, headerText);
        }
 public void AddResult(string actionName, ValidationError error, ValidationOutcome? outcome = null )
 {
     this[actionName].AddResults(new ValidationError[] { error }, outcome);
 }
示例#21
0
        /// <summary>
        /// Validates that a particular HttpResponse matches the method definition and optionally the expected response.
        /// </summary>
        /// <param name="method">Method definition that was used to generate a request.</param>
        /// <param name="actualResponse">Actual response from the service (this is what we validate).</param>
        /// <param name="expectedResponse">Prototype response (expected) that shows what a valid response should look like.</param>
        /// <param name="scenario">A test scenario used to generate the response, which may include additional parameters to verify.</param>
        /// <param name="errors">A collection of errors, warnings, and verbose messages generated by this process.</param>
        public void ValidateResponse(HttpResponse actualResponse, HttpResponse expectedResponse, ScenarioDefinition scenario, out ValidationError[] errors, ValidationOptions options = null)
        {
            if (null == actualResponse) throw new ArgumentNullException("actualResponse");

            List<ValidationError> detectedErrors = new List<ValidationError>();

            // Verify the request is valid (headers, etc)
            this.VerifyHttpRequest(detectedErrors);

            // Verify that the expected response headers match the actual response headers
            ValidationError[] httpErrors;
            if (null != expectedResponse && !expectedResponse.ValidateResponseHeaders(actualResponse, out httpErrors, (null != scenario) ? scenario.AllowedStatusCodes : null))
            {
                detectedErrors.AddRange(httpErrors);
            }

            // Verify the actual response body is correct according to the schema defined for the response
            ValidationError[] bodyErrors;
            this.VerifyResponseBody(actualResponse, expectedResponse, out bodyErrors, options);
            detectedErrors.AddRange(bodyErrors);

            // Verify any expectations in the scenario are met
            if (null != scenario)
            {
                scenario.ValidateExpectations(actualResponse, detectedErrors);
            }

            errors = detectedErrors.ToArray();
        }
            public void AddResults(ValidationError[] errors, ValidationOutcome? outcome = null)
            {
                if (errors.Length == 0)
                    return;

                this.Errors.AddRange(errors);
                if (outcome.HasValue)
                    this.Outcome = outcome.Value;
            }
示例#23
0
        /// <summary>
        /// Read the contents of the file into blocks and generate any resource or method definitions from the contents
        /// </summary>
        public bool Scan(out ValidationError[] errors)
        {
            this.HasScanRun = true;
            List<ValidationError> detectedErrors = new List<ValidationError>();

            try
            {
                this.TransformMarkdownIntoBlocksAndLinks(this.GetContentsOfFile());
            }
            catch (IOException ioex)
            {
                detectedErrors.Add(new ValidationError(ValidationErrorCode.ErrorOpeningFile, this.DisplayName, "Error reading file contents: {0}", ioex.Message));
                errors = detectedErrors.ToArray();
                return false;
            }
            catch (Exception ex)
            {
                detectedErrors.Add(new ValidationError(ValidationErrorCode.ErrorReadingFile, this.DisplayName, "Error reading file contents: {0}", ex.Message));
                errors = detectedErrors.ToArray();
                return false;
            }

            return this.ParseMarkdownBlocks(out errors);
        }