feat(#1303): toml parser for scripts and tests

This commit is contained in:
Anoop M D 2023-12-31 02:52:41 +05:30
parent 5ba2c98e1d
commit abb24c93c5
10 changed files with 150 additions and 9 deletions

View File

@ -177,7 +177,7 @@ function stringifyMultilineString (str) {
return escapeString(str).replace(/'(?='')/g, "\\'") return escapeString(str).replace(/'(?='')/g, "\\'")
}).join('\n') }).join('\n')
if (escaped.slice(-1) === "'") escaped += '\\\n' if (escaped.slice(-1) === "'") escaped += '\\\n'
return "'''\n" + escaped + "\n'''" return "'''\n" + escaped + "'''"
} }
function stringifyAnyInline (value, multilineOk) { function stringifyAnyInline (value, multilineOk) {

View File

@ -18,12 +18,22 @@ const keyValPairHasReservedKeys = (keyValPair) => {
return false; return false;
} }
const reservedKeys = ['disabled', 'description', 'enum']; const reservedKeys = ['disabled', 'description', 'enum', 'bru'];
const names = keyValPair.map((pair) => pair.name); const names = keyValPair.map((pair) => pair.name);
return names.some((name) => reservedKeys.includes(name)); return names.some((name) => reservedKeys.includes(name));
}; };
/**
* Json to Toml
*
* Note: Bruno always append a new line at the end of text blocks
* This is to aid readability when viewing the toml representation of the request
* The newline is removed when converting back to json
*
* @param {object} json
* @returns string
*/
const jsonToToml = (json) => { const jsonToToml = (json) => {
const formattedJson = { const formattedJson = {
meta: { meta: {
@ -55,11 +65,33 @@ const jsonToToml = (json) => {
}); });
} else { } else {
formattedJson.headers = { formattedJson.headers = {
bru: JSON.stringify(json.headers, null, 2) bru: JSON.stringify(json.headers, null, 2) + '\n'
}; };
} }
} }
if (json.script) {
let preRequestScript = get(json, 'script.req', '');
if (preRequestScript.trim().length > 0) {
formattedJson.script = formattedJson.script || {};
formattedJson.script['pre-request'] = preRequestScript + '\n';
}
let postResponseScript = get(json, 'script.res', '');
if (postResponseScript.trim().length > 0) {
formattedJson.script = formattedJson.script || {};
formattedJson.script['post-response'] = postResponseScript + '\n';
}
}
if (json.tests) {
let testsScript = get(json, 'tests', '');
if (testsScript.trim().length > 0) {
formattedJson.script = formattedJson.script || {};
formattedJson.script['tests'] = testsScript + '\n';
}
}
return stringify(formattedJson); return stringify(formattedJson);
}; };

View File

@ -1,14 +1,22 @@
const Toml = require('@iarna/toml'); const Toml = require('@iarna/toml');
const { has, each } = require('lodash'); const { has, each, get } = require('lodash');
const stripNewlineAtEnd = (str) => {
if (!str || typeof str !== 'string') {
return '';
}
return str.replace(/\n$/, '');
};
const tomlToJson = (toml) => { const tomlToJson = (toml) => {
const json = Toml.parse(toml); const json = Toml.parse(toml);
const formattedJson = { const formattedJson = {
meta: { meta: {
name: json.meta.name, name: get(json, 'meta.name', ''),
type: json.meta.type, type: get(json, 'meta.type', ''),
seq: json.meta.seq seq: get(json, 'meta.seq', 0)
}, },
http: { http: {
method: json.http.method, method: json.http.method,
@ -53,6 +61,22 @@ const tomlToJson = (toml) => {
} }
} }
if (json.script) {
if (json.script['pre-request']) {
formattedJson.script = formattedJson.script || {};
formattedJson.script.req = stripNewlineAtEnd(json.script['pre-request']);
}
if (json.script['post-response']) {
formattedJson.script = formattedJson.script || {};
formattedJson.script.res = stripNewlineAtEnd(json.script['post-response']);
}
if (json.script['tests']) {
formattedJson.tests = stripNewlineAtEnd(json.script['tests']);
}
}
return formattedJson; return formattedJson;
}; };

View File

@ -13,7 +13,10 @@ const fixtures = [
'headers/disabled-header', 'headers/disabled-header',
'headers/dotted-header', 'headers/dotted-header',
'headers/duplicate-header', 'headers/duplicate-header',
'headers/reserved-header' 'headers/reserved-header',
'scripts/pre-request',
'scripts/post-response',
'scripts/tests'
]; ];
describe('bruno toml', () => { describe('bruno toml', () => {
@ -35,7 +38,7 @@ describe('bruno toml', () => {
}); });
it(`should convert toml to json`, () => { it(`should convert toml to json`, () => {
// expect(json).toEqual(tomlToJson(toml)); expect(json).toEqual(tomlToJson(toml));
}); });
}); });
}); });

View File

@ -0,0 +1,14 @@
{
"meta": {
"name": "Get users",
"type": "http",
"seq": 1
},
"http": {
"method": "GET",
"url": "https://reqres.in/api/users"
},
"script": {
"res": "bru.setVar('token', res.body.token);\nconsole.log('token: ' + res.body.token);"
}
}

View File

@ -0,0 +1,14 @@
[meta]
name = 'Get users'
type = 'http'
seq = 1
[http]
method = 'GET'
url = 'https://reqres.in/api/users'
[script]
post-response = '''
bru.setVar('token', res.body.token);
console.log('token: ' + res.body.token);
'''

View File

@ -0,0 +1,14 @@
{
"meta": {
"name": "Get users",
"type": "http",
"seq": 1
},
"http": {
"method": "GET",
"url": "https://reqres.in/api/users"
},
"script": {
"req": "req.body.id = uuid();"
}
}

View File

@ -0,0 +1,13 @@
[meta]
name = 'Get users'
type = 'http'
seq = 1
[http]
method = 'GET'
url = 'https://reqres.in/api/users'
[script]
pre-request = '''
req.body.id = uuid();
'''

View File

@ -0,0 +1,12 @@
{
"meta": {
"name": "Get users",
"type": "http",
"seq": 1
},
"http": {
"method": "GET",
"url": "https://reqres.in/api/users"
},
"tests": "test('Status code is 200', function () {\n expect(res.statusCode).to.eql(200);\n});"
}

View File

@ -0,0 +1,15 @@
[meta]
name = 'Get users'
type = 'http'
seq = 1
[http]
method = 'GET'
url = 'https://reqres.in/api/users'
[script]
tests = '''
test('Status code is 200', function () {
expect(res.statusCode).to.eql(200);
});
'''