forked from extern/bruno
feat: brun lang - ast updates, tests for headers and script tags
This commit is contained in:
parent
9d6ba4691c
commit
2ee2e270b0
@ -1,4 +1,5 @@
|
|||||||
const ohm = require("ohm-js");
|
const ohm = require("ohm-js");
|
||||||
|
const _ = require('lodash');
|
||||||
|
|
||||||
const grammar = ohm.grammar(`Bru {
|
const grammar = ohm.grammar(`Bru {
|
||||||
BruFile = (script | test | headers)*
|
BruFile = (script | test | headers)*
|
||||||
@ -6,14 +7,14 @@ const grammar = ohm.grammar(`Bru {
|
|||||||
st = " " | "\\t"
|
st = " " | "\\t"
|
||||||
tagend = nl "}"
|
tagend = nl "}"
|
||||||
|
|
||||||
headers = "headers" st* "{" nl* pairlist tagend
|
headers = "headers" st* "{" pairlist? tagend
|
||||||
|
|
||||||
pairlist = pair (~tagend nl pair)* (~tagend space)*
|
pairlist = nl* pair (~tagend nl pair)* (~tagend space)*
|
||||||
pair = st* key st* ":" st* val st*
|
pair = st* key st* ":" st* val st*
|
||||||
key = alnum*
|
key = ~tagend alnum*
|
||||||
val = letter*
|
val = ~tagend letter*
|
||||||
|
|
||||||
script = "script" st* "{" codeblock tagend
|
script = "script" st* "{" nl* codeblock tagend
|
||||||
test = "test" st* "{" codeblock tagend
|
test = "test" st* "{" codeblock tagend
|
||||||
|
|
||||||
codeblock = codeline (~tagend nl codeline)*
|
codeblock = codeline (~tagend nl codeline)*
|
||||||
@ -21,11 +22,36 @@ const grammar = ohm.grammar(`Bru {
|
|||||||
codechar = ~nl any
|
codechar = ~nl any
|
||||||
}`);
|
}`);
|
||||||
|
|
||||||
|
const mapPairListToKeyValPairs = (pairList = [], enabled = true) => {
|
||||||
|
if(!pairList.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return _.map(pairList[0], pair => {
|
||||||
|
const key = _.keys(pair)[0];
|
||||||
|
return {
|
||||||
|
name: key,
|
||||||
|
value: pair[key],
|
||||||
|
enabled: enabled
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const sem = grammar.createSemantics().addAttribute('ast', {
|
const sem = grammar.createSemantics().addAttribute('ast', {
|
||||||
headers(_1, _2, _3, _4, pairlist, _5) {
|
BruFile(tags) {
|
||||||
return pairlist.ast;
|
if(!tags || !tags.ast || !tags.ast.length) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.reduce(tags.ast, (result, item) => {
|
||||||
|
return _.assign(result, item);
|
||||||
|
}, {});
|
||||||
},
|
},
|
||||||
pairlist(pair, _1, rest, _2) {
|
headers(_1, _2, _3, pairlist, _4) {
|
||||||
|
return {
|
||||||
|
headers: mapPairListToKeyValPairs(pairlist.ast)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
pairlist(_1, pair, _2, rest, _3) {
|
||||||
return [pair.ast, ...rest.ast];
|
return [pair.ast, ...rest.ast];
|
||||||
},
|
},
|
||||||
pair(_1, key, _2, _3, _4, val, _5) {
|
pair(_1, key, _2, _3, _4, val, _5) {
|
||||||
@ -39,11 +65,15 @@ const sem = grammar.createSemantics().addAttribute('ast', {
|
|||||||
val(chars) {
|
val(chars) {
|
||||||
return chars.sourceString;
|
return chars.sourceString;
|
||||||
},
|
},
|
||||||
script(_1, _2, _3, codeblock, _4) {
|
script(_1, _2, _3, _4, codeblock, _5) {
|
||||||
return codeblock.sourceString;
|
return {
|
||||||
|
script: codeblock.sourceString
|
||||||
|
};
|
||||||
},
|
},
|
||||||
test(_1, _2, _3, codeblock, _4) {
|
test(_1, _2, _3, codeblock, _4) {
|
||||||
return codeblock.sourceString;
|
return {
|
||||||
|
test: codeblock.sourceString
|
||||||
|
};;
|
||||||
},
|
},
|
||||||
codeblock(line, _1, rest) {
|
codeblock(line, _1, rest) {
|
||||||
return [line.ast, ...rest.ast].join('\n');
|
return [line.ast, ...rest.ast].join('\n');
|
||||||
@ -74,8 +104,6 @@ const parser = (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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
100
packages/bruno-lang/v2/tests/headers.spec.js
Normal file
100
packages/bruno-lang/v2/tests/headers.spec.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
const bruToJsonV2 = require("../src/index");
|
||||||
|
|
||||||
|
const assertSingleHeader = (input) => {
|
||||||
|
const output = bruToJsonV2(input);
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
"headers": [{
|
||||||
|
"name": "hello",
|
||||||
|
"value": "world",
|
||||||
|
"enabled": true
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
expect(output).toEqual(expected);
|
||||||
|
};
|
||||||
|
|
||||||
|
describe("headers parser", () => {
|
||||||
|
it("should parse empty header", () => {
|
||||||
|
const input = `
|
||||||
|
headers {
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const output = bruToJsonV2(input);
|
||||||
|
const expected = {
|
||||||
|
"headers": []
|
||||||
|
};
|
||||||
|
expect(output).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse single header", () => {
|
||||||
|
const input = `
|
||||||
|
headers {
|
||||||
|
hello: world
|
||||||
|
}`;
|
||||||
|
|
||||||
|
assertSingleHeader(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse single header with spaces", () => {
|
||||||
|
const input = `
|
||||||
|
headers {
|
||||||
|
hello: world
|
||||||
|
}`;
|
||||||
|
|
||||||
|
assertSingleHeader(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse single header with spaces and newlines", () => {
|
||||||
|
const input = `
|
||||||
|
headers {
|
||||||
|
|
||||||
|
hello: world
|
||||||
|
|
||||||
|
|
||||||
|
}`;
|
||||||
|
|
||||||
|
assertSingleHeader(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse multi headers", () => {
|
||||||
|
const input = `
|
||||||
|
headers {
|
||||||
|
hello: world
|
||||||
|
foo: bar
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const output = bruToJsonV2(input);
|
||||||
|
const expected = {
|
||||||
|
"headers": [{
|
||||||
|
"name": "hello",
|
||||||
|
"value": "world",
|
||||||
|
"enabled": true
|
||||||
|
}, {
|
||||||
|
"name": "foo",
|
||||||
|
"value": "bar",
|
||||||
|
"enabled": true
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
expect(output).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw error on invalid header", () => {
|
||||||
|
const input = `
|
||||||
|
headers {
|
||||||
|
hello: world
|
||||||
|
foo
|
||||||
|
}`;
|
||||||
|
|
||||||
|
expect(() => bruToJsonV2(input)).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw error on invalid header", () => {
|
||||||
|
const input = `
|
||||||
|
headers {
|
||||||
|
hello: world
|
||||||
|
foo: bar}`;
|
||||||
|
|
||||||
|
expect(() => bruToJsonV2(input)).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,19 +1,13 @@
|
|||||||
const parser = require("../src/index");
|
const parser = require("../src/index");
|
||||||
|
|
||||||
describe("parser", () => {
|
describe("parser", () => {
|
||||||
it("should parse headers", () => {
|
it("should parse the bru file", () => {
|
||||||
const input = `
|
const input = `
|
||||||
headers {
|
headers {
|
||||||
hello: world
|
hello: world
|
||||||
foo: bar
|
foo: bar
|
||||||
}`;
|
}
|
||||||
|
|
||||||
const output = parser(input);
|
|
||||||
console.log(output);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should parse script body", () => {
|
|
||||||
const input = `
|
|
||||||
script {
|
script {
|
||||||
function onResponse(request, response) {
|
function onResponse(request, response) {
|
||||||
expect(response.status).to.equal(200);
|
expect(response.status).to.equal(200);
|
||||||
@ -22,6 +16,21 @@ script {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const output = parser(input);
|
const output = parser(input);
|
||||||
console.log(output);
|
const expected = {
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"name": "hello",
|
||||||
|
"value": "world",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foo",
|
||||||
|
"value": "bar",
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"script": " function onResponse(request, response) {\n expect(response.status).to.equal(200);\n }"
|
||||||
|
}
|
||||||
|
expect(output).toEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
17
packages/bruno-lang/v2/tests/script.spec.js
Normal file
17
packages/bruno-lang/v2/tests/script.spec.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const parser = require("../src/index");
|
||||||
|
|
||||||
|
describe("script parser", () => {
|
||||||
|
it("should parse script body", () => {
|
||||||
|
const input = `
|
||||||
|
script {
|
||||||
|
function onResponse(request, response) {
|
||||||
|
expect(response.status).to.equal(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const output = parser(input);
|
||||||
|
const expected = " function onResponse(request, response) {\n expect(response.status).to.equal(200);\n }";
|
||||||
|
expect(output.script).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user