From 03716a562d50aac359a6f4892ef1b2f17d8f5e5b Mon Sep 17 00:00:00 2001 From: David Majda Date: Sun, 22 Apr 2012 14:55:00 +0200 Subject: [PATCH] Jasmine: Convert action code tests --- spec/generated-parser.spec.js | 74 +++++++++++++++++ test/compiler-test.js | 146 ---------------------------------- 2 files changed, 74 insertions(+), 146 deletions(-) diff --git a/spec/generated-parser.spec.js b/spec/generated-parser.spec.js index a26fce6..be6ecd4 100644 --- a/spec/generated-parser.spec.js +++ b/spec/generated-parser.spec.js @@ -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() { diff --git a/test/compiler-test.js b/test/compiler-test.js index 3de8cd8..d0ee3aa 100644 --- a/test/compiler-test.js +++ b/test/compiler-test.js @@ -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; }',