From 87a4778a9191efb2b0bdff84b2b2f63c0e0faeb2 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Sun, 15 Jan 2023 00:45:01 +0530 Subject: [PATCH] feat: bruno-lang now supprts parsing body json --- packages/bruno-lang/src/body-tag.js | 59 +++++++++++++++++++ packages/bruno-lang/src/index.js | 7 ++- packages/bruno-lang/src/utils.js | 12 ++++ packages/bruno-lang/tests/body-tag.spec.js | 46 +++++++++++++++ .../bruno-lang/tests/fixtures/request.bru | 10 +++- packages/bruno-lang/tests/parser.spec.js | 3 +- 6 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 packages/bruno-lang/src/body-tag.js create mode 100644 packages/bruno-lang/src/utils.js create mode 100644 packages/bruno-lang/tests/body-tag.spec.js diff --git a/packages/bruno-lang/src/body-tag.js b/packages/bruno-lang/src/body-tag.js new file mode 100644 index 000000000..208c31f14 --- /dev/null +++ b/packages/bruno-lang/src/body-tag.js @@ -0,0 +1,59 @@ +const { + str, + sequenceOf, + optionalWhitespace, + choice, + endOfInput, + between, + regex, + everyCharUntil +} = require("arcsecond"); +const { safeParseJson } = require('./utils'); + +const newline = regex(/^\r?\n/); +const newLineOrEndOfInput = choice([newline, endOfInput]); + +// body(type=json) +const bodyJsonBegin = sequenceOf([ + str('body'), + optionalWhitespace, + str('('), + optionalWhitespace, + str('type'), + optionalWhitespace, + str('='), + optionalWhitespace, + str('json'), + optionalWhitespace, + regex(/^\)\s*\r?\n/), +]); + +const bodyEnd = sequenceOf([ + regex(/^\/body\s*/), + newLineOrEndOfInput +]); + +const bodyJsonTag = between(bodyJsonBegin)(bodyEnd)(everyCharUntil(bodyEnd)).map((bodyJson) => { + if(bodyJson && bodyJson.length) { + bodyJson = bodyJson.trim(); + const safelyParsed = safeParseJson(bodyJson); + + if(!safelyParsed) { + return { + bodyJson + } + } + + return { + bodyJson: JSON.stringify(safelyParsed) + }; + } + + return { + bodyJson + }; +}); + +module.exports = { + bodyJsonTag +}; diff --git a/packages/bruno-lang/src/index.js b/packages/bruno-lang/src/index.js index d36b72254..fc4388ca4 100644 --- a/packages/bruno-lang/src/index.js +++ b/packages/bruno-lang/src/index.js @@ -7,12 +7,16 @@ const { const inlineTag = require('./inline-tag'); const paramsTag = require('./params-tag'); const headersTag = require('./headers-tag'); +const { + bodyJsonTag +} = require('./body-tag'); const bruToJson = (fileContents) => { const parser = many(choice([ inlineTag, paramsTag, headersTag, + bodyJsonTag, anyChar ])); @@ -33,7 +37,8 @@ const bruToJson = (fileContents) => { method: parsed.method, url: parsed.url, params: parsed.params, - headers: parsed.headers + headers: parsed.headers, + bodyJson: parsed.bodyJson } }; diff --git a/packages/bruno-lang/src/utils.js b/packages/bruno-lang/src/utils.js new file mode 100644 index 000000000..4f041b7d3 --- /dev/null +++ b/packages/bruno-lang/src/utils.js @@ -0,0 +1,12 @@ +// safely parse json +const safeParseJson = (json) => { + try { + return JSON.parse(json); + } catch (e) { + return null; + } +}; + +module.exports = { + safeParseJson +}; diff --git a/packages/bruno-lang/tests/body-tag.spec.js b/packages/bruno-lang/tests/body-tag.spec.js new file mode 100644 index 000000000..cd67bfc5b --- /dev/null +++ b/packages/bruno-lang/tests/body-tag.spec.js @@ -0,0 +1,46 @@ +const { bodyJsonTag } = require('../src/body-tag'); + + +describe('bodyJsonTag', () => { + const testbodyJson = (input, expected) => { + const result = bodyJsonTag.run(input); + expect(result.isError).toBe(false); + expect(result.result.bodyJson).toEqual('{"foo":"bar"}'); + }; + + // simple case + it('should parse json body tag - 1', () => { + const input = 'body(type=json)\n{ "foo": "bar" }\n/body'; + testbodyJson(input, '{ "foo": "bar" }\n'); + }); + + // space between body and args + it('should parse json body tag - 2', () => { + const input = 'body (type = json)\n{ "foo": "bar" }\n/body'; + testbodyJson(input, '{ "foo": "bar" }\n'); + }); + + // space after body tag + it('should parse json body tag - 3', () => { + const input = 'body (type = json) \n{ "foo": "bar" }\n/body'; + testbodyJson(input, '{ "foo": "bar" }\n'); + }); + + // space after body tag + it('should parse json body tag - 4', () => { + const input = 'body (type = json) \n{ "foo": "bar" }\n/body '; + testbodyJson(input, '{ "foo": "bar" }\n'); + }); + + it('should fail to parse when body tag is missing', () => { + const input = '{ "foo": "bar" }\n/body'; + const result = bodyJsonTag.run(input); + expect(result.isError).toBe(true); + }); + + it('should fail to parse when body end tag is missing', () => { + const input = 'body (type = json)\n{ "foo": "bar" }'; + const result = bodyJsonTag.run(input); + expect(result.isError).toBe(true); + }); +}); diff --git a/packages/bruno-lang/tests/fixtures/request.bru b/packages/bruno-lang/tests/fixtures/request.bru index bc23ddf9e..ac2e85524 100644 --- a/packages/bruno-lang/tests/fixtures/request.bru +++ b/packages/bruno-lang/tests/fixtures/request.bru @@ -15,4 +15,12 @@ headers 1 content-type application/json 1 accept-language en-US,en;q=0.9,hi;q=0.8 0 transaction-id {{transactionId}} -/headers \ No newline at end of file +/headers + +body(type=json) + { + "apikey": "secret", + "numbers": "+91998877665" + } +/body + diff --git a/packages/bruno-lang/tests/parser.spec.js b/packages/bruno-lang/tests/parser.spec.js index f282b5f3d..359811b03 100644 --- a/packages/bruno-lang/tests/parser.spec.js +++ b/packages/bruno-lang/tests/parser.spec.js @@ -49,7 +49,8 @@ describe('bruToJson', () => { "key": "transaction-id", "value": "{{transactionId}}" } - ] + ], + "bodyJson": '{"apikey":"secret","numbers":"+91998877665"}' }); }); });