feat: bru lang tests, scripts and headers using ohm

This commit is contained in:
Anoop M D 2023-02-03 08:01:44 +05:30
parent 104bd272f9
commit 9d6ba4691c
2 changed files with 73 additions and 35 deletions

View File

@ -1,53 +1,81 @@
const ohm = require("ohm-js"); const ohm = require("ohm-js");
const grammar = ohm.grammar(`Bru { const grammar = ohm.grammar(`Bru {
Headers = "headers" "{" PairList "}" BruFile = (script | test | headers)*
PairList = Pair ("," Pair)* nl = "\\r"? "\\n"
Pair = Key ":" Value st = " " | "\\t"
Key = identifier tagend = nl "}"
Value = stringLiteral
identifier = alnum* headers = "headers" st* "{" nl* pairlist tagend
stringLiteral = letter*
pairlist = pair (~tagend nl pair)* (~tagend space)*
pair = st* key st* ":" st* val st*
key = alnum*
val = letter*
script = "script" st* "{" codeblock tagend
test = "test" st* "{" codeblock tagend
codeblock = codeline (~tagend nl codeline)*
codeline = codechar*
codechar = ~nl any
}`); }`);
const sem = grammar.createSemantics().addAttribute('ast', { const sem = grammar.createSemantics().addAttribute('ast', {
Headers(_, _1, PairList, _2) { headers(_1, _2, _3, _4, pairlist, _5) {
return PairList.ast; return pairlist.ast;
}, },
PairList(pairs, _, rest) { pairlist(pair, _1, rest, _2) {
return [pairs.ast, ...rest.ast]; return [pair.ast, ...rest.ast];
}, },
Pair(key, _, value) { pair(_1, key, _2, _3, _4, val, _5) {
return { key: key.ast, value: value.ast }; let res = {};
res[key.ast] = val.ast;
return res;
}, },
Key(id) { key(chars) {
return id.sourceString; return chars.sourceString;
}, },
Value(str) { val(chars) {
return str.sourceString; return chars.sourceString;
}, },
identifier(id) { script(_1, _2, _3, codeblock, _4) {
return id.sourceString; return codeblock.sourceString;
}, },
stringLiteral(str) { test(_1, _2, _3, codeblock, _4) {
return str.sourceString; return codeblock.sourceString;
},
codeblock(line, _1, rest) {
return [line.ast, ...rest.ast].join('\n');
},
codeline(chars) {
return chars.sourceString;
},
codechar(char) {
return char.sourceString;
},
nl(_1, _2) {
return '';
},
st(_) {
return '';
},
tagend(_1 ,_2) {
return '';
}, },
_iter(...elements) { _iter(...elements) {
return elements.map(e => e.ast); return elements.map(e => e.ast);
} }
}); });
const input = `headers {
hello: world,
foo: bar
}`;
const parser = (input) => { const parser = (input) => {
const match = grammar.match(input); const match = grammar.match(input);
if(match.succeeded()) { if(match.succeeded()) {
return sem(match).ast; return sem(match).ast;
} else { } else {
console.log('match.message=========');
console.log(match.message);
throw new Error(match.message); throw new Error(match.message);
} }
} }

View File

@ -2,16 +2,26 @@ const parser = require("../src/index");
describe("parser", () => { describe("parser", () => {
it("should parse headers", () => { it("should parse headers", () => {
const input = `headers { const input = `
hello: world, headers {
foo: bar hello: world
}`; foo: bar
}`;
const expected = [ const output = parser(input);
{ key: "hello", value: "world" }, console.log(output);
{ key: "foo", value: "bar" } });
];
expect(parser(input)).toEqual(expected); it("should parse script body", () => {
const input = `
script {
function onResponse(request, response) {
expect(response.status).to.equal(200);
}
}
`;
const output = parser(input);
console.log(output);
}); });
}); });