From e1399c0168703d0d245229ceed2a41806cd37b91 Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Sat, 6 Sep 2014 12:33:19 +0200 Subject: [PATCH] Add error messages --- gradient-parser.js | 76 ++++++++++++++++++++---------- spec/gradient-parser.spec.js | 91 ++++++++++++++++++++++++++++++++++-- 2 files changed, 139 insertions(+), 28 deletions(-) diff --git a/gradient-parser.js b/gradient-parser.js index 8437842..a2d8648 100644 --- a/gradient-parser.js +++ b/gradient-parser.js @@ -39,27 +39,27 @@ module.exports = (function() { } function getAST() { - var ast = listDefinitions(); + var ast = matchListDefinitions(); if (input.length > 0) { - error(input, cursor, 'Invalid input not EOF'); + error('Invalid input not EOF'); } return ast; - }; + } - function listDefinitions() { + function matchListDefinitions() { var definitions = [], - currentDefinition = definition(); + currentDefinition = matchDefinition(); if (currentDefinition) { definitions.push(currentDefinition); while (scan(tokens.comma)) { - currentDefinition = definition(); + currentDefinition = matchDefinition(); if (currentDefinition) { definitions.push(currentDefinition); } else { - // throw error + error('One extra comma'); } } } @@ -67,22 +67,35 @@ module.exports = (function() { return definitions; } - function definition() { - return linearGradient(); + function matchDefinition() { + return matchLinearGradient(); } - function linearGradient() { + function matchLinearGradient() { var captures = scan(tokens.linearGradient), orientation, colorStops; - if (captures) { - scan(tokens.startCall); + if (!scan(tokens.startCall)) { + error('Missing ('); + } + orientation = matchOrientation(); - scan(tokens.comma); + if (orientation) { + if (!scan(tokens.comma)) { + error('Missing comma before color stops'); + } + } + colorStops = matchColorStops(); - scan(tokens.endCall); + if (!colorStops.length) { + error('Missing color definitions'); + } + + if (!scan(tokens.endCall)) { + error('Missing )'); + } return { type: 'linear-gradient', @@ -93,10 +106,10 @@ module.exports = (function() { } function matchOrientation() { - return sideOrCorner(); + return matchSideOrCorner(); } - function sideOrCorner() { + function matchSideOrCorner() { var captures = scan(tokens.sideOrCorner); if (captures) { return { @@ -107,18 +120,17 @@ module.exports = (function() { } function matchColorStops() { - var literalColors = /^([a-zA-Z]+)/, - captures = scan(literalColors), + var color = matchColorStop(), colors = []; - if (captures) { - colors.push(captures[0].toLowerCase()); + if (color) { + colors.push(color); while (scan(tokens.comma)) { - captures = scan(literalColors); - if (captures) { - colors.push(captures[0].toLowerCase()); + color = matchColorStop(); + if (color) { + colors.push(color); } else { - // trow error + error('One extra comma'); } } } @@ -126,6 +138,22 @@ module.exports = (function() { return colors; } + function matchColorStop() { + return matchLiteralColor(); + } + + function matchLiteralColor() { + var literalColors = /^([a-zA-Z]+)/, + captures = scan(literalColors); + + if (captures) { + return { + type: 'literal', + value: captures[0].toLowerCase() + }; + } + } + function scan(regexp) { var captures, blankCaptures; diff --git a/spec/gradient-parser.spec.js b/spec/gradient-parser.spec.js index 5649844..9a64715 100644 --- a/spec/gradient-parser.spec.js +++ b/spec/gradient-parser.spec.js @@ -32,20 +32,103 @@ var gradientParser = require('gradient-parser'); // ] describe('gradient-parser.js', function () { + var ast, + subject; + it('should exist', function () { expect(typeof gradientParser).to.equal('function'); }); - describe('when parsing a simple definition', function(){ - var ast; + describe('when parsing wrong definition should throw an error', function() { + it('when there\'s one more comma in definitions', function() { + expect(function() { + gradientParser('linear-gradient(red, blue),'); + }).to.throwException(/One extra comma/); + }); + it('when there\'s one more comma in colors', function() { + expect(function() { + gradientParser('linear-gradient(red, blue,)'); + }).to.throwException(/One extra comma/); + }); + + it('when there\'s invalid input', function() { + expect(function() { + gradientParser('linear-gradient(red, blue) aaa'); + }).to.throwException(/Invalid input not EOF/); + }); + + it('when there\'s missing open call', function() { + expect(function() { + gradientParser('linear-gradient red, blue'); + }).to.throwException(/Missing \(/); + }); + + it('when there\'s missing comma before color stops', function() { + expect(function() { + gradientParser('linear-gradient(to right red, blue)'); + }).to.throwException(/Missing comma before color stops/); + }); + + it('when there\'s missing color stops', function() { + expect(function() { + gradientParser('linear-gradient(to right, )'); + }).to.throwException(/Missing color definitions/); + }); + + it('when there\'s missing closing call', function() { + expect(function() { + gradientParser('linear-gradient(to right, red, blue aaa'); + }).to.throwException(/Missing \)/); + }); + }); + + describe('when parsing a simple definition', function(){ beforeEach(function() { - ast = gradientParser('linear-gradient(to right bottom, red, blue)'); + ast = gradientParser('linear-gradient(red, blue)'); + subject = ast[0]; }); it('should get the gradient type', function () { - expect(ast[0].type).to.equal('linear-gradient'); + expect(subject.type).to.equal('linear-gradient'); }); + it('should get the orientation', function() { + expect(subject.orientation).to.be(undefined); + }); + + describe('colors', function() { + it('should get all colors', function() { + expect(subject.colorStops).to.have.length(2); + }); + + describe('first color', function() { + beforeEach(function() { + subject = subject.colorStops[0]; + }); + + it('should get literal type', function() { + expect(subject.type).to.equal('literal'); + }); + + it('should get the right color', function() { + expect(subject.value).to.equal('red'); + }); + }); + + describe('second color', function() { + beforeEach(function() { + subject = subject.colorStops[1]; + }); + + it('should get literal type', function() { + expect(subject.type).to.equal('literal'); + }); + + it('should get the right color', function() { + expect(subject.value).to.equal('blue'); + }); + }); + }); }); });