Skip to content

Commit

Permalink
Check allowedStartRules. (#175)
Browse files Browse the repository at this point in the history
Check allowedStartRules.  Fixes #166.
  • Loading branch information
hildjj authored Aug 16, 2021
1 parent 11f46d9 commit 29edafc
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Released: TBD
- New CLI [@hildjj](https://github.com/peggyjs/peggy/pull/167)
- Backward compatible with the previous
- New -t/--test and -T/--testfile flags to directly test the generated grammar
- Check allowedStartRules for validity [@hildjj](https://github.com/peggyjs/peggy/pull/175)

1.2.0
-----
Expand Down
13 changes: 13 additions & 0 deletions lib/compiler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ const compiler = {
trace: false,
});

if (!Array.isArray(options.allowedStartRules)) {
throw new Error("allowedStartRules must be an array");
}
if (options.allowedStartRules.length === 0) {
throw new Error("Must have at least one start rule");
}
const allRules = ast.rules.map(r => r.name);
for (const rule of options.allowedStartRules) {
if (allRules.indexOf(rule) === -1) {
throw new Error(`Unknown start rule "${rule}"`);
}
}

Object.keys(passes).forEach(stage => {
passes[stage].forEach(p => { p(ast, options); });
});
Expand Down
16 changes: 9 additions & 7 deletions test/cli/run.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ type Options = {
stdin?: string | Buffer;
};

const foobarbaz = `\
foo = '1'
bar = '2'
baz = '3'
`;

/** Execution failed */
class ExecError extends Error {
/** Result error code, always non-zero */
Expand Down Expand Up @@ -141,11 +147,7 @@ Options:
it("handles start rules", async() => {
await expect(exec({
args: ["--allowed-start-rules", "foo,bar,baz"],
stdin: `\
foo = "1"
bar = "2"
baz = "3"
`,
stdin: foobarbaz,
})).resolves.toMatch(
/startRuleFunctions = { foo: [^, ]+, bar: [^, ]+, baz: \S+ }/
);
Expand Down Expand Up @@ -239,7 +241,7 @@ baz = "3"

const res = await exec({
args: ["--extra-options-file", optFile],
stdin: "foo = '1'",
stdin: foobarbaz,
});
expect(res).toMatch(
/startRuleFunctions = { foo: [^, ]+, bar: [^, ]+, baz: \S+ }/
Expand All @@ -249,7 +251,7 @@ baz = "3"
// Intentional overwrite
await expect(exec({
args: ["-c", optFile, "--format", "amd"],
stdin: "foo = '1'",
stdin: foobarbaz,
})).resolves.toMatch(/^define\(/m);

await expect(exec({
Expand Down
33 changes: 33 additions & 0 deletions test/unit/compiler.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"use strict";

const chai = require("chai");
const parser = require("../../lib/parser");
const compiler = require("../../lib/compiler/index");

const expect = chai.expect;

describe("Peggy compiler", () => {
it("checks start rules", () => {
const ast = parser.parse("foo='1'");
expect(compiler.compile(ast, compiler.passes)).to.be.an("object");
expect(() => compiler.compile(ast, compiler.passes, {
allowedStartRules: null,
})).to.throw("allowedStartRules must be an array");
expect(() => compiler.compile(ast, compiler.passes, {
allowedStartRules: [],
})).to.throw("Must have at least one start rule");
expect(() => compiler.compile(ast, compiler.passes, {
allowedStartRules: ["bar"],
})).to.throw('Unknown start rule "bar"');
});

it("checks ouput type", () => {
const ast = parser.parse("foo='1'");
expect(compiler.compile(ast, compiler.passes, {
output: "source",
})).to.be.a("string");
expect(() => compiler.compile(ast, compiler.passes, {
output: "INVALID OUTPUT TYPE",
})).to.throw("Invalid output format: INVALID OUTPUT TYPE.");
});
});

0 comments on commit 29edafc

Please sign in to comment.