mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-22 07:53:34 +01:00
feat: bru lang tests, scripts and headers using ohm
This commit is contained in:
parent
104bd272f9
commit
9d6ba4691c
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user