Add support for defining tags in Bru files

Add a generic `list` block to Bru grammar that holds simple text values
in square brackets separated by newlines.

Example usage:

```
meta {
  name: Login
  type: http
  seq: 1
}

tags [
  smoke-test
  authentication
]

post {
  url: https://example.com/login
  body: json
}
```
This commit is contained in:
Antti Sonkeri
2024-07-20 11:41:56 +03:00
parent 6349e9b816
commit 259eee184b
4 changed files with 43 additions and 3 deletions

View File

@@ -4,7 +4,7 @@ const { safeParseJson, outdentString } = require('./utils');
/**
* A Bru file is made up of blocks.
* There are two types of blocks
* There are three types of blocks
*
* 1. Dictionary Blocks - These are blocks that have key value pairs
* ex:
@@ -19,10 +19,17 @@ const { safeParseJson, outdentString } = require('./utils');
* "username": "John Nash",
* "password": "governingdynamics
* }
* 3. List Blocks - These are blocks that have a list of items
* ex:
* tags [
* regression
* smoke-test
* ]
*
*/
const grammar = ohm.grammar(`Bru {
BruFile = (meta | http | query | params | headers | auths | bodies | varsandassert | script | tests | docs)*
BruFile = (meta | tags | http | query | params | headers | auths | bodies | varsandassert | script | tests | docs)*
auths = authawsv4 | authbasic | authbearer | authdigest | authNTLM | authOAuth2 | authwsse | authapikey
bodies = bodyjson | bodytext | bodyxml | bodysparql | bodygraphql | bodygraphqlvars | bodyforms | body
bodyforms = bodyformurlencoded | bodymultipart | bodyfile
@@ -59,6 +66,13 @@ const grammar = ohm.grammar(`Bru {
textline = textchar*
textchar = ~nl any
// List
listend = nl "]"
list = st* "[" listitems? listend
listitems = (~listend nl)* listitem (~listend stnl* listitem)* (~listend space)*
listitem = st* textchar+ st*
tags = "tags" list
meta = "meta" dictionary
http = get | post | put | delete | patch | options | head | connect | trace
@@ -297,6 +311,15 @@ const sem = grammar.createSemantics().addAttribute('ast', {
assertkey(chars) {
return chars.sourceString ? chars.sourceString.trim() : '';
},
list(_1, _2, listitems, _3) {
return listitems.ast.flat()
},
listitems(_1, listitem, _2, rest, _3) {
return [listitem.ast, ...rest.ast]
},
listitem(_1, textchar, _2) {
return textchar.sourceString;
},
textblock(line, _1, rest) {
return [line.ast, ...rest.ast].join('\n');
},
@@ -318,6 +341,9 @@ const sem = grammar.createSemantics().addAttribute('ast', {
_iter(...elements) {
return elements.map((e) => e.ast);
},
tags(_1, list) {
return { tags: list.ast };
},
meta(_1, dictionary) {
let meta = mapPairListToKeyValPair(dictionary.ast);

View File

@@ -30,7 +30,7 @@ const getValueString = (value) => {
};
const jsonToBru = (json) => {
const { meta, http, params, headers, auth, body, script, tests, vars, assertions, docs } = json;
const { meta, tags, http, params, headers, auth, body, script, tests, vars, assertions, docs } = json;
let bru = '';
@@ -42,6 +42,14 @@ const jsonToBru = (json) => {
bru += '}\n\n';
}
if (tags) {
bru += 'tags [\n';
for (const tag of tags) {
bru += ` ${tag}\n`;
}
bru += ']\n\n';
}
if (http && http.method) {
bru += `${http.method} {
url: ${http.url}`;

View File

@@ -4,6 +4,11 @@ meta {
seq: 1
}
tags [
foo
bar
]
get {
url: https://api.textlocal.in/send/:id
body: json

View File

@@ -4,6 +4,7 @@
"type": "http",
"seq": "1"
},
"tags": ["foo", "bar"],
"http": {
"method": "get",
"url": "https://api.textlocal.in/send/:id",