diff --git a/parse.js b/parse.js index 5a00b45..526470c 100644 --- a/parse.js +++ b/parse.js @@ -57,10 +57,18 @@ module.exports = function (tokens) { } } t = token() + if (t === null) { + throw new Error('Unexpected end of input') + } if (t.type === 'LICENSEREF') { next() string += 'LicenseRef-' + t.string - return { license: string } + var node = { license: string } + var exception = parseWith() + if (exception) { + node.exception = exception + } + return node } index = begin } diff --git a/test.js b/test.js index 3ae9e96..4a2c26b 100644 --- a/test.js +++ b/test.js @@ -49,6 +49,17 @@ it('parses DocumentRefs and LicenseRefs', function () { ) }) +it('requires DocumentRefs to be followed by LicenseRef', function () { + assert.throws( + function () { p('DocumentRef-something:x') }, + /Error: Unexpected `x`/ + ) + assert.throws( + function () { p('DocumentRef-something:') }, + /Error: Unexpected end of input/ + ) +}) + // See the note in `parser.js`. it('parses `AND`, `OR` and `WITH` with the correct precedence', function () { assert.deepStrictEqual( @@ -106,6 +117,59 @@ it('allows mixed-case `and`, `or`, and `with`', function () { } }) +it('supports License with exception', function () { + assert.deepStrictEqual( + p('GPL-2.0 WITH GCC-exception-2.0'), + { + license: 'GPL-2.0', + exception: 'GCC-exception-2.0' + } + ) +}) + +it('supports LicenseRef with exception', function () { + assert.deepStrictEqual( + p('LicenseRef-something WITH GCC-exception-2.0'), + { + license: 'LicenseRef-something', + exception: 'GCC-exception-2.0' + } + ) + assert.deepStrictEqual( + p('DocumentRef-somedoc : LicenseRef-something WITH GCC-exception-2.0'), + { + license: 'DocumentRef-somedoc:LicenseRef-something', + exception: 'GCC-exception-2.0' + } + ) +}) + +it('parses simple expressions in parens', function () { + assert.deepStrictEqual( + p('(MIT)'), + { + license: 'MIT' + } + ) + assert.deepStrictEqual( + p('(LicenseRef-something)'), + { + license: 'LicenseRef-something' + } + ) +}) + +it('does not validate compound expressions with exception', function () { + assert.throws( + function () { p('(LicenseRef-something) WITH GCC-exception-2.0') }, + /Error: Syntax error/ + ) + assert.throws( + function () { p('(DocumentRef-somedoc : LicenseRef-something) WITH GCC-exception-2.0') }, + /Error: Syntax error/ + ) +}) + function it (message, test) { test() }