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 grammar = ohm.grammar(`Bru {
Headers = "headers" "{" PairList "}"
PairList = Pair ("," Pair)*
Pair = Key ":" Value
Key = identifier
Value = stringLiteral
identifier = alnum*
stringLiteral = letter*
BruFile = (script | test | headers)*
nl = "\\r"? "\\n"
st = " " | "\\t"
tagend = nl "}"
headers = "headers" st* "{" nl* pairlist tagend
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', {
Headers(_, _1, PairList, _2) {
return PairList.ast;
headers(_1, _2, _3, _4, pairlist, _5) {
return pairlist.ast;
},
PairList(pairs, _, rest) {
return [pairs.ast, ...rest.ast];
pairlist(pair, _1, rest, _2) {
return [pair.ast, ...rest.ast];
},
Pair(key, _, value) {
return { key: key.ast, value: value.ast };
pair(_1, key, _2, _3, _4, val, _5) {
let res = {};
res[key.ast] = val.ast;
return res;
},
Key(id) {
return id.sourceString;
key(chars) {
return chars.sourceString;
},
Value(str) {
return str.sourceString;
val(chars) {
return chars.sourceString;
},
identifier(id) {
return id.sourceString;
script(_1, _2, _3, codeblock, _4) {
return codeblock.sourceString;
},
stringLiteral(str) {
return str.sourceString;
test(_1, _2, _3, codeblock, _4) {
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) {
return elements.map(e => e.ast);
}
});
const input = `headers {
hello: world,
foo: bar
}`;
const parser = (input) => {
const match = grammar.match(input);
if(match.succeeded()) {
return sem(match).ast;
} else {
console.log('match.message=========');
console.log(match.message);
throw new Error(match.message);
}
}

View File

@ -2,16 +2,26 @@ const parser = require("../src/index");
describe("parser", () => {
it("should parse headers", () => {
const input = `headers {
hello: world,
foo: bar
}`;
const input = `
headers {
hello: world
foo: bar
}`;
const expected = [
{ key: "hello", value: "world" },
{ key: "foo", value: "bar" }
];
const output = parser(input);
console.log(output);
});
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);
});
});