feat: bru lang - support for body type parsing

This commit is contained in:
Anoop M D 2023-02-04 06:06:02 +05:30
parent 7a8e5198ff
commit 689d886e74
2 changed files with 212 additions and 1 deletions

View File

@ -2,7 +2,9 @@ const ohm = require("ohm-js");
const _ = require('lodash'); const _ = require('lodash');
const grammar = ohm.grammar(`Bru { const grammar = ohm.grammar(`Bru {
BruFile = (script | test | headersdisabled | headers)* BruFile = (script | test | querydisabled | query | headersdisabled | headers | bodies )*
bodies = bodyjson | bodytext | bodyxml | bodygraphql | bodygraphqlvars | bodyforms
bodyforms = bodyformurlencodeddisabled | bodyformurlencoded | bodymultipartdisabled | bodymultipart
nl = "\\r"? "\\n" nl = "\\r"? "\\n"
st = " " | "\\t" st = " " | "\\t"
tagend = nl "}" tagend = nl "}"
@ -12,12 +14,26 @@ const grammar = ohm.grammar(`Bru {
headers = "headers" pairblock headers = "headers" pairblock
headersdisabled = "headers:disabled" pairblock headersdisabled = "headers:disabled" pairblock
query = "query" pairblock
querydisabled = "query:disabled" pairblock
pairblock = st* "{" pairlist? tagend pairblock = st* "{" pairlist? tagend
pairlist = nl* pair (~tagend nl pair)* (~tagend space)* pairlist = nl* pair (~tagend nl pair)* (~tagend space)*
pair = st* key st* ":" st* value? st* pair = st* key st* ":" st* value? st*
key = ~tagend validkey* key = ~tagend validkey*
value = ~tagend validvalue* value = ~tagend validvalue*
bodyjson = "body:json" st* "{" nl* textblock tagend
bodytext = "body:text" st* "{" nl* textblock tagend
bodyxml = "body:xml" st* "{" nl* textblock tagend
bodygraphql = "body:graphql" st* "{" nl* textblock tagend
bodygraphqlvars = "body:graphql:vars" st* "{" nl* textblock tagend
bodyformurlencoded = "body:form-urlencoded" pairblock
bodyformurlencodeddisabled = "body:form-urlencoded:disabled" pairblock
bodymultipart = "body:multipart-form" pairblock
bodymultipartdisabled = "body:multipart-form:disabled" pairblock
script = "script" st* "{" nl* textblock tagend script = "script" st* "{" nl* textblock tagend
test = "test" st* "{" textblock tagend test = "test" st* "{" textblock tagend
@ -56,6 +72,16 @@ const sem = grammar.createSemantics().addAttribute('ast', {
return _.mergeWith(result, item, concatArrays); return _.mergeWith(result, item, concatArrays);
}, {}); }, {});
}, },
query(_1, pairblock) {
return {
query: mapPairListToKeyValPairs(pairblock.ast)
};
},
querydisabled(_1, pairblock) {
return {
query: mapPairListToKeyValPairs(pairblock.ast, false)
};
},
headers(_1, pairblock) { headers(_1, pairblock) {
return { return {
headers: mapPairListToKeyValPairs(pairblock.ast) headers: mapPairListToKeyValPairs(pairblock.ast)
@ -83,6 +109,73 @@ const sem = grammar.createSemantics().addAttribute('ast', {
value(chars) { value(chars) {
return chars.sourceString ? chars.sourceString.trim() : ''; return chars.sourceString ? chars.sourceString.trim() : '';
}, },
bodyformurlencoded(_1, pairblock) {
return {
body: {
formUrlEncoded: mapPairListToKeyValPairs(pairblock.ast)
}
};
},
bodyformurlencodeddisabled(_1, pairblock) {
return {
body: {
formUrlEncoded: mapPairListToKeyValPairs(pairblock.ast, false)
}
};
},
bodymultipart(_1, pairblock) {
return {
body: {
multipartForm: mapPairListToKeyValPairs(pairblock.ast)
}
};
},
bodymultipartdisabled(_1, pairblock) {
return {
body: {
multipartForm: mapPairListToKeyValPairs(pairblock.ast, false)
}
};
},
bodyjson(_1, _2, _3, _4, textblock, _5) {
return {
body: {
json: textblock.sourceString
}
};
},
bodytext(_1, _2, _3, _4, textblock, _5) {
return {
body: {
text: textblock.sourceString
}
};
},
bodyxml(_1, _2, _3, _4, textblock, _5) {
return {
body: {
xml: textblock.sourceString
}
};
},
bodygraphql(_1, _2, _3, _4, textblock, _5) {
return {
body: {
graphql: {
query: textblock.sourceString
}
}
};
},
bodygraphqlvars(_1, _2, _3, _4, textblock, _5) {
return {
body: {
graphql: {
variables: textblock.sourceString
}
}
};
},
script(_1, _2, _3, _4, textblock, _5) { script(_1, _2, _3, _4, textblock, _5) {
return { return {
script: textblock.sourceString script: textblock.sourceString

View File

@ -3,6 +3,15 @@ const parser = require("../src/index");
describe("parser", () => { describe("parser", () => {
it("should parse the bru file", () => { it("should parse the bru file", () => {
const input = ` const input = `
query {
apiKey: secret
numbers: 998877665
}
query:disabled {
message: hello
}
headers { headers {
content-type: application/json content-type: application/json
Authorization: Bearer 123 Authorization: Bearer 123
@ -12,6 +21,58 @@ headers:disabled {
transaction-id: {{transactionId}} transaction-id: {{transactionId}}
} }
body:form-urlencoded {
apikey: secret
numbers: +91998877665
}
body:form-urlencoded:disabled {
message: hello
}
body:multipart-form {
apikey: secret
numbers: +91998877665
}
body:multipart-form:disabled {
message: hello
}
body:json {
{
"hello": "world"
}
}
body:text {
This is a text body
}
body:xml {
<xml>
<name>John</name>
<age>30</age>
</xml>
}
body:graphql {
{
launchesPast {
launch_site {
site_name
}
launch_success
}
}
}
body:graphql:vars {
{
"limit": 5
}
}
script { script {
function onResponse(request, response) { function onResponse(request, response) {
expect(response.status).to.equal(200); expect(response.status).to.equal(200);
@ -21,6 +82,19 @@ script {
const output = parser(input); const output = parser(input);
const expected = { const expected = {
"query": [{
"name": "apiKey",
"value": "secret",
"enabled": true
}, {
"name": "numbers",
"value": "998877665",
"enabled": true
}, {
"name": "message",
"value": "hello",
"enabled": false
}],
"headers": [ "headers": [
{ {
"name": "content-type", "name": "content-type",
@ -38,9 +112,53 @@ script {
"enabled": false "enabled": false
} }
], ],
"body": {
"json": " {\n \"hello\": \"world\"\n }",
"text": " This is a text body",
"xml": " <xml>\n <name>John</name>\n <age>30</age>\n </xml>",
"graphql": {
"query": " {\n launchesPast {\n launch_site {\n site_name\n }\n launch_success\n }\n }",
"variables": " {\n \"limit\": 5\n }"
},
"formUrlEncoded": [
{
"name": "apikey",
"value": "secret",
"enabled": true
},
{
"name": "numbers",
"value": "+91998877665",
"enabled": true
},
{
"name": "message",
"value": "hello",
"enabled": false
}
],
"multipartForm": [
{
"name": "apikey",
"value": "secret",
"enabled": true
},
{
"name": "numbers",
"value": "+91998877665",
"enabled": true
},
{
"name": "message",
"value": "hello",
"enabled": false
}
]
},
"script": " function onResponse(request, response) {\n expect(response.status).to.equal(200);\n }" "script": " function onResponse(request, response) {\n expect(response.status).to.equal(200);\n }"
} }
// console.log(JSON.stringify(output, null, 2));
expect(output).toEqual(expected); expect(output).toEqual(expected);
}); });
}); });