From 94aaf4ec75161567e7725ea3e0c1843b4693c85b Mon Sep 17 00:00:00 2001 From: David Majda Date: Sun, 22 Apr 2012 19:45:34 +0200 Subject: [PATCH] Jasmine: Convert error position reporting tests --- spec/generated-parser.spec.js | 104 +++++++++++++++++++++++++++++++--- test/compiler-test.js | 27 --------- 2 files changed, 96 insertions(+), 35 deletions(-) diff --git a/spec/generated-parser.spec.js b/spec/generated-parser.spec.js index a32ddab..9db3c6a 100644 --- a/spec/generated-parser.spec.js +++ b/spec/generated-parser.spec.js @@ -66,24 +66,50 @@ describe("generated parser", function() { } }, - toFailToParse: function(input) { - var result; + toFailToParse: function(input, details) { + /* + * Extracted into a function just to silence JSHint complaining about + * creating functions in a loop. + */ + function buildKeyMessage(key, value) { + return function() { + return "Expected " + jasmine.pp(input) + " to fail to parse" + + (details ? " with details " + jasmine.pp(details) : "") + ", " + + "but " + jasmine.pp(key) + " " + + "is " + jasmine.pp(value) + "."; + }; + } + + var result, key; try { result = this.actual.parse(input); this.message = function() { - return "Expected " + jasmine.pp(input) + " to fail to parse, " + return "Expected " + jasmine.pp(input) + " to fail to parse" + + (details ? " with details " + jasmine.pp(details) : "") + ", " + "but it parsed as " + jasmine.pp(result) + "."; }; return false; } catch (e) { - this.message = function() { - return "Expected " + jasmine.pp(input) + " to parse, " - + "but it failed with message " - + jasmine.pp(e.message) + "."; - }; + if (this.isNot) { + this.message = function() { + return "Expected " + jasmine.pp(input) + " to parse, " + + "but it failed with message " + + jasmine.pp(e.message) + "."; + }; + } else { + if (details) { + for (key in details) { + if (!this.env.equals_(e[key], details[key])) { + this.message = buildKeyMessage(key, e[key]); + + return false; + } + } + } + } return true; } @@ -644,6 +670,68 @@ describe("generated parser", function() { }); }); + describe("error reporting", function() { + varyAll(function(options) { + describe("position reporting", function() { + it("reports position correctly with invalid input", function() { + var parser = PEG.buildParser('start = "a"', options); + + expect(parser).toFailToParse("b", { offset: 0, line: 1, column: 1 }); + }); + + it("reports position correctly with trailing input", function() { + var parser = PEG.buildParser('start = "a"', options); + + expect(parser).toFailToParse("aa", { offset: 1, line: 1, column: 2}); + }); + + it("reports position correctly in complex cases", function() { + var parser = PEG.buildParser([ + 'start = line (nl+ line)*', + 'line = digit (" "+ digit)*', + 'digit = [0-9]', + 'nl = ("\\r" / "\\n" / "\\u2028" / "\\u2029")' + ].join("\n"), options); + + expect(parser).toFailToParse("1\n2\n\n3\n\n\n4 5 x", { + offset: 13, + line: 7, + column: 5 + }); + + /* Non-Unix newlines */ + expect(parser).toFailToParse("1\rx", { // Old Mac + offset: 2, + line: 2, + column: 1 + }); + expect(parser).toFailToParse("1\r\nx", { // Windows + offset: 3, + line: 2, + column: 1 + }); + expect(parser).toFailToParse("1\n\rx", { // mismatched + offset: 3, + line: 3, + column: 1 + }); + + /* Strange newlines */ + expect(parser).toFailToParse("1\u2028x", { // line separator + offset: 2, + line: 2, + column: 1 + }); + expect(parser).toFailToParse("1\u2029x", { // paragraph separator + offset: 2, + line: 2, + column: 1 + }); + }); + }); + }); + }); + /* * Following examples are from Wikipedia, see * http://en.wikipedia.org/w/index.php?title=Parsing_expression_grammar&oldid=335106938. diff --git a/test/compiler-test.js b/test/compiler-test.js index 2dc6484..e28300d 100644 --- a/test/compiler-test.js +++ b/test/compiler-test.js @@ -160,31 +160,4 @@ testWithVaryingTrackLineAndColumn("error details", function(options) { ); }); -testWithVaryingTrackLineAndColumn("error positions", function(options) { - var simpleParser = PEG.buildParser('start = "a"', options); - - /* Regular match failure */ - doesNotParseWithPos(simpleParser, "b", 0, 1, 1); - - /* Trailing input */ - doesNotParseWithPos(simpleParser, "ab", 1, 1, 2); - - var digitsParser = PEG.buildParser([ - 'start = line (("\\r" / "\\n" / "\\u2028" / "\\u2029")+ line)*', - 'line = digits (" "+ digits)*', - 'digits = digits:[0-9]+ { return digits.join(""); }' - ].join("\n"), options); - - doesNotParseWithPos(digitsParser, "1\n2\n\n3\n\n\n4 5 x", 13, 7, 5); - - /* Non-Unix newlines */ - doesNotParseWithPos(digitsParser, "1\rx", 2, 2, 1); // Old Mac - doesNotParseWithPos(digitsParser, "1\r\nx", 3, 2, 1); // Windows - doesNotParseWithPos(digitsParser, "1\n\rx", 3, 3, 1); // mismatched - - /* Strange newlines */ - doesNotParseWithPos(digitsParser, "1\u2028x", 2, 2, 1); // line separator - doesNotParseWithPos(digitsParser, "1\u2029x", 2, 2, 1); // paragraph separator -}); - })();