4 const assert
= require('assert');
6 describe('RFC 8288 Header parser', function () {
7 const { parse
, SyntaxError: PEGSyntaxError
} = require('../../lib/rfc8288-web-linking');
9 function checkParser(linkHeader
, expectedResult
) {
10 const result
= parse(linkHeader
.replace(/\r?\n|\r/gm, ''));
11 assert
.deepStrictEqual(result
, expectedResult
);
14 describe('§3.3 Relation Type', function () {
15 it('Must ignore occurrences after the first', function () {
17 '<http://example.org/>;',
18 'rel="start"; rel="ignore"; foo',
20 const expectedResult
= [
22 target: 'http://example.org/',
37 checkParser(linkHeader
, expectedResult
);
41 describe('§3.5 Link Header Field Examples', function () {
44 '<http://example.com/TheBook/chapter2>; rel="previous";',
45 'title="previous chapter"',
47 const expectedResult
= [
49 target: 'http://example.com/TheBook/chapter2',
59 value: 'previous chapter',
64 checkParser(linkHeader
, expectedResult
);
67 const linkHeader
= '</>; rel="http://example.net/foo"';
68 const expectedResult
= [
75 value: 'http://example.net/foo',
80 checkParser(linkHeader
, expectedResult
);
83 const linkHeader
= '</terms>; rel="copyright"; anchor="#foo"';
84 const expectedResult
= [
101 checkParser(linkHeader
, expectedResult
);
103 it('d', function () {
105 '</TheBook/chapter2>;',
106 'rel="previous"; title*=UTF-8\'de\'letztes%20Kapitel,',
107 '</TheBook/chapter4>;',
108 'rel="next"; title*=UTF-8\'de\'n%c3%a4chstes%20Kapitel',
110 const expectedResult
= [
112 target: '/TheBook/chapter2',
122 value: 'UTF-8\'de\'letztes%20Kapitel',
127 target: '/TheBook/chapter4',
137 value: 'UTF-8\'de\'n%c3%a4chstes%20Kapitel',
142 checkParser(linkHeader
, expectedResult
);
144 it('e', function () {
146 '<http://example.org/>;',
147 'rel="start http://example.net/relation/other"',
149 const expectedResult
= [
151 target: 'http://example.org/',
156 value: 'start http://example.net/relation/other',
161 checkParser(linkHeader
, expectedResult
);
163 it('f', function () {
165 '<https://example.org/>; rel="start",',
166 ' <https://example.org/index>; rel="index"',
168 const expectedResult
= [
170 target: 'https://example.org/',
180 target: 'https://example.org/index',
190 checkParser(linkHeader
, expectedResult
);
192 }); // §3.5 Link Header Field Examples
194 describe('Unusual Cases', function () {
195 it('handles uris with semicolons', function () {
197 '<http://example.com/strange;url;indeed>; rel="self";',
199 const expectedResult
= [
201 target: 'http://example.com/strange;url;indeed',
211 checkParser(linkHeader
, expectedResult
);
213 it('handles value-less attributes', function () {
215 '</>; special; rel="special";',
217 const expectedResult
= [
234 checkParser(linkHeader
, expectedResult
);
238 describe('Extended Values', function () {
239 it('decodes extended value', function () {
240 const extendedValue
= 'UTF-8\'\'%c2%a3%20and%20%e2%82%ac%20rates';
241 const expectedResult
= {
244 value: '£ and € rates',
246 const result
= parse(extendedValue
, { startRule: 'extendedValue' });
247 assert
.deepStrictEqual(result
, expectedResult
);
249 }); // Extended Values
251 describe('Failures', function () {
252 it('does not parse invalid header', function () {
253 const linkHeader
= 'not a link header';
254 const expectedResult
= [];
256 checkParser(linkHeader
, expectedResult
);
257 assert
.fail('unexpected success');
259 assert
.strictEqual(e
.name
, 'SyntaxError');
262 it('does not parse partial invalid header', function () {
263 const linkHeader
= '<https://example.com/foo>; rel="valid", not a link header';
264 const expectedResult
= [];
266 checkParser(linkHeader
, expectedResult
);
267 assert
.fail('unexpected success');
269 assert(e
instanceof PEGSyntaxError
);
270 assert
.strictEqual(e
.name
, 'SyntaxError');