/// <summary> /// Convert an annotation and fenced code block in the documentation into something usable. Adds /// the detected object into one of the internal collections of resources, methods, or examples. /// </summary> /// <param name="metadata"></param> /// <param name="code"></param> public ItemDefinition ParseCodeBlock(Block metadata, Block code) { if (metadata.BlockType != BlockType.html) { throw new ArgumentException("metadata block does not appear to be metadata"); } if (code.BlockType != BlockType.codeblock) { throw new ArgumentException("code block does not appear to be code"); } var metadataJsonString = StripHtmlCommentTags(metadata.Content); CodeBlockAnnotation annotation = CodeBlockAnnotation.ParseMetadata(metadataJsonString, code); switch (annotation.BlockType) { case CodeBlockType.Resource: { ResourceDefinition resource; if (code.CodeLanguage.Equals("json", StringComparison.OrdinalIgnoreCase)) { resource = new JsonResourceDefinition(annotation, code.Content, this); } //else if (code.CodeLanguage.Equals("xml", StringComparison.OrdinalIgnoreCase)) //{ // //} else { throw new NotSupportedException("Unsupported resource definition language: " + code.CodeLanguage); } if (string.IsNullOrEmpty(resource.Name)) { throw new InvalidDataException("Resource definition is missing a name"); } this.resources.Add(resource); return(resource); } case CodeBlockType.Request: { var method = MethodDefinition.FromRequest(code.Content, annotation, this); if (string.IsNullOrEmpty(method.Identifier)) { method.Identifier = string.Format("{0} #{1}", this.DisplayName, this.requests.Count); } this.requests.Add(method); return(method); } case CodeBlockType.Response: { MethodDefinition pairedRequest = null; if (!string.IsNullOrEmpty(annotation.MethodName)) { // Look up paired request by name pairedRequest = (from m in this.requests where m.Identifier == annotation.MethodName select m).FirstOrDefault(); } else if (this.requests.Any()) { pairedRequest = Enumerable.Last(this.requests); } if (null == pairedRequest) { throw new InvalidOperationException(string.Format("Unable to locate the corresponding request for response block: {0}. Requests must be defined before a response.", annotation.MethodName)); } pairedRequest.AddExpectedResponse(code.Content, annotation); return(pairedRequest); } case CodeBlockType.Example: { var example = new ExampleDefinition(annotation, code.Content, this, code.CodeLanguage); this.examples.Add(example); return(example); } case CodeBlockType.Ignored: return(null); case CodeBlockType.SimulatedResponse: { var method = Enumerable.Last(this.requests); method.AddSimulatedResponse(code.Content, annotation); return(method); } case CodeBlockType.TestParams: { var method = Enumerable.Last(this.requests); method.AddTestParams(code.Content); return(method); } default: { var errorMessage = string.Format("Unable to parse metadata block or unsupported block type. Line {1}. Content: {0}", metadata.Content, metadata.LineStart); throw new NotSupportedException(errorMessage); } } }
/// <summary> /// Convert an annotation and fenced code block in the documentation into something usable. Adds /// the detected object into one of the internal collections of resources, methods, or examples. /// </summary> /// <param name="metadata"></param> /// <param name="code"></param> public ItemDefinition ParseCodeBlock(Block metadata, Block code) { if (metadata.BlockType != BlockType.html) { throw new ArgumentException("metadata block does not appear to be metadata"); } if (code.BlockType != BlockType.codeblock) { throw new ArgumentException("code block does not appear to be code"); } var metadataJsonString = metadata.Content.Substring(4, metadata.Content.Length - 9); var annotation = CodeBlockAnnotation.FromJson(metadataJsonString); switch (annotation.BlockType) { case CodeBlockType.Resource: { var resource = new ResourceDefinition(annotation, code.Content, this, code.CodeLanguage); this.resources.Add(resource); return(resource); } case CodeBlockType.Request: { var method = MethodDefinition.FromRequest(code.Content, annotation, this); if (string.IsNullOrEmpty(method.Identifier)) { method.Identifier = string.Format("{0} #{1}", this.DisplayName, this.requests.Count); } this.requests.Add(method); return(method); } case CodeBlockType.Response: { MethodDefinition pairedRequest = null; if (!string.IsNullOrEmpty(annotation.MethodName)) { // Look up paired request by name pairedRequest = (from m in this.requests where m.Identifier == annotation.MethodName select m).FirstOrDefault(); } else { pairedRequest = Enumerable.Last(this.requests); } if (null == pairedRequest) { throw new InvalidOperationException(string.Format("Unable to locate the corresponding request for response block: {0}. Requests must be defined before a response.", annotation.MethodName)); } pairedRequest.AddExpectedResponse(code.Content, annotation); return(pairedRequest); } case CodeBlockType.Example: { var example = new ExampleDefinition(annotation, code.Content, this, code.CodeLanguage); this.examples.Add(example); return(example); } case CodeBlockType.Ignored: return(null); case CodeBlockType.SimulatedResponse: { var method = Enumerable.Last(this.requests); method.AddSimulatedResponse(code.Content, annotation); return(method); } case CodeBlockType.TestParams: { var method = Enumerable.Last(this.requests); method.AddTestParams(code.Content); return(method); } default: throw new NotSupportedException("Unsupported block type: " + annotation.BlockType); } }