You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
4.1 KiB
JavaScript
157 lines
4.1 KiB
JavaScript
"use strict";
|
|
|
|
let peg = require("../../lib/peg");
|
|
|
|
describe("plugin API", function() {
|
|
beforeEach(function() {
|
|
this.addMatchers({
|
|
toBeObject() {
|
|
this.message = () =>
|
|
"Expected " + jasmine.pp(this.actual) + " "
|
|
+ (this.isNot ? "not " : "")
|
|
+ "to be an object.";
|
|
|
|
return this.actual !== null && typeof this.actual === "object";
|
|
},
|
|
|
|
toBeArray() {
|
|
this.message = () =>
|
|
"Expected " + jasmine.pp(this.actual) + " "
|
|
+ (this.isNot ? "not " : "")
|
|
+ "to be an array.";
|
|
|
|
return Object.prototype.toString.apply(this.actual) === "[object Array]";
|
|
},
|
|
|
|
toBeFunction() {
|
|
this.message = () =>
|
|
"Expected " + jasmine.pp(this.actual) + " "
|
|
+ (this.isNot ? "not " : "")
|
|
+ "to be a function.";
|
|
|
|
return typeof this.actual === "function";
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("use", function() {
|
|
let grammar = "start = 'a'";
|
|
|
|
it("is called for each plugin", function() {
|
|
let pluginsUsed = [false, false, false];
|
|
let plugins = [
|
|
{ use() { pluginsUsed[0] = true; } },
|
|
{ use() { pluginsUsed[1] = true; } },
|
|
{ use() { pluginsUsed[2] = true; } }
|
|
];
|
|
|
|
peg.generate(grammar, { plugins: plugins });
|
|
|
|
expect(pluginsUsed).toEqual([true, true, true]);
|
|
});
|
|
|
|
it("receives configuration", function() {
|
|
let plugin = {
|
|
use(config) {
|
|
expect(config).toBeObject();
|
|
|
|
expect(config.parser).toBeObject();
|
|
expect(config.parser.parse("start = 'a'")).toBeObject();
|
|
|
|
expect(config.passes).toBeObject();
|
|
|
|
expect(config.passes.check).toBeArray();
|
|
config.passes.check.forEach(pass => {
|
|
expect(pass).toBeFunction();
|
|
});
|
|
|
|
expect(config.passes.transform).toBeArray();
|
|
config.passes.transform.forEach(pass => {
|
|
expect(pass).toBeFunction();
|
|
});
|
|
|
|
expect(config.passes.generate).toBeArray();
|
|
config.passes.generate.forEach(pass => {
|
|
expect(pass).toBeFunction();
|
|
});
|
|
}
|
|
};
|
|
|
|
peg.generate(grammar, { plugins: [plugin] });
|
|
});
|
|
|
|
it("receives options", function() {
|
|
let plugin = {
|
|
use(config, options) {
|
|
expect(options).toEqual(generateOptions);
|
|
}
|
|
};
|
|
let generateOptions = { plugins: [plugin], foo: 42 };
|
|
|
|
peg.generate(grammar, generateOptions);
|
|
});
|
|
|
|
it("can replace parser", function() {
|
|
let plugin = {
|
|
use(config) {
|
|
let parser = peg.generate([
|
|
"start = .* {",
|
|
" return {",
|
|
" type: 'grammar',",
|
|
" rules: [",
|
|
" {",
|
|
" type: 'rule',",
|
|
" name: 'start',",
|
|
" expression: { type: 'literal', value: text(), ignoreCase: false }",
|
|
" }",
|
|
" ]",
|
|
" };",
|
|
"}"
|
|
].join("\n"));
|
|
|
|
config.parser = parser;
|
|
}
|
|
};
|
|
let parser = peg.generate("a", { plugins: [plugin] });
|
|
|
|
expect(parser.parse("a")).toBe("a");
|
|
});
|
|
|
|
it("can change compiler passes", function() {
|
|
let plugin = {
|
|
use(config) {
|
|
let pass = ast => {
|
|
ast.code = "({ parse: function() { return 42; } })";
|
|
};
|
|
|
|
config.passes.generate = [pass];
|
|
}
|
|
};
|
|
let parser = peg.generate(grammar, { plugins: [plugin] });
|
|
|
|
expect(parser.parse("a")).toBe(42);
|
|
});
|
|
|
|
it("can change options", function() {
|
|
let grammar = [
|
|
"a = 'x'",
|
|
"b = 'x'",
|
|
"c = 'x'"
|
|
].join("\n");
|
|
let plugin = {
|
|
use(config, options) {
|
|
options.allowedStartRules = ["b", "c"];
|
|
}
|
|
};
|
|
let parser = peg.generate(grammar, {
|
|
allowedStartRules: ["a"],
|
|
plugins: [plugin]
|
|
});
|
|
|
|
expect(() => { parser.parse("x", { startRule: "a" }); }).toThrow();
|
|
expect(parser.parse("x", { startRule: "b" })).toBe("x");
|
|
expect(parser.parse("x", { startRule: "c" })).toBe("x");
|
|
});
|
|
});
|
|
});
|