extension.test.js (5122B)
1 'use strict'; 2 3 const assert = require('assert'); 4 5 const { format, parse } = require('../lib/extension'); 6 7 describe('extension', () => { 8 describe('parse', () => { 9 it('parses a single extension', () => { 10 assert.deepStrictEqual(parse('foo'), { 11 foo: [{ __proto__: null }], 12 __proto__: null 13 }); 14 }); 15 16 it('parses params', () => { 17 assert.deepStrictEqual(parse('foo;bar;baz=1;bar=2'), { 18 foo: [{ bar: [true, '2'], baz: ['1'], __proto__: null }], 19 __proto__: null 20 }); 21 }); 22 23 it('parses multiple extensions', () => { 24 assert.deepStrictEqual(parse('foo,bar;baz,foo;baz'), { 25 foo: [{ __proto__: null }, { baz: [true], __proto__: null }], 26 bar: [{ baz: [true], __proto__: null }], 27 __proto__: null 28 }); 29 }); 30 31 it('parses quoted params', () => { 32 assert.deepStrictEqual(parse('foo;bar="hi"'), { 33 foo: [{ bar: ['hi'], __proto__: null }], 34 __proto__: null 35 }); 36 assert.deepStrictEqual(parse('foo;bar="\\0"'), { 37 foo: [{ bar: ['0'], __proto__: null }], 38 __proto__: null 39 }); 40 assert.deepStrictEqual(parse('foo;bar="b\\a\\z"'), { 41 foo: [{ bar: ['baz'], __proto__: null }], 42 __proto__: null 43 }); 44 assert.deepStrictEqual(parse('foo;bar="b\\az";bar'), { 45 foo: [{ bar: ['baz', true], __proto__: null }], 46 __proto__: null 47 }); 48 assert.throws( 49 () => parse('foo;bar="baz"qux'), 50 /^SyntaxError: Unexpected character at index 13$/ 51 ); 52 assert.throws( 53 () => parse('foo;bar="baz" qux'), 54 /^SyntaxError: Unexpected character at index 14$/ 55 ); 56 }); 57 58 it('works with names that match `Object.prototype` property names', () => { 59 assert.deepStrictEqual(parse('hasOwnProperty, toString'), { 60 hasOwnProperty: [{ __proto__: null }], 61 toString: [{ __proto__: null }], 62 __proto__: null 63 }); 64 assert.deepStrictEqual(parse('foo;constructor'), { 65 foo: [{ constructor: [true], __proto__: null }], 66 __proto__: null 67 }); 68 }); 69 70 it('ignores the optional white spaces', () => { 71 const header = 'foo; bar\t; \tbaz=1\t ; bar="1"\t\t, \tqux\t ;norf'; 72 73 assert.deepStrictEqual(parse(header), { 74 foo: [{ bar: [true, '1'], baz: ['1'], __proto__: null }], 75 qux: [{ norf: [true], __proto__: null }], 76 __proto__: null 77 }); 78 }); 79 80 it('throws an error if a name is empty', () => { 81 [ 82 [',', 0], 83 ['foo,,', 4], 84 ['foo, ,', 6], 85 ['foo;=', 4], 86 ['foo; =', 5], 87 ['foo;;', 4], 88 ['foo; ;', 5], 89 ['foo;bar=,', 8], 90 ['foo;bar=""', 9] 91 ].forEach((element) => { 92 assert.throws( 93 () => parse(element[0]), 94 new RegExp( 95 `^SyntaxError: Unexpected character at index ${element[1]}$` 96 ) 97 ); 98 }); 99 }); 100 101 it('throws an error if a white space is misplaced', () => { 102 [ 103 [' foo', 0], 104 ['f oo', 2], 105 ['foo;ba r', 7], 106 ['foo;bar =', 8], 107 ['foo;bar= ', 8], 108 ['foo;bar=ba z', 11] 109 ].forEach((element) => { 110 assert.throws( 111 () => parse(element[0]), 112 new RegExp( 113 `^SyntaxError: Unexpected character at index ${element[1]}$` 114 ) 115 ); 116 }); 117 }); 118 119 it('throws an error if a token contains invalid characters', () => { 120 [ 121 ['f@o', 1], 122 ['f\\oo', 1], 123 ['"foo"', 0], 124 ['f"oo"', 1], 125 ['foo;b@r', 5], 126 ['foo;b\\ar', 5], 127 ['foo;"bar"', 4], 128 ['foo;b"ar"', 5], 129 ['foo;bar=b@z', 9], 130 ['foo;bar=b\\az ', 9], 131 ['foo;bar="b@z"', 10], 132 ['foo;bar="baz;"', 12], 133 ['foo;bar=b"az"', 9], 134 ['foo;bar="\\\\"', 10] 135 ].forEach((element) => { 136 assert.throws( 137 () => parse(element[0]), 138 new RegExp( 139 `^SyntaxError: Unexpected character at index ${element[1]}$` 140 ) 141 ); 142 }); 143 }); 144 145 it('throws an error if the header value ends prematurely', () => { 146 [ 147 '', 148 'foo ', 149 'foo\t', 150 'foo, ', 151 'foo;', 152 'foo;bar ', 153 'foo;bar,', 154 'foo;bar; ', 155 'foo;bar=', 156 'foo;bar="baz', 157 'foo;bar="1\\', 158 'foo;bar="baz" ' 159 ].forEach((header) => { 160 assert.throws( 161 () => parse(header), 162 /^SyntaxError: Unexpected end of input$/ 163 ); 164 }); 165 }); 166 }); 167 168 describe('format', () => { 169 it('formats a single extension', () => { 170 const extensions = format({ foo: {} }); 171 172 assert.strictEqual(extensions, 'foo'); 173 }); 174 175 it('formats params', () => { 176 const extensions = format({ foo: { bar: [true, 2], baz: 1 } }); 177 178 assert.strictEqual(extensions, 'foo; bar; bar=2; baz=1'); 179 }); 180 181 it('formats multiple extensions', () => { 182 const extensions = format({ 183 foo: [{}, { baz: true }], 184 bar: { baz: true } 185 }); 186 187 assert.strictEqual(extensions, 'foo, foo; baz, bar; baz'); 188 }); 189 }); 190 });