-
Notifications
You must be signed in to change notification settings - Fork 54
Refactor Progress
The purpose of this document is to track the parser architecture refactor works on #114.
The main interest are ***Parser.h
files with the exception of the UriParser.h
file and the parse()
route. Necessary Markdown-AST processing files were already refactored and are not included in this list.
The list is ordered in the way the work should be done (first to last):
-
AssetParser.h
-
HeadersParser.h
-
PayloadParser.h
-
ParameterDefinitionParser.h
-
ParametersParser.h
-
ActionParser.h
-
ResourceParser.h
-
ResourceGroupParser.h
-
BlueprintParser.h
-
snowcrash.cc
Note: Section parsers are now solely a partial specifications of
SectionProcessor
.
Tests should be refactored alongside with the respective files mentioned above, as such they are not listed on this Wiki.
Note: Tests should no longer construct Markdown AST, instead parse blueprint snippets using provided
SectionParserHelper::parse()
- Leak test
- Performance test
- Regression test
Add benchmark results and analysis collected using the perf
target on a representative collection of blueprints (e.g. blueprints listed at Apiary.io homepage)
Using the perf
detect and fix any possible memory leaks.
In coordination with Protagonist – use pre and after refactor versions of protagonist to compare serialized outputs of parsing an input blueprint
- Resolved
Response payload with a Content-Type in signature when referencing a model with a Content-Type in its signature result in 2 Content-Type headers.
# A [/a]
+ model (type)
X
## GET
+ response 200 (type)
[A][]
OK.
_version: 2.0
metadata:
name:
description:
resourceGroups:
- name:
description:
resources:
- name: "A"
description:
uriTemplate: "/a"
model:
name: "A"
description:
headers:
- name: "Content-Type"
value: "type"
body: "X\n"
schema:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
- name: "Content-Type"
value: "type"
body: "X\n"
schema:
OK.
_version: 2.0
metadata:
name:
description:
resourceGroups:
- name:
description:
resources:
- name: "A"
description:
uriTemplate: "/a"
model:
name: "A"
description:
headers:
- name: "Content-Type"
value: "type"
body: "X\n"
schema:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
- name: "Content-Type"
value: "type"
- name: "Content-Type"
value: "type"
body: "X\n"
schema:
New behavior (actual) is OK and not considered a regression issue.
- Resolved
Recognize parameter when there is no description on its signature and remaining description is not a new node.
# GET /{id}
+ Parameters
+ id (required, string)
This is a description
OK.
warning: (5) ignoring unrecognized block :28:24;56:22
warning: (6) No parameters defined in parameters section :13:65
warning: (6) action is missing a response :0:13
warning: (1) expected API name, e.g. '# <API Name>' :0:13
{
"_version": "2.0",
"metadata": [],
"name": "",
"description": "",
"resourceGroups": [
{
"name": "",
"description": "",
"resources": [
{
"name": "",
"description": "",
"uriTemplate": "/{id}",
"model": {},
"parameters": [],
"actions": [
{
"name": "",
"description": "",
"method": "GET",
"parameters": [],
"examples": []
}
]
}
]
}
]
}
{
"_version": "2.0",
"metadata": [],
"name": "",
"description": "",
"resourceGroups": [
{
"name": "",
"description": "",
"resources": [
{
"name": "",
"description": "",
"uriTemplate": "/{id}",
"model": {},
"parameters": [],
"actions": [
{
"name": "",
"description": "",
"method": "GET",
"parameters": [
{
"name": "id",
"description": "\nThis is a description\n\n",
"type": "string",
"required": true,
"default": "",
"example": "",
"values": []
}
],
"examples": []
}
]
}
]
}
]
}
This is a regression which needs to be fixed.
- Resolved
Also, having
model
in list item sentence makes it aModelSectionType
@alikh31 is working on it.
FORMAT: 1A
# S
Hello
+ Response
# GET /
OK.
_version: 2.0
metadata:
- name: "FORMAT"
value: "1A"
name: "S"
description: "Hello\n\n"
resourceGroups:
_version: 2.0
metadata:
- name: "FORMAT"
value: "1A"
name: "S"
description: "Hello\n\n+ Response\n\n"
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
OK.
warning: (6) no response defined for 'GET /' :36:7
Neither actual or expected behavior is correct.
To get to the expect behavior clearly the steps are described here: https://github.com/apiaryio/snowcrash/pull/155#issuecomment-50970869
However the parser should warn when a keyword defined section is swallowed in description (this would be a new behavior). For this a change to isDescriptionNode
is needed – see here
- Resolved
Metadata can be distributed among any number of paragraph nodes.
meta1: 1
meta2: 2
# API
Lorem Ipsum
OK.
warning: (1) expected API name, e.g. '# <API Name>' :0:10
{
"_version": "2.0",
"metadata": [
{
"name": "meta1",
"value": "1"
}
],
"name": "",
"description": "meta2: 2\n\n# API \n\nLorem Ipsum\n",
"resourceGroups": []
}
{
"_version": "2.0",
"metadata": [
{
"name": "meta1",
"value": "1"
},
{
"name": "meta2",
"value": "2"
}
],
"name": "",
"description": "# API \nLorem Ipsum\n",
"resourceGroups": []
}
This is a regression which needs to be fixed.
- Resolved
Not recognizing api name when metadata spans multiple paragraphs
meta1: 1
meta2: 2
# API
Lorem Ipsum
OK.
{
"_version": "2.0",
"metadata": [
{
"name": "meta1",
"value": "1"
},
{
"name": "meta2",
"value": "2"
}
],
"name": "API",
"description": "Lorem Ipsum\n",
"resourceGroups": []
}
{
"_version": "2.0",
"metadata": [
{
"name": "meta1",
"value": "1"
},
{
"name": "meta2",
"value": "2"
}
],
"name": "",
"description": "# API \nLorem Ipsum\n",
"resourceGroups": []
}
New behaviour (actual) is OK and not considered a regression issue.
- Resolved
Wrong indentation for transaction examples in actions.
# API
## GET /a
+ Request
+ Headers
Accept: application/json
+ Response 202 (application/json)
A
+ Response 200 (application/json)
+ Body
B
OK.
warning: (6) action is missing a response for a request :6:11
{
"_version": "2.0",
"metadata": [],
"name": "API",
"description": "",
"resourceGroups": [
{
"name": "",
"description": "",
"resources": [
{
"name": "",
"description": "",
"uriTemplate": "/a",
"model": {},
"parameters": [],
"actions": [
{
"name": "",
"description": "",
"method": "GET",
"parameters": [],
"examples": [
{
"name": "",
"description": "",
"requests": [
{
"name": "",
"description": "",
"headers": [
{
"name": "Accept",
"value": "application/json"
}
],
"body": "",
"schema": ""
}
],
"responses": []
}
]
}
]
}
]
}
]
}
{
"_version": "2.0",
"metadata": [],
"name": "API",
"description": "",
"resourceGroups": [
{
"name": "",
"description": "",
"resources": [
{
"name": "",
"description": "",
"uriTemplate": "/a",
"model": {},
"parameters": [],
"actions": [
{
"name": "",
"description": "",
"method": "GET",
"parameters": [],
"examples": [
{
"name": "",
"description": "",
"requests": [
{
"name": "",
"description": "",
"headers": [
{
"name": "Accept",
"value": "application/json"
}
],
"body": "",
"schema": ""
}
],
"responses": [
{
"name": "202",
"description": "",
"headers": [
{
"name": "Content-Type",
"value": "application/json"
}
],
"body": "A\n",
"schema": ""
},
{
"name": "200",
"description": "",
"headers": [
{
"name": "Content-Type",
"value": "application/json"
}
],
"body": "B\n",
"schema": ""
}
]
}
]
}
]
}
]
}
]
}
- Leave the actual (new) behavior.
- Create a new issue for not warning about ingoring excessively nested responses.
- Resolved
When a symbol is referenced in a Payload, parser warns them if it's not indented by 8 spaces.
# Posts [/posts]
+ Model (application/json)
{...}
## List [GET]
+ Response 200
[Posts][]
OK.
warning: (10) response is expected to be a pre-formatted code block, every of its line indented by exactly 4 spaces or 1 tabs :0:0
warning: (1) expected API name, e.g. '# <API Name>' :0:17
{
"_version": "2.0",
"metadata": [],
"name": "",
"description": "",
"resourceGroups": [
{
"name": "",
"description": "",
"resources": [
{
"name": "Posts",
"description": "",
"uriTemplate": "/posts",
"model": {
"name": "Posts",
"description": "",
"headers": [
{
"name": "Content-Type",
"value": "application/json"
}
],
"body": "{...}\n",
"schema": ""
},
"parameters": [],
"actions": [
{
"name": "List",
"description": "",
"method": "GET",
"parameters": [],
"examples": [
{
"name": "",
"description": "",
"requests": [],
"responses": [
{
"name": "200",
"description": "",
"headers": [
{
"name": "Content-Type",
"value": "application/json"
}
],
"body": "{...}\n",
"schema": ""
}
]
}
]
}
]
}
]
}
]
}
{
"_version": "2.0",
"metadata": [],
"name": "",
"description": "",
"resourceGroups": [
{
"name": "",
"description": "",
"resources": [
{
"name": "Posts",
"description": "",
"uriTemplate": "/posts",
"model": {
"name": "Posts",
"description": "",
"headers": [
{
"name": "Content-Type",
"value": "application/json"
}
],
"body": "{...}\n",
"schema": ""
},
"parameters": [],
"actions": [
{
"name": "List",
"description": "",
"method": "GET",
"parameters": [],
"examples": [
{
"name": "",
"description": "",
"requests": [],
"responses": [
{
"name": "200",
"description": "",
"headers": [
{
"name": "Content-Type",
"value": "application/json"
}
],
"body": "{...}\n",
"schema": ""
}
]
}
]
}
]
}
]
}
]
}
- when indented by 8 spaces (code block) – reference is parsed as an asset
- when indented by 4 spaces (pragraph) – explode the reference
- Resolved
Add parameter description when no description on its signature and remaining description is not a new node.
# API
## GET /vehicles/{id}/command/sun_roof_control?state={state}
+ Parameters
+ id (number) ... The ID number of the car
+ state (string)
This description is not shown in AST
+ Values
+ `open`
+ `close`
+ `comfort`
+ `vent`
+ Response 200
OK.
warning: (5) ignoring unrecognized block :129:17;150:39;193:11;208:15;227:16;247:18;269:15
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/vehicles/{id}/command/sun_roof_control?state={state}"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
- name: "id"
description: "The ID number of the car"
type: "number"
required: true
default:
example:
values:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body:
schema:
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/vehicles/{id}/command/sun_roof_control?state={state}"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
- name: "id"
description: "The ID number of the car"
type: "number"
required: true
default:
example:
values:
- name: "state"
description:
type: "string"
required: true
default:
example:
values:
- value: "open"
- value: "close"
- value: "comfort"
- value: "vent"
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body:
schema:
OK.
The AST should match expected however the state
should have its description set.
- Resolved
Allows parameter default value to have ...
.
FORMAT: 1A
HOST: http://www.google.com
# sandbox
## GET /vehicles/{id}/command/sun_roof_control?state={state}
Controls the car's panoramic roof, if installed.
+ Parameters
+ state (required, string) ... State of the roof
+ id (required, string, `wejude77...`) ... The ID number of the car
+ Response 200
OK.
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/vehicles/{id}/command/sun_roof_control?state={state}"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
- name: "id"
description: "The ID number of the car"
type: "number"
required: true
default:
example: "wejude77..."
values:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body:
schema:
OK.
warning: (5) ignoring unrecognized list, expected parameter discussion, e.g. '<parameter name> ... lorem ipsum' :86:52
warning: (3) no parameters specified, expected a nested list of parameters, one parameter per list item :71:11
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/vehicles/{id}/command/sun_roof_control?state={state}"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body:
schema:
The actual behavior is correct. The issue was brought by fixing #125 or #107
- Resolved
# Posts [/posts]
+ Model (application/json)
{...}
## List [GET]
+ Response 200
[Post][]
error: (1) parser exception: 'map::at'
warning: (10) response is expected to be a pre-formatted code block, every of its line indented by exactly 4 spaces or 1 tabs :0:0
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
error: (3) undefined symbol 'Post' :102:10
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
The expected behavior is correct which makes this a regression.
- Resolved
# GET /1
+ response 200
OK.
warning: (1) expected API name, e.g. '# <API Name>' :0:9
_version: 2.0
metadata:
name:
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/1"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body:
schema:
_version: 2.0
metadata:
name:
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/1"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body:
schema:
OK.
The API name is optional by default
- Resolved
Missing warning when there are no headers specified in the headers section.
# API
## GET /1
+ response 200
+ headers
+ body
A1
OK.
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/1"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body: "A1\n"
schema:
OK.
warning: (3) no headers specified :37:8
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/1"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body: "A1\n"
schema:
Add missing warning
- Resolved
Doesn't recognize the main Parameters section.
# GET /1
+ Parameters
-_id (string, `1`) ... Desks
+ Response 200
_version: 2.0
metadata:
name:
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/1"
model:
parameters:
actions:
- name:
description: "+ Parameters\n -_id (string, `1`) ... Desks\n\n"
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body:
schema:
OK.
warning: (5) ignoring additional content after 'parameters' keyword, expected a nested list of parameters, one parameter per list item :12:11;27:29
warning: (3) no parameters specified, expected a nested list of parameters, one parameter per list item :12:11;27:29
_version: 2.0
metadata:
name:
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/1"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body:
schema:
Expected is correct, so this is a regession.
- Resolved
Doesn't get recognized as BodySection.
# GET /
+ Response 200
+ Body
{}
_version: 2.0
metadata:
name:
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body: "+ Body\n {}\n"
schema:
_version: 2.0
metadata:
name:
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body: " {}\n"
schema:
OK.
warning: (10) message-body asset is expected to be a pre-formatted code block, separate it by a newline and indent every of its line by 12 spaces or 3 tabs :29:5;42:7
This is a regression.
- Resolved
A source map is missing for poorly nested asset
# API
## GET /1
+ response 200
+ Body
X
OK.
warning: (10) message-body is expected to be a pre-formatted code block, every of its line indented by exactly 12 spaces or 3 tabs :0:0
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/1"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body: "X"
schema:
OK.
warning: (10) message-body asset is expected to be a pre-formatted code block, every of its line indented by exactly 12 spaces or 3 tabs :51:1
_version: 2.0
metadata:
name: "API"
description:
resourceGroups:
- name:
description:
resources:
- name:
description:
uriTemplate: "/1"
model:
parameters:
actions:
- name:
description:
method: "GET"
parameters:
examples:
- name:
description:
requests:
responses:
- name: "200"
description:
headers:
body: "X"
schema:
The source map should be :51:1