Skip to content

Commit

Permalink
Jasmine: Convert action code tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dmajda committed May 6, 2012
1 parent b06bd77 commit 03716a5
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 146 deletions.
74 changes: 74 additions & 0 deletions spec/generated-parser.spec.js
Expand Up @@ -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() {
Expand Down
146 changes: 0 additions & 146 deletions test/compiler-test.js
Expand Up @@ -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; }',
Expand Down

0 comments on commit 03716a5

Please sign in to comment.