Skip to content

Commit 29edafc

Browse files
authored
Check allowedStartRules. (#175)
Check allowedStartRules. Fixes #166.
1 parent 11f46d9 commit 29edafc

File tree

4 files changed

+56
-7
lines changed

4 files changed

+56
-7
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Released: TBD
1313
- New CLI [@hildjj](https://github.com/peggyjs/peggy/pull/167)
1414
- Backward compatible with the previous
1515
- New -t/--test and -T/--testfile flags to directly test the generated grammar
16+
- Check allowedStartRules for validity [@hildjj](https://github.com/peggyjs/peggy/pull/175)
1617

1718
1.2.0
1819
-----

lib/compiler/index.js

+13
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,19 @@ const compiler = {
7474
trace: false,
7575
});
7676

77+
if (!Array.isArray(options.allowedStartRules)) {
78+
throw new Error("allowedStartRules must be an array");
79+
}
80+
if (options.allowedStartRules.length === 0) {
81+
throw new Error("Must have at least one start rule");
82+
}
83+
const allRules = ast.rules.map(r => r.name);
84+
for (const rule of options.allowedStartRules) {
85+
if (allRules.indexOf(rule) === -1) {
86+
throw new Error(`Unknown start rule "${rule}"`);
87+
}
88+
}
89+
7790
Object.keys(passes).forEach(stage => {
7891
passes[stage].forEach(p => { p(ast, options); });
7992
});

test/cli/run.spec.ts

+9-7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ type Options = {
1212
stdin?: string | Buffer;
1313
};
1414

15+
const foobarbaz = `\
16+
foo = '1'
17+
bar = '2'
18+
baz = '3'
19+
`;
20+
1521
/** Execution failed */
1622
class ExecError extends Error {
1723
/** Result error code, always non-zero */
@@ -141,11 +147,7 @@ Options:
141147
it("handles start rules", async() => {
142148
await expect(exec({
143149
args: ["--allowed-start-rules", "foo,bar,baz"],
144-
stdin: `\
145-
foo = "1"
146-
bar = "2"
147-
baz = "3"
148-
`,
150+
stdin: foobarbaz,
149151
})).resolves.toMatch(
150152
/startRuleFunctions = { foo: [^, ]+, bar: [^, ]+, baz: \S+ }/
151153
);
@@ -239,7 +241,7 @@ baz = "3"
239241

240242
const res = await exec({
241243
args: ["--extra-options-file", optFile],
242-
stdin: "foo = '1'",
244+
stdin: foobarbaz,
243245
});
244246
expect(res).toMatch(
245247
/startRuleFunctions = { foo: [^, ]+, bar: [^, ]+, baz: \S+ }/
@@ -249,7 +251,7 @@ baz = "3"
249251
// Intentional overwrite
250252
await expect(exec({
251253
args: ["-c", optFile, "--format", "amd"],
252-
stdin: "foo = '1'",
254+
stdin: foobarbaz,
253255
})).resolves.toMatch(/^define\(/m);
254256

255257
await expect(exec({

test/unit/compiler.spec.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"use strict";
2+
3+
const chai = require("chai");
4+
const parser = require("../../lib/parser");
5+
const compiler = require("../../lib/compiler/index");
6+
7+
const expect = chai.expect;
8+
9+
describe("Peggy compiler", () => {
10+
it("checks start rules", () => {
11+
const ast = parser.parse("foo='1'");
12+
expect(compiler.compile(ast, compiler.passes)).to.be.an("object");
13+
expect(() => compiler.compile(ast, compiler.passes, {
14+
allowedStartRules: null,
15+
})).to.throw("allowedStartRules must be an array");
16+
expect(() => compiler.compile(ast, compiler.passes, {
17+
allowedStartRules: [],
18+
})).to.throw("Must have at least one start rule");
19+
expect(() => compiler.compile(ast, compiler.passes, {
20+
allowedStartRules: ["bar"],
21+
})).to.throw('Unknown start rule "bar"');
22+
});
23+
24+
it("checks ouput type", () => {
25+
const ast = parser.parse("foo='1'");
26+
expect(compiler.compile(ast, compiler.passes, {
27+
output: "source",
28+
})).to.be.a("string");
29+
expect(() => compiler.compile(ast, compiler.passes, {
30+
output: "INVALID OUTPUT TYPE",
31+
})).to.throw("Invalid output format: INVALID OUTPUT TYPE.");
32+
});
33+
});

0 commit comments

Comments
 (0)