Jasmine: Convert action code tests
This commit is contained in:
parent
b06bd774f5
commit
03716a562d
|
@ -91,6 +91,80 @@ describe("generated parser", function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe("action code", function() {
|
||||
varyAll(function(options) {
|
||||
it("tranforms the expression result by returnung a non-|null| value", function() {
|
||||
var parser = PEG.buildParser('start = "a" { return 42; }', options);
|
||||
|
||||
expect(parser).toParse("a", 42);
|
||||
});
|
||||
|
||||
it("causes match failure by returning |null|", function() {
|
||||
var parser = PEG.buildParser('start = "a" { return null; }', options);
|
||||
|
||||
expect(parser).toFailToParse("a");
|
||||
});
|
||||
|
||||
it("is not called when the expression does not match", function() {
|
||||
var parser = PEG.buildParser(
|
||||
'start = "a" { throw "Boom!"; } / "b"',
|
||||
options
|
||||
);
|
||||
|
||||
expect(parser).toParse("b", "b");
|
||||
});
|
||||
|
||||
it("can use label variables", function() {
|
||||
var parser = PEG.buildParser('start = a:"a" { return a; }', options);
|
||||
|
||||
expect(parser).toParse("a", "a");
|
||||
});
|
||||
|
||||
it("can use the |offset| variable to get the current parse position", function() {
|
||||
var parser = PEG.buildParser(
|
||||
'start = "a" ("b" { return offset; })',
|
||||
options
|
||||
);
|
||||
|
||||
expect(parser).toParse("ab", ["a", 1]);
|
||||
});
|
||||
|
||||
if (options.trackLineAndColumn) {
|
||||
it("can use the |line| and |column| variables to get the current line and column", function() {
|
||||
var parser = PEG.buildParser([
|
||||
'{ var result; }',
|
||||
'start = line (nl+ line)* { return result; }',
|
||||
'line = thing (" "+ thing)*',
|
||||
'thing = digit / mark',
|
||||
'digit = [0-9]',
|
||||
'mark = "x" { result = [line, column]; }',
|
||||
'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
|
||||
].join("\n"), options);
|
||||
|
||||
expect(parser).toParse("1\n2\n\n3\n\n\n4 5 x", [7, 5]);
|
||||
|
||||
/* Non-Unix newlines */
|
||||
expect(parser).toParse("1\rx", [2, 1]); // Old Mac
|
||||
expect(parser).toParse("1\r\nx", [2, 1]); // Windows
|
||||
expect(parser).toParse("1\n\rx", [3, 1]); // mismatched
|
||||
|
||||
/* Strange newlines */
|
||||
expect(parser).toParse("1\u2028x", [2, 1]); // line separator
|
||||
expect(parser).toParse("1\u2029x", [2, 1]); // paragraph separator
|
||||
});
|
||||
}
|
||||
|
||||
it("does not advance position when the expression matches but the action returns |null|", function() {
|
||||
var parser = PEG.buildParser(
|
||||
'start = "a" { return null; } / "a"',
|
||||
options
|
||||
);
|
||||
|
||||
expect(parser).toParse("a", "a");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("rule reference matching", function() {
|
||||
varyAll(function(options) {
|
||||
it("follows rule references", function() {
|
||||
|
|
|
@ -449,152 +449,6 @@ testWithVaryingTrackLineAndColumn("one or more expressions", function(options) {
|
|||
parses(parser, "aaa", ["a", "a", "a"]);
|
||||
});
|
||||
|
||||
test("actions (with trackLineAndColumn: false)", function() {
|
||||
var options = { trackLineAndColumn: false };
|
||||
|
||||
var singleElementUnlabeledParser = PEG.buildParser(
|
||||
'start = "a" { return arguments.length; }',
|
||||
options
|
||||
);
|
||||
parses(singleElementUnlabeledParser, "a", 1);
|
||||
|
||||
var singleElementLabeledParser = PEG.buildParser(
|
||||
'start = a:"a" { return [arguments.length, offset, a]; }',
|
||||
options
|
||||
);
|
||||
parses(singleElementLabeledParser, "a", [2, 0, "a"]);
|
||||
|
||||
var multiElementUnlabeledParser = PEG.buildParser(
|
||||
'start = "a" "b" "c" { return arguments.length; }',
|
||||
options
|
||||
);
|
||||
parses(multiElementUnlabeledParser, "abc", 1);
|
||||
|
||||
var multiElementLabeledParser = PEG.buildParser(
|
||||
'start = a:"a" "b" c:"c" { return [arguments.length, offset, a, c]; }',
|
||||
options
|
||||
);
|
||||
parses(multiElementLabeledParser, "abc", [3, 0, "a", "c"]);
|
||||
|
||||
var innerElementsUnlabeledParser = PEG.buildParser(
|
||||
'start = "a" ("b" "c" "d" { return arguments.length; }) "e"',
|
||||
options
|
||||
);
|
||||
parses(innerElementsUnlabeledParser, "abcde", ["a", 1, "e"]);
|
||||
|
||||
var innerElementsLabeledParser = PEG.buildParser([
|
||||
'start = "a"',
|
||||
' (b:"b" "c" d:"d" { return [arguments.length, offset, b, d]; })',
|
||||
' "e"'
|
||||
].join("\n"), options);
|
||||
parses(innerElementsLabeledParser, "abcde", ["a", [3, 1, "b", "d"], "e"]);
|
||||
|
||||
/*
|
||||
* Test that the parsing position returns after successfull parsing of the
|
||||
* action expression and action returning |null|.
|
||||
*/
|
||||
var posTestParser = PEG.buildParser(
|
||||
'start = "a" { return null; } / "a"',
|
||||
options
|
||||
);
|
||||
parses(posTestParser, "a", "a");
|
||||
|
||||
/* Test that the action is not called when its expression does not match. */
|
||||
var notAMatchParser = PEG.buildParser(
|
||||
'start = "a" { ok(false, "action got called when it should not be"); }',
|
||||
options
|
||||
);
|
||||
doesNotParse(notAMatchParser, "b");
|
||||
});
|
||||
|
||||
test("actions (with trackLineAndColumn: true)", function() {
|
||||
var options = { trackLineAndColumn: true };
|
||||
|
||||
var singleElementUnlabeledParser = PEG.buildParser(
|
||||
'start = "a" { return arguments.length; }',
|
||||
options
|
||||
);
|
||||
parses(singleElementUnlabeledParser, "a", 3);
|
||||
|
||||
var singleElementLabeledParser = PEG.buildParser(
|
||||
'start = a:"a" { return [arguments.length, offset, line, column, a]; }',
|
||||
options
|
||||
);
|
||||
parses(singleElementLabeledParser, "a", [4, 0, 1, 1, "a"]);
|
||||
|
||||
var multiElementUnlabeledParser = PEG.buildParser(
|
||||
'start = "a" "b" "c" { return arguments.length; }',
|
||||
options
|
||||
);
|
||||
parses(multiElementUnlabeledParser, "abc", 3);
|
||||
|
||||
var multiElementLabeledParser = PEG.buildParser([
|
||||
'start = a:"a" "b" c:"c" {',
|
||||
' return [arguments.length, offset, line, column, a, c];',
|
||||
'}'
|
||||
].join("\n"), options);
|
||||
parses(multiElementLabeledParser, "abc", [5, 0, 1, 1, "a", "c"]);
|
||||
|
||||
var innerElementsUnlabeledParser = PEG.buildParser(
|
||||
'start = "a" ("b" "c" "d" { return arguments.length; }) "e"',
|
||||
options
|
||||
);
|
||||
parses(innerElementsUnlabeledParser, "abcde", ["a", 3, "e"]);
|
||||
|
||||
var innerElementsLabeledParser = PEG.buildParser([
|
||||
'start = "a"',
|
||||
' (',
|
||||
' b:"b" "c" d:"d" {',
|
||||
' return [arguments.length, offset, line, column, b, d];',
|
||||
' }',
|
||||
' )',
|
||||
' "e"'
|
||||
].join("\n"), options);
|
||||
parses(
|
||||
innerElementsLabeledParser,
|
||||
"abcde",
|
||||
["a", [5, 1, 1, 2, "b", "d"], "e"]
|
||||
);
|
||||
|
||||
/*
|
||||
* Test that the parsing position returns after successfull parsing of the
|
||||
* action expression and action returning |null|.
|
||||
*/
|
||||
var posTestParser = PEG.buildParser(
|
||||
'start = "a" { return null; } / "a"',
|
||||
options
|
||||
);
|
||||
parses(posTestParser, "a", "a");
|
||||
|
||||
/* Test that the action is not called when its expression does not match. */
|
||||
var notAMatchParser = PEG.buildParser(
|
||||
'start = "a" { ok(false, "action got called when it should not be"); }',
|
||||
options
|
||||
);
|
||||
doesNotParse(notAMatchParser, "b");
|
||||
|
||||
var numbersParser = PEG.buildParser([
|
||||
'{ var result; }',
|
||||
'start = line (nl+ line)* { return result; }',
|
||||
'line = thing (" "+ thing)*',
|
||||
'thing = digit / mark',
|
||||
'digit = [0-9]',
|
||||
'mark = "x" { result = [line, column]; }',
|
||||
'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")'
|
||||
].join("\n"), options);
|
||||
|
||||
parses(numbersParser, "1\n2\n\n3\n\n\n4 5 x", [7, 5]);
|
||||
|
||||
/* Non-Unix newlines */
|
||||
parses(numbersParser, "1\rx", [2, 1]); // Old Mac
|
||||
parses(numbersParser, "1\r\nx", [2, 1]); // Windows
|
||||
parses(numbersParser, "1\n\rx", [3, 1]); // mismatched
|
||||
|
||||
/* Strange newlines */
|
||||
parses(numbersParser, "1\u2028x", [2, 1]); // line separator
|
||||
parses(numbersParser, "1\u2029x", [2, 1]); // paragraph separator
|
||||
});
|
||||
|
||||
testWithVaryingTrackLineAndColumn("initializer", function(options) {
|
||||
var variableInActionParser = PEG.buildParser(
|
||||
'{ a = 42; }; start = "a" { return a; }',
|
||||
|
|
Loading…
Reference in a new issue