mirror of
				https://github.com/1disk/edp445.git
				synced 2024-08-14 22:47:02 +00:00 
			
		
		
		
	Changed alot of things.
This commit is contained in:
		
							parent
							
								
									a5a0523e5a
								
							
						
					
					
						commit
						3513d5390c
					
				
					 2016 changed files with 336930 additions and 9 deletions
				
			
		
							
								
								
									
										7
									
								
								node_modules/qs/test/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								node_modules/qs/test/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| 'use strict'; | ||||
| 
 | ||||
| require('./parse'); | ||||
| 
 | ||||
| require('./stringify'); | ||||
| 
 | ||||
| require('./utils'); | ||||
							
								
								
									
										649
									
								
								node_modules/qs/test/parse.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										649
									
								
								node_modules/qs/test/parse.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,649 @@ | |||
| 'use strict'; | ||||
| 
 | ||||
| var test = require('tape'); | ||||
| var qs = require('../'); | ||||
| var utils = require('../lib/utils'); | ||||
| var iconv = require('iconv-lite'); | ||||
| var SaferBuffer = require('safer-buffer').Buffer; | ||||
| 
 | ||||
| test('parse()', function (t) { | ||||
|     t.test('parses a simple string', function (st) { | ||||
|         st.deepEqual(qs.parse('0=foo'), { 0: 'foo' }); | ||||
|         st.deepEqual(qs.parse('foo=c++'), { foo: 'c  ' }); | ||||
|         st.deepEqual(qs.parse('a[>=]=23'), { a: { '>=': '23' } }); | ||||
|         st.deepEqual(qs.parse('a[<=>]==23'), { a: { '<=>': '=23' } }); | ||||
|         st.deepEqual(qs.parse('a[==]=23'), { a: { '==': '23' } }); | ||||
|         st.deepEqual(qs.parse('foo', { strictNullHandling: true }), { foo: null }); | ||||
|         st.deepEqual(qs.parse('foo'), { foo: '' }); | ||||
|         st.deepEqual(qs.parse('foo='), { foo: '' }); | ||||
|         st.deepEqual(qs.parse('foo=bar'), { foo: 'bar' }); | ||||
|         st.deepEqual(qs.parse(' foo = bar = baz '), { ' foo ': ' bar = baz ' }); | ||||
|         st.deepEqual(qs.parse('foo=bar=baz'), { foo: 'bar=baz' }); | ||||
|         st.deepEqual(qs.parse('foo=bar&bar=baz'), { foo: 'bar', bar: 'baz' }); | ||||
|         st.deepEqual(qs.parse('foo2=bar2&baz2='), { foo2: 'bar2', baz2: '' }); | ||||
|         st.deepEqual(qs.parse('foo=bar&baz', { strictNullHandling: true }), { foo: 'bar', baz: null }); | ||||
|         st.deepEqual(qs.parse('foo=bar&baz'), { foo: 'bar', baz: '' }); | ||||
|         st.deepEqual(qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World'), { | ||||
|             cht: 'p3', | ||||
|             chd: 't:60,40', | ||||
|             chs: '250x100', | ||||
|             chl: 'Hello|World' | ||||
|         }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows enabling dot notation', function (st) { | ||||
|         st.deepEqual(qs.parse('a.b=c'), { 'a.b': 'c' }); | ||||
|         st.deepEqual(qs.parse('a.b=c', { allowDots: true }), { a: { b: 'c' } }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.deepEqual(qs.parse('a[b]=c'), { a: { b: 'c' } }, 'parses a single nested string'); | ||||
|     t.deepEqual(qs.parse('a[b][c]=d'), { a: { b: { c: 'd' } } }, 'parses a double nested string'); | ||||
|     t.deepEqual( | ||||
|         qs.parse('a[b][c][d][e][f][g][h]=i'), | ||||
|         { a: { b: { c: { d: { e: { f: { '[g][h]': 'i' } } } } } } }, | ||||
|         'defaults to a depth of 5' | ||||
|     ); | ||||
| 
 | ||||
|     t.test('only parses one level when depth = 1', function (st) { | ||||
|         st.deepEqual(qs.parse('a[b][c]=d', { depth: 1 }), { a: { b: { '[c]': 'd' } } }); | ||||
|         st.deepEqual(qs.parse('a[b][c][d]=e', { depth: 1 }), { a: { b: { '[c][d]': 'e' } } }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.deepEqual(qs.parse('a=b&a=c'), { a: ['b', 'c'] }, 'parses a simple array'); | ||||
| 
 | ||||
|     t.test('parses an explicit array', function (st) { | ||||
|         st.deepEqual(qs.parse('a[]=b'), { a: ['b'] }); | ||||
|         st.deepEqual(qs.parse('a[]=b&a[]=c'), { a: ['b', 'c'] }); | ||||
|         st.deepEqual(qs.parse('a[]=b&a[]=c&a[]=d'), { a: ['b', 'c', 'd'] }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses a mix of simple and explicit arrays', function (st) { | ||||
|         st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] }); | ||||
|         st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] }); | ||||
|         st.deepEqual(qs.parse('a[0]=b&a=c'), { a: ['b', 'c'] }); | ||||
|         st.deepEqual(qs.parse('a=b&a[0]=c'), { a: ['b', 'c'] }); | ||||
| 
 | ||||
|         st.deepEqual(qs.parse('a[1]=b&a=c', { arrayLimit: 20 }), { a: ['b', 'c'] }); | ||||
|         st.deepEqual(qs.parse('a[]=b&a=c', { arrayLimit: 0 }), { a: ['b', 'c'] }); | ||||
|         st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] }); | ||||
| 
 | ||||
|         st.deepEqual(qs.parse('a=b&a[1]=c', { arrayLimit: 20 }), { a: ['b', 'c'] }); | ||||
|         st.deepEqual(qs.parse('a=b&a[]=c', { arrayLimit: 0 }), { a: ['b', 'c'] }); | ||||
|         st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] }); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses a nested array', function (st) { | ||||
|         st.deepEqual(qs.parse('a[b][]=c&a[b][]=d'), { a: { b: ['c', 'd'] } }); | ||||
|         st.deepEqual(qs.parse('a[>=]=25'), { a: { '>=': '25' } }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows to specify array indices', function (st) { | ||||
|         st.deepEqual(qs.parse('a[1]=c&a[0]=b&a[2]=d'), { a: ['b', 'c', 'd'] }); | ||||
|         st.deepEqual(qs.parse('a[1]=c&a[0]=b'), { a: ['b', 'c'] }); | ||||
|         st.deepEqual(qs.parse('a[1]=c', { arrayLimit: 20 }), { a: ['c'] }); | ||||
|         st.deepEqual(qs.parse('a[1]=c', { arrayLimit: 0 }), { a: { 1: 'c' } }); | ||||
|         st.deepEqual(qs.parse('a[1]=c'), { a: ['c'] }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('limits specific array indices to arrayLimit', function (st) { | ||||
|         st.deepEqual(qs.parse('a[20]=a', { arrayLimit: 20 }), { a: ['a'] }); | ||||
|         st.deepEqual(qs.parse('a[21]=a', { arrayLimit: 20 }), { a: { 21: 'a' } }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.deepEqual(qs.parse('a[12b]=c'), { a: { '12b': 'c' } }, 'supports keys that begin with a number'); | ||||
| 
 | ||||
|     t.test('supports encoded = signs', function (st) { | ||||
|         st.deepEqual(qs.parse('he%3Dllo=th%3Dere'), { 'he=llo': 'th=ere' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('is ok with url encoded strings', function (st) { | ||||
|         st.deepEqual(qs.parse('a[b%20c]=d'), { a: { 'b c': 'd' } }); | ||||
|         st.deepEqual(qs.parse('a[b]=c%20d'), { a: { b: 'c d' } }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows brackets in the value', function (st) { | ||||
|         st.deepEqual(qs.parse('pets=["tobi"]'), { pets: '["tobi"]' }); | ||||
|         st.deepEqual(qs.parse('operators=[">=", "<="]'), { operators: '[">=", "<="]' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows empty values', function (st) { | ||||
|         st.deepEqual(qs.parse(''), {}); | ||||
|         st.deepEqual(qs.parse(null), {}); | ||||
|         st.deepEqual(qs.parse(undefined), {}); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('transforms arrays to objects', function (st) { | ||||
|         st.deepEqual(qs.parse('foo[0]=bar&foo[bad]=baz'), { foo: { 0: 'bar', bad: 'baz' } }); | ||||
|         st.deepEqual(qs.parse('foo[bad]=baz&foo[0]=bar'), { foo: { bad: 'baz', 0: 'bar' } }); | ||||
|         st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar'), { foo: { bad: 'baz', 0: 'bar' } }); | ||||
|         st.deepEqual(qs.parse('foo[]=bar&foo[bad]=baz'), { foo: { 0: 'bar', bad: 'baz' } }); | ||||
|         st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo'), { foo: { bad: 'baz', 0: 'bar', 1: 'foo' } }); | ||||
|         st.deepEqual(qs.parse('foo[0][a]=a&foo[0][b]=b&foo[1][a]=aa&foo[1][b]=bb'), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] }); | ||||
| 
 | ||||
|         st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: false }), { a: { 0: 'b', t: 'u' } }); | ||||
|         st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: true }), { a: { 0: 'b', t: 'u', hasOwnProperty: 'c' } }); | ||||
|         st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: false }), { a: { 0: 'b', x: 'y' } }); | ||||
|         st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: true }), { a: { 0: 'b', hasOwnProperty: 'c', x: 'y' } }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('transforms arrays to objects (dot notation)', function (st) { | ||||
|         st.deepEqual(qs.parse('foo[0].baz=bar&fool.bad=baz', { allowDots: true }), { foo: [{ baz: 'bar' }], fool: { bad: 'baz' } }); | ||||
|         st.deepEqual(qs.parse('foo[0].baz=bar&fool.bad.boo=baz', { allowDots: true }), { foo: [{ baz: 'bar' }], fool: { bad: { boo: 'baz' } } }); | ||||
|         st.deepEqual(qs.parse('foo[0][0].baz=bar&fool.bad=baz', { allowDots: true }), { foo: [[{ baz: 'bar' }]], fool: { bad: 'baz' } }); | ||||
|         st.deepEqual(qs.parse('foo[0].baz[0]=15&foo[0].bar=2', { allowDots: true }), { foo: [{ baz: ['15'], bar: '2' }] }); | ||||
|         st.deepEqual(qs.parse('foo[0].baz[0]=15&foo[0].baz[1]=16&foo[0].bar=2', { allowDots: true }), { foo: [{ baz: ['15', '16'], bar: '2' }] }); | ||||
|         st.deepEqual(qs.parse('foo.bad=baz&foo[0]=bar', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar' } }); | ||||
|         st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar' } }); | ||||
|         st.deepEqual(qs.parse('foo[]=bar&foo.bad=baz', { allowDots: true }), { foo: { 0: 'bar', bad: 'baz' } }); | ||||
|         st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar', 1: 'foo' } }); | ||||
|         st.deepEqual(qs.parse('foo[0].a=a&foo[0].b=b&foo[1].a=aa&foo[1].b=bb', { allowDots: true }), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('correctly prunes undefined values when converting an array to an object', function (st) { | ||||
|         st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { 2: 'b', 99999999: 'c' } }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('supports malformed uri characters', function (st) { | ||||
|         st.deepEqual(qs.parse('{%:%}', { strictNullHandling: true }), { '{%:%}': null }); | ||||
|         st.deepEqual(qs.parse('{%:%}='), { '{%:%}': '' }); | ||||
|         st.deepEqual(qs.parse('foo=%:%}'), { foo: '%:%}' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('doesn\'t produce empty keys', function (st) { | ||||
|         st.deepEqual(qs.parse('_r=1&'), { _r: '1' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('cannot access Object prototype', function (st) { | ||||
|         qs.parse('constructor[prototype][bad]=bad'); | ||||
|         qs.parse('bad[constructor][prototype][bad]=bad'); | ||||
|         st.equal(typeof Object.prototype.bad, 'undefined'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses arrays of objects', function (st) { | ||||
|         st.deepEqual(qs.parse('a[][b]=c'), { a: [{ b: 'c' }] }); | ||||
|         st.deepEqual(qs.parse('a[0][b]=c'), { a: [{ b: 'c' }] }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows for empty strings in arrays', function (st) { | ||||
|         st.deepEqual(qs.parse('a[]=b&a[]=&a[]=c'), { a: ['b', '', 'c'] }); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=', { strictNullHandling: true, arrayLimit: 20 }), | ||||
|             { a: ['b', null, 'c', ''] }, | ||||
|             'with arrayLimit 20 + array indices: null then empty string works' | ||||
|         ); | ||||
|         st.deepEqual( | ||||
|             qs.parse('a[]=b&a[]&a[]=c&a[]=', { strictNullHandling: true, arrayLimit: 0 }), | ||||
|             { a: ['b', null, 'c', ''] }, | ||||
|             'with arrayLimit 0 + array brackets: null then empty string works' | ||||
|         ); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]', { strictNullHandling: true, arrayLimit: 20 }), | ||||
|             { a: ['b', '', 'c', null] }, | ||||
|             'with arrayLimit 20 + array indices: empty string then null works' | ||||
|         ); | ||||
|         st.deepEqual( | ||||
|             qs.parse('a[]=b&a[]=&a[]=c&a[]', { strictNullHandling: true, arrayLimit: 0 }), | ||||
|             { a: ['b', '', 'c', null] }, | ||||
|             'with arrayLimit 0 + array brackets: empty string then null works' | ||||
|         ); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('a[]=&a[]=b&a[]=c'), | ||||
|             { a: ['', 'b', 'c'] }, | ||||
|             'array brackets: empty strings work' | ||||
|         ); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('compacts sparse arrays', function (st) { | ||||
|         st.deepEqual(qs.parse('a[10]=1&a[2]=2', { arrayLimit: 20 }), { a: ['2', '1'] }); | ||||
|         st.deepEqual(qs.parse('a[1][b][2][c]=1', { arrayLimit: 20 }), { a: [{ b: [{ c: '1' }] }] }); | ||||
|         st.deepEqual(qs.parse('a[1][2][3][c]=1', { arrayLimit: 20 }), { a: [[[{ c: '1' }]]] }); | ||||
|         st.deepEqual(qs.parse('a[1][2][3][c][1]=1', { arrayLimit: 20 }), { a: [[[{ c: ['1'] }]]] }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses semi-parsed strings', function (st) { | ||||
|         st.deepEqual(qs.parse({ 'a[b]': 'c' }), { a: { b: 'c' } }); | ||||
|         st.deepEqual(qs.parse({ 'a[b]': 'c', 'a[d]': 'e' }), { a: { b: 'c', d: 'e' } }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses buffers correctly', function (st) { | ||||
|         var b = SaferBuffer.from('test'); | ||||
|         st.deepEqual(qs.parse({ a: b }), { a: b }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses jquery-param strings', function (st) { | ||||
|         // readable = 'filter[0][]=int1&filter[0][]==&filter[0][]=77&filter[]=and&filter[2][]=int2&filter[2][]==&filter[2][]=8'
 | ||||
|         var encoded = 'filter%5B0%5D%5B%5D=int1&filter%5B0%5D%5B%5D=%3D&filter%5B0%5D%5B%5D=77&filter%5B%5D=and&filter%5B2%5D%5B%5D=int2&filter%5B2%5D%5B%5D=%3D&filter%5B2%5D%5B%5D=8'; | ||||
|         var expected = { filter: [['int1', '=', '77'], 'and', ['int2', '=', '8']] }; | ||||
|         st.deepEqual(qs.parse(encoded), expected); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('continues parsing when no parent is found', function (st) { | ||||
|         st.deepEqual(qs.parse('[]=&a=b'), { 0: '', a: 'b' }); | ||||
|         st.deepEqual(qs.parse('[]&a=b', { strictNullHandling: true }), { 0: null, a: 'b' }); | ||||
|         st.deepEqual(qs.parse('[foo]=bar'), { foo: 'bar' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('does not error when parsing a very long array', function (st) { | ||||
|         var str = 'a[]=a'; | ||||
|         while (Buffer.byteLength(str) < 128 * 1024) { | ||||
|             str = str + '&' + str; | ||||
|         } | ||||
| 
 | ||||
|         st.doesNotThrow(function () { | ||||
|             qs.parse(str); | ||||
|         }); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('should not throw when a native prototype has an enumerable property', function (st) { | ||||
|         Object.prototype.crash = ''; | ||||
|         Array.prototype.crash = ''; | ||||
|         st.doesNotThrow(qs.parse.bind(null, 'a=b')); | ||||
|         st.deepEqual(qs.parse('a=b'), { a: 'b' }); | ||||
|         st.doesNotThrow(qs.parse.bind(null, 'a[][b]=c')); | ||||
|         st.deepEqual(qs.parse('a[][b]=c'), { a: [{ b: 'c' }] }); | ||||
|         delete Object.prototype.crash; | ||||
|         delete Array.prototype.crash; | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses a string with an alternative string delimiter', function (st) { | ||||
|         st.deepEqual(qs.parse('a=b;c=d', { delimiter: ';' }), { a: 'b', c: 'd' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses a string with an alternative RegExp delimiter', function (st) { | ||||
|         st.deepEqual(qs.parse('a=b; c=d', { delimiter: /[;,] */ }), { a: 'b', c: 'd' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('does not use non-splittable objects as delimiters', function (st) { | ||||
|         st.deepEqual(qs.parse('a=b&c=d', { delimiter: true }), { a: 'b', c: 'd' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows overriding parameter limit', function (st) { | ||||
|         st.deepEqual(qs.parse('a=b&c=d', { parameterLimit: 1 }), { a: 'b' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows setting the parameter limit to Infinity', function (st) { | ||||
|         st.deepEqual(qs.parse('a=b&c=d', { parameterLimit: Infinity }), { a: 'b', c: 'd' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows overriding array limit', function (st) { | ||||
|         st.deepEqual(qs.parse('a[0]=b', { arrayLimit: -1 }), { a: { 0: 'b' } }); | ||||
|         st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: -1 }), { a: { '-1': 'b' } }); | ||||
|         st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows disabling array parsing', function (st) { | ||||
|         var indices = qs.parse('a[0]=b&a[1]=c', { parseArrays: false }); | ||||
|         st.deepEqual(indices, { a: { 0: 'b', 1: 'c' } }); | ||||
|         st.equal(Array.isArray(indices.a), false, 'parseArrays:false, indices case is not an array'); | ||||
| 
 | ||||
|         var emptyBrackets = qs.parse('a[]=b', { parseArrays: false }); | ||||
|         st.deepEqual(emptyBrackets, { a: { 0: 'b' } }); | ||||
|         st.equal(Array.isArray(emptyBrackets.a), false, 'parseArrays:false, empty brackets case is not an array'); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('allows for query string prefix', function (st) { | ||||
|         st.deepEqual(qs.parse('?foo=bar', { ignoreQueryPrefix: true }), { foo: 'bar' }); | ||||
|         st.deepEqual(qs.parse('foo=bar', { ignoreQueryPrefix: true }), { foo: 'bar' }); | ||||
|         st.deepEqual(qs.parse('?foo=bar', { ignoreQueryPrefix: false }), { '?foo': 'bar' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses an object', function (st) { | ||||
|         var input = { | ||||
|             'user[name]': { 'pop[bob]': 3 }, | ||||
|             'user[email]': null | ||||
|         }; | ||||
| 
 | ||||
|         var expected = { | ||||
|             user: { | ||||
|                 name: { 'pop[bob]': 3 }, | ||||
|                 email: null | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         var result = qs.parse(input); | ||||
| 
 | ||||
|         st.deepEqual(result, expected); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses an object in dot notation', function (st) { | ||||
|         var input = { | ||||
|             'user.name': { 'pop[bob]': 3 }, | ||||
|             'user.email.': null | ||||
|         }; | ||||
| 
 | ||||
|         var expected = { | ||||
|             user: { | ||||
|                 name: { 'pop[bob]': 3 }, | ||||
|                 email: null | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         var result = qs.parse(input, { allowDots: true }); | ||||
| 
 | ||||
|         st.deepEqual(result, expected); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses an object and not child values', function (st) { | ||||
|         var input = { | ||||
|             'user[name]': { 'pop[bob]': { test: 3 } }, | ||||
|             'user[email]': null | ||||
|         }; | ||||
| 
 | ||||
|         var expected = { | ||||
|             user: { | ||||
|                 name: { 'pop[bob]': { test: 3 } }, | ||||
|                 email: null | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         var result = qs.parse(input); | ||||
| 
 | ||||
|         st.deepEqual(result, expected); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('does not blow up when Buffer global is missing', function (st) { | ||||
|         var tempBuffer = global.Buffer; | ||||
|         delete global.Buffer; | ||||
|         var result = qs.parse('a=b&c=d'); | ||||
|         global.Buffer = tempBuffer; | ||||
|         st.deepEqual(result, { a: 'b', c: 'd' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('does not crash when parsing circular references', function (st) { | ||||
|         var a = {}; | ||||
|         a.b = a; | ||||
| 
 | ||||
|         var parsed; | ||||
| 
 | ||||
|         st.doesNotThrow(function () { | ||||
|             parsed = qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a }); | ||||
|         }); | ||||
| 
 | ||||
|         st.equal('foo' in parsed, true, 'parsed has "foo" property'); | ||||
|         st.equal('bar' in parsed.foo, true); | ||||
|         st.equal('baz' in parsed.foo, true); | ||||
|         st.equal(parsed.foo.bar, 'baz'); | ||||
|         st.deepEqual(parsed.foo.baz, a); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('does not crash when parsing deep objects', function (st) { | ||||
|         var parsed; | ||||
|         var str = 'foo'; | ||||
| 
 | ||||
|         for (var i = 0; i < 5000; i++) { | ||||
|             str += '[p]'; | ||||
|         } | ||||
| 
 | ||||
|         str += '=bar'; | ||||
| 
 | ||||
|         st.doesNotThrow(function () { | ||||
|             parsed = qs.parse(str, { depth: 5000 }); | ||||
|         }); | ||||
| 
 | ||||
|         st.equal('foo' in parsed, true, 'parsed has "foo" property'); | ||||
| 
 | ||||
|         var depth = 0; | ||||
|         var ref = parsed.foo; | ||||
|         while ((ref = ref.p)) { | ||||
|             depth += 1; | ||||
|         } | ||||
| 
 | ||||
|         st.equal(depth, 5000, 'parsed is 5000 properties deep'); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses null objects correctly', { skip: !Object.create }, function (st) { | ||||
|         var a = Object.create(null); | ||||
|         a.b = 'c'; | ||||
| 
 | ||||
|         st.deepEqual(qs.parse(a), { b: 'c' }); | ||||
|         var result = qs.parse({ a: a }); | ||||
|         st.equal('a' in result, true, 'result has "a" property'); | ||||
|         st.deepEqual(result.a, a); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses dates correctly', function (st) { | ||||
|         var now = new Date(); | ||||
|         st.deepEqual(qs.parse({ a: now }), { a: now }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('parses regular expressions correctly', function (st) { | ||||
|         var re = /^test$/; | ||||
|         st.deepEqual(qs.parse({ a: re }), { a: re }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('does not allow overwriting prototype properties', function (st) { | ||||
|         st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: false }), {}); | ||||
|         st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: false }), {}); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('toString', { allowPrototypes: false }), | ||||
|             {}, | ||||
|             'bare "toString" results in {}' | ||||
|         ); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('can allow overwriting prototype properties', function (st) { | ||||
|         st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }), { a: { hasOwnProperty: 'b' } }); | ||||
|         st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: true }), { hasOwnProperty: 'b' }); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('toString', { allowPrototypes: true }), | ||||
|             { toString: '' }, | ||||
|             'bare "toString" results in { toString: "" }' | ||||
|         ); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('params starting with a closing bracket', function (st) { | ||||
|         st.deepEqual(qs.parse(']=toString'), { ']': 'toString' }); | ||||
|         st.deepEqual(qs.parse(']]=toString'), { ']]': 'toString' }); | ||||
|         st.deepEqual(qs.parse(']hello]=toString'), { ']hello]': 'toString' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('params starting with a starting bracket', function (st) { | ||||
|         st.deepEqual(qs.parse('[=toString'), { '[': 'toString' }); | ||||
|         st.deepEqual(qs.parse('[[=toString'), { '[[': 'toString' }); | ||||
|         st.deepEqual(qs.parse('[hello[=toString'), { '[hello[': 'toString' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('add keys to objects', function (st) { | ||||
|         st.deepEqual( | ||||
|             qs.parse('a[b]=c&a=d'), | ||||
|             { a: { b: 'c', d: true } }, | ||||
|             'can add keys to objects' | ||||
|         ); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('a[b]=c&a=toString'), | ||||
|             { a: { b: 'c' } }, | ||||
|             'can not overwrite prototype' | ||||
|         ); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('a[b]=c&a=toString', { allowPrototypes: true }), | ||||
|             { a: { b: 'c', toString: true } }, | ||||
|             'can overwrite prototype with allowPrototypes true' | ||||
|         ); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('a[b]=c&a=toString', { plainObjects: true }), | ||||
|             { __proto__: null, a: { __proto__: null, b: 'c', toString: true } }, | ||||
|             'can overwrite prototype with plainObjects true' | ||||
|         ); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('dunder proto is ignored', function (st) { | ||||
|         var payload = 'categories[__proto__]=login&categories[__proto__]&categories[length]=42'; | ||||
|         var result = qs.parse(payload, { allowPrototypes: true }); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             result, | ||||
|             { | ||||
|                 categories: { | ||||
|                     length: '42' | ||||
|                 } | ||||
|             }, | ||||
|             'silent [[Prototype]] payload' | ||||
|         ); | ||||
| 
 | ||||
|         var plainResult = qs.parse(payload, { allowPrototypes: true, plainObjects: true }); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             plainResult, | ||||
|             { | ||||
|                 __proto__: null, | ||||
|                 categories: { | ||||
|                     __proto__: null, | ||||
|                     length: '42' | ||||
|                 } | ||||
|             }, | ||||
|             'silent [[Prototype]] payload: plain objects' | ||||
|         ); | ||||
| 
 | ||||
|         var query = qs.parse('categories[__proto__]=cats&categories[__proto__]=dogs&categories[some][json]=toInject', { allowPrototypes: true }); | ||||
| 
 | ||||
|         st.notOk(Array.isArray(query.categories), 'is not an array'); | ||||
|         st.notOk(query.categories instanceof Array, 'is not instanceof an array'); | ||||
|         st.deepEqual(query.categories, { some: { json: 'toInject' } }); | ||||
|         st.equal(JSON.stringify(query.categories), '{"some":{"json":"toInject"}}', 'stringifies as a non-array'); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true }), | ||||
|             { | ||||
|                 foo: { | ||||
|                     bar: 'stuffs' | ||||
|                 } | ||||
|             }, | ||||
|             'hidden values' | ||||
|         ); | ||||
| 
 | ||||
|         st.deepEqual( | ||||
|             qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true, plainObjects: true }), | ||||
|             { | ||||
|                 __proto__: null, | ||||
|                 foo: { | ||||
|                     __proto__: null, | ||||
|                     bar: 'stuffs' | ||||
|                 } | ||||
|             }, | ||||
|             'hidden values: plain objects' | ||||
|         ); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('can return null objects', { skip: !Object.create }, function (st) { | ||||
|         var expected = Object.create(null); | ||||
|         expected.a = Object.create(null); | ||||
|         expected.a.b = 'c'; | ||||
|         expected.a.hasOwnProperty = 'd'; | ||||
|         st.deepEqual(qs.parse('a[b]=c&a[hasOwnProperty]=d', { plainObjects: true }), expected); | ||||
|         st.deepEqual(qs.parse(null, { plainObjects: true }), Object.create(null)); | ||||
|         var expectedArray = Object.create(null); | ||||
|         expectedArray.a = Object.create(null); | ||||
|         expectedArray.a[0] = 'b'; | ||||
|         expectedArray.a.c = 'd'; | ||||
|         st.deepEqual(qs.parse('a[]=b&a[c]=d', { plainObjects: true }), expectedArray); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('can parse with custom encoding', function (st) { | ||||
|         st.deepEqual(qs.parse('%8c%a7=%91%e5%8d%e3%95%7b', { | ||||
|             decoder: function (str) { | ||||
|                 var reg = /%([0-9A-F]{2})/ig; | ||||
|                 var result = []; | ||||
|                 var parts = reg.exec(str); | ||||
|                 while (parts) { | ||||
|                     result.push(parseInt(parts[1], 16)); | ||||
|                     parts = reg.exec(str); | ||||
|                 } | ||||
|                 return String(iconv.decode(SaferBuffer.from(result), 'shift_jis')); | ||||
|             } | ||||
|         }), { 県: '大阪府' }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('receives the default decoder as a second argument', function (st) { | ||||
|         st.plan(1); | ||||
|         qs.parse('a', { | ||||
|             decoder: function (str, defaultDecoder) { | ||||
|                 st.equal(defaultDecoder, utils.decode); | ||||
|             } | ||||
|         }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('throws error with wrong decoder', function (st) { | ||||
|         st['throws'](function () { | ||||
|             qs.parse({}, { decoder: 'string' }); | ||||
|         }, new TypeError('Decoder has to be a function.')); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('does not mutate the options argument', function (st) { | ||||
|         var options = {}; | ||||
|         qs.parse('a[b]=true', options); | ||||
|         st.deepEqual(options, {}); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.end(); | ||||
| }); | ||||
							
								
								
									
										642
									
								
								node_modules/qs/test/stringify.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										642
									
								
								node_modules/qs/test/stringify.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,642 @@ | |||
| 'use strict'; | ||||
| 
 | ||||
| var test = require('tape'); | ||||
| var qs = require('../'); | ||||
| var utils = require('../lib/utils'); | ||||
| var iconv = require('iconv-lite'); | ||||
| var SaferBuffer = require('safer-buffer').Buffer; | ||||
| 
 | ||||
| test('stringify()', function (t) { | ||||
|     t.test('stringifies a querystring object', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b' }), 'a=b'); | ||||
|         st.equal(qs.stringify({ a: 1 }), 'a=1'); | ||||
|         st.equal(qs.stringify({ a: 1, b: 2 }), 'a=1&b=2'); | ||||
|         st.equal(qs.stringify({ a: 'A_Z' }), 'a=A_Z'); | ||||
|         st.equal(qs.stringify({ a: '€' }), 'a=%E2%82%AC'); | ||||
|         st.equal(qs.stringify({ a: '' }), 'a=%EE%80%80'); | ||||
|         st.equal(qs.stringify({ a: 'א' }), 'a=%D7%90'); | ||||
|         st.equal(qs.stringify({ a: '𐐷' }), 'a=%F0%90%90%B7'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies falsy values', function (st) { | ||||
|         st.equal(qs.stringify(undefined), ''); | ||||
|         st.equal(qs.stringify(null), ''); | ||||
|         st.equal(qs.stringify(null, { strictNullHandling: true }), ''); | ||||
|         st.equal(qs.stringify(false), ''); | ||||
|         st.equal(qs.stringify(0), ''); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('adds query prefix', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b' }, { addQueryPrefix: true }), '?a=b'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('with query prefix, outputs blank string given an empty object', function (st) { | ||||
|         st.equal(qs.stringify({}, { addQueryPrefix: true }), ''); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies nested falsy values', function (st) { | ||||
|         st.equal(qs.stringify({ a: { b: { c: null } } }), 'a%5Bb%5D%5Bc%5D='); | ||||
|         st.equal(qs.stringify({ a: { b: { c: null } } }, { strictNullHandling: true }), 'a%5Bb%5D%5Bc%5D'); | ||||
|         st.equal(qs.stringify({ a: { b: { c: false } } }), 'a%5Bb%5D%5Bc%5D=false'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies a nested object', function (st) { | ||||
|         st.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c'); | ||||
|         st.equal(qs.stringify({ a: { b: { c: { d: 'e' } } } }), 'a%5Bb%5D%5Bc%5D%5Bd%5D=e'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies a nested object with dots notation', function (st) { | ||||
|         st.equal(qs.stringify({ a: { b: 'c' } }, { allowDots: true }), 'a.b=c'); | ||||
|         st.equal(qs.stringify({ a: { b: { c: { d: 'e' } } } }, { allowDots: true }), 'a.b.c.d=e'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies an array value', function (st) { | ||||
|         st.equal( | ||||
|             qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'indices' }), | ||||
|             'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d', | ||||
|             'indices => indices' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'brackets' }), | ||||
|             'a%5B%5D=b&a%5B%5D=c&a%5B%5D=d', | ||||
|             'brackets => brackets' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify({ a: ['b', 'c', 'd'] }), | ||||
|             'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d', | ||||
|             'default => indices' | ||||
|         ); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('omits nulls when asked', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b', c: null }, { skipNulls: true }), 'a=b'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('omits nested nulls when asked', function (st) { | ||||
|         st.equal(qs.stringify({ a: { b: 'c', d: null } }, { skipNulls: true }), 'a%5Bb%5D=c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('omits array indices when asked', function (st) { | ||||
|         st.equal(qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false }), 'a=b&a=c&a=d'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies a nested array value', function (st) { | ||||
|         st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'indices' }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d'); | ||||
|         st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'brackets' }), 'a%5Bb%5D%5B%5D=c&a%5Bb%5D%5B%5D=d'); | ||||
|         st.equal(qs.stringify({ a: { b: ['c', 'd'] } }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies a nested array value with dots notation', function (st) { | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: { b: ['c', 'd'] } }, | ||||
|                 { allowDots: true, encode: false, arrayFormat: 'indices' } | ||||
|             ), | ||||
|             'a.b[0]=c&a.b[1]=d', | ||||
|             'indices: stringifies with dots + indices' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: { b: ['c', 'd'] } }, | ||||
|                 { allowDots: true, encode: false, arrayFormat: 'brackets' } | ||||
|             ), | ||||
|             'a.b[]=c&a.b[]=d', | ||||
|             'brackets: stringifies with dots + brackets' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: { b: ['c', 'd'] } }, | ||||
|                 { allowDots: true, encode: false } | ||||
|             ), | ||||
|             'a.b[0]=c&a.b[1]=d', | ||||
|             'default: stringifies with dots + indices' | ||||
|         ); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies an object inside an array', function (st) { | ||||
|         st.equal( | ||||
|             qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices' }), | ||||
|             'a%5B0%5D%5Bb%5D=c', | ||||
|             'indices => brackets' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets' }), | ||||
|             'a%5B%5D%5Bb%5D=c', | ||||
|             'brackets => brackets' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify({ a: [{ b: 'c' }] }), | ||||
|             'a%5B0%5D%5Bb%5D=c', | ||||
|             'default => indices' | ||||
|         ); | ||||
| 
 | ||||
|         st.equal( | ||||
|             qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices' }), | ||||
|             'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1', | ||||
|             'indices => indices' | ||||
|         ); | ||||
| 
 | ||||
|         st.equal( | ||||
|             qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets' }), | ||||
|             'a%5B%5D%5Bb%5D%5Bc%5D%5B%5D=1', | ||||
|             'brackets => brackets' | ||||
|         ); | ||||
| 
 | ||||
|         st.equal( | ||||
|             qs.stringify({ a: [{ b: { c: [1] } }] }), | ||||
|             'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1', | ||||
|             'default => indices' | ||||
|         ); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies an array with mixed objects and primitives', function (st) { | ||||
|         st.equal( | ||||
|             qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'indices' }), | ||||
|             'a[0][b]=1&a[1]=2&a[2]=3', | ||||
|             'indices => indices' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'brackets' }), | ||||
|             'a[][b]=1&a[]=2&a[]=3', | ||||
|             'brackets => brackets' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false }), | ||||
|             'a[0][b]=1&a[1]=2&a[2]=3', | ||||
|             'default => indices' | ||||
|         ); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies an object inside an array with dots notation', function (st) { | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: [{ b: 'c' }] }, | ||||
|                 { allowDots: true, encode: false, arrayFormat: 'indices' } | ||||
|             ), | ||||
|             'a[0].b=c', | ||||
|             'indices => indices' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: [{ b: 'c' }] }, | ||||
|                 { allowDots: true, encode: false, arrayFormat: 'brackets' } | ||||
|             ), | ||||
|             'a[].b=c', | ||||
|             'brackets => brackets' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: [{ b: 'c' }] }, | ||||
|                 { allowDots: true, encode: false } | ||||
|             ), | ||||
|             'a[0].b=c', | ||||
|             'default => indices' | ||||
|         ); | ||||
| 
 | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: [{ b: { c: [1] } }] }, | ||||
|                 { allowDots: true, encode: false, arrayFormat: 'indices' } | ||||
|             ), | ||||
|             'a[0].b.c[0]=1', | ||||
|             'indices => indices' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: [{ b: { c: [1] } }] }, | ||||
|                 { allowDots: true, encode: false, arrayFormat: 'brackets' } | ||||
|             ), | ||||
|             'a[].b.c[]=1', | ||||
|             'brackets => brackets' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: [{ b: { c: [1] } }] }, | ||||
|                 { allowDots: true, encode: false } | ||||
|             ), | ||||
|             'a[0].b.c[0]=1', | ||||
|             'default => indices' | ||||
|         ); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('does not omit object keys when indices = false', function (st) { | ||||
|         st.equal(qs.stringify({ a: [{ b: 'c' }] }, { indices: false }), 'a%5Bb%5D=c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('uses indices notation for arrays when indices=true', function (st) { | ||||
|         st.equal(qs.stringify({ a: ['b', 'c'] }, { indices: true }), 'a%5B0%5D=b&a%5B1%5D=c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('uses indices notation for arrays when no arrayFormat is specified', function (st) { | ||||
|         st.equal(qs.stringify({ a: ['b', 'c'] }), 'a%5B0%5D=b&a%5B1%5D=c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('uses indices notation for arrays when no arrayFormat=indices', function (st) { | ||||
|         st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }), 'a%5B0%5D=b&a%5B1%5D=c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('uses repeat notation for arrays when no arrayFormat=repeat', function (st) { | ||||
|         st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }), 'a=b&a=c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('uses brackets notation for arrays when no arrayFormat=brackets', function (st) { | ||||
|         st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }), 'a%5B%5D=b&a%5B%5D=c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies a complicated object', function (st) { | ||||
|         st.equal(qs.stringify({ a: { b: 'c', d: 'e' } }), 'a%5Bb%5D=c&a%5Bd%5D=e'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies an empty value', function (st) { | ||||
|         st.equal(qs.stringify({ a: '' }), 'a='); | ||||
|         st.equal(qs.stringify({ a: null }, { strictNullHandling: true }), 'a'); | ||||
| 
 | ||||
|         st.equal(qs.stringify({ a: '', b: '' }), 'a=&b='); | ||||
|         st.equal(qs.stringify({ a: null, b: '' }, { strictNullHandling: true }), 'a&b='); | ||||
| 
 | ||||
|         st.equal(qs.stringify({ a: { b: '' } }), 'a%5Bb%5D='); | ||||
|         st.equal(qs.stringify({ a: { b: null } }, { strictNullHandling: true }), 'a%5Bb%5D'); | ||||
|         st.equal(qs.stringify({ a: { b: null } }, { strictNullHandling: false }), 'a%5Bb%5D='); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies a null object', { skip: !Object.create }, function (st) { | ||||
|         var obj = Object.create(null); | ||||
|         obj.a = 'b'; | ||||
|         st.equal(qs.stringify(obj), 'a=b'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('returns an empty string for invalid input', function (st) { | ||||
|         st.equal(qs.stringify(undefined), ''); | ||||
|         st.equal(qs.stringify(false), ''); | ||||
|         st.equal(qs.stringify(null), ''); | ||||
|         st.equal(qs.stringify(''), ''); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies an object with a null object as a child', { skip: !Object.create }, function (st) { | ||||
|         var obj = { a: Object.create(null) }; | ||||
| 
 | ||||
|         obj.a.b = 'c'; | ||||
|         st.equal(qs.stringify(obj), 'a%5Bb%5D=c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('drops keys with a value of undefined', function (st) { | ||||
|         st.equal(qs.stringify({ a: undefined }), ''); | ||||
| 
 | ||||
|         st.equal(qs.stringify({ a: { b: undefined, c: null } }, { strictNullHandling: true }), 'a%5Bc%5D'); | ||||
|         st.equal(qs.stringify({ a: { b: undefined, c: null } }, { strictNullHandling: false }), 'a%5Bc%5D='); | ||||
|         st.equal(qs.stringify({ a: { b: undefined, c: '' } }), 'a%5Bc%5D='); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('url encodes values', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies a date', function (st) { | ||||
|         var now = new Date(); | ||||
|         var str = 'a=' + encodeURIComponent(now.toISOString()); | ||||
|         st.equal(qs.stringify({ a: now }), str); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies the weird object from qs', function (st) { | ||||
|         st.equal(qs.stringify({ 'my weird field': '~q1!2"\'w$5&7/z8)?' }), 'my%20weird%20field=~q1%212%22%27w%245%267%2Fz8%29%3F'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('skips properties that are part of the object prototype', function (st) { | ||||
|         Object.prototype.crash = 'test'; | ||||
|         st.equal(qs.stringify({ a: 'b' }), 'a=b'); | ||||
|         st.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c'); | ||||
|         delete Object.prototype.crash; | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies boolean values', function (st) { | ||||
|         st.equal(qs.stringify({ a: true }), 'a=true'); | ||||
|         st.equal(qs.stringify({ a: { b: true } }), 'a%5Bb%5D=true'); | ||||
|         st.equal(qs.stringify({ b: false }), 'b=false'); | ||||
|         st.equal(qs.stringify({ b: { c: false } }), 'b%5Bc%5D=false'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies buffer values', function (st) { | ||||
|         st.equal(qs.stringify({ a: SaferBuffer.from('test') }), 'a=test'); | ||||
|         st.equal(qs.stringify({ a: { b: SaferBuffer.from('test') } }), 'a%5Bb%5D=test'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('stringifies an object using an alternative delimiter', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('doesn\'t blow up when Buffer global is missing', function (st) { | ||||
|         var tempBuffer = global.Buffer; | ||||
|         delete global.Buffer; | ||||
|         var result = qs.stringify({ a: 'b', c: 'd' }); | ||||
|         global.Buffer = tempBuffer; | ||||
|         st.equal(result, 'a=b&c=d'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('selects properties when filter=array', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b' }, { filter: ['a'] }), 'a=b'); | ||||
|         st.equal(qs.stringify({ a: 1 }, { filter: [] }), ''); | ||||
| 
 | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, | ||||
|                 { filter: ['a', 'b', 0, 2], arrayFormat: 'indices' } | ||||
|             ), | ||||
|             'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3', | ||||
|             'indices => indices' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, | ||||
|                 { filter: ['a', 'b', 0, 2], arrayFormat: 'brackets' } | ||||
|             ), | ||||
|             'a%5Bb%5D%5B%5D=1&a%5Bb%5D%5B%5D=3', | ||||
|             'brackets => brackets' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, | ||||
|                 { filter: ['a', 'b', 0, 2] } | ||||
|             ), | ||||
|             'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3', | ||||
|             'default => indices' | ||||
|         ); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('supports custom representations when filter=function', function (st) { | ||||
|         var calls = 0; | ||||
|         var obj = { a: 'b', c: 'd', e: { f: new Date(1257894000000) } }; | ||||
|         var filterFunc = function (prefix, value) { | ||||
|             calls += 1; | ||||
|             if (calls === 1) { | ||||
|                 st.equal(prefix, '', 'prefix is empty'); | ||||
|                 st.equal(value, obj); | ||||
|             } else if (prefix === 'c') { | ||||
|                 return void 0; | ||||
|             } else if (value instanceof Date) { | ||||
|                 st.equal(prefix, 'e[f]'); | ||||
|                 return value.getTime(); | ||||
|             } | ||||
|             return value; | ||||
|         }; | ||||
| 
 | ||||
|         st.equal(qs.stringify(obj, { filter: filterFunc }), 'a=b&e%5Bf%5D=1257894000000'); | ||||
|         st.equal(calls, 5); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('can disable uri encoding', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b' }, { encode: false }), 'a=b'); | ||||
|         st.equal(qs.stringify({ a: { b: 'c' } }, { encode: false }), 'a[b]=c'); | ||||
|         st.equal(qs.stringify({ a: 'b', c: null }, { strictNullHandling: true, encode: false }), 'a=b&c'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('can sort the keys', function (st) { | ||||
|         var sort = function (a, b) { | ||||
|             return a.localeCompare(b); | ||||
|         }; | ||||
|         st.equal(qs.stringify({ a: 'c', z: 'y', b: 'f' }, { sort: sort }), 'a=c&b=f&z=y'); | ||||
|         st.equal(qs.stringify({ a: 'c', z: { j: 'a', i: 'b' }, b: 'f' }, { sort: sort }), 'a=c&b=f&z%5Bi%5D=b&z%5Bj%5D=a'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('can sort the keys at depth 3 or more too', function (st) { | ||||
|         var sort = function (a, b) { | ||||
|             return a.localeCompare(b); | ||||
|         }; | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, | ||||
|                 { sort: sort, encode: false } | ||||
|             ), | ||||
|             'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, | ||||
|                 { sort: null, encode: false } | ||||
|             ), | ||||
|             'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b' | ||||
|         ); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('can stringify with custom encoding', function (st) { | ||||
|         st.equal(qs.stringify({ 県: '大阪府', '': '' }, { | ||||
|             encoder: function (str) { | ||||
|                 if (str.length === 0) { | ||||
|                     return ''; | ||||
|                 } | ||||
|                 var buf = iconv.encode(str, 'shiftjis'); | ||||
|                 var result = []; | ||||
|                 for (var i = 0; i < buf.length; ++i) { | ||||
|                     result.push(buf.readUInt8(i).toString(16)); | ||||
|                 } | ||||
|                 return '%' + result.join('%'); | ||||
|             } | ||||
|         }), '%8c%a7=%91%e5%8d%e3%95%7b&='); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('receives the default encoder as a second argument', function (st) { | ||||
|         st.plan(2); | ||||
|         qs.stringify({ a: 1 }, { | ||||
|             encoder: function (str, defaultEncoder) { | ||||
|                 st.equal(defaultEncoder, utils.encode); | ||||
|             } | ||||
|         }); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('throws error with wrong encoder', function (st) { | ||||
|         st['throws'](function () { | ||||
|             qs.stringify({}, { encoder: 'string' }); | ||||
|         }, new TypeError('Encoder has to be a function.')); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('can use custom encoder for a buffer object', { skip: typeof Buffer === 'undefined' }, function (st) { | ||||
|         st.equal(qs.stringify({ a: SaferBuffer.from([1]) }, { | ||||
|             encoder: function (buffer) { | ||||
|                 if (typeof buffer === 'string') { | ||||
|                     return buffer; | ||||
|                 } | ||||
|                 return String.fromCharCode(buffer.readUInt8(0) + 97); | ||||
|             } | ||||
|         }), 'a=b'); | ||||
| 
 | ||||
|         st.equal(qs.stringify({ a: SaferBuffer.from('a b') }, { | ||||
|             encoder: function (buffer) { | ||||
|                 return buffer; | ||||
|             } | ||||
|         }), 'a=a b'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('serializeDate option', function (st) { | ||||
|         var date = new Date(); | ||||
|         st.equal( | ||||
|             qs.stringify({ a: date }), | ||||
|             'a=' + date.toISOString().replace(/:/g, '%3A'), | ||||
|             'default is toISOString' | ||||
|         ); | ||||
| 
 | ||||
|         var mutatedDate = new Date(); | ||||
|         mutatedDate.toISOString = function () { | ||||
|             throw new SyntaxError(); | ||||
|         }; | ||||
|         st['throws'](function () { | ||||
|             mutatedDate.toISOString(); | ||||
|         }, SyntaxError); | ||||
|         st.equal( | ||||
|             qs.stringify({ a: mutatedDate }), | ||||
|             'a=' + Date.prototype.toISOString.call(mutatedDate).replace(/:/g, '%3A'), | ||||
|             'toISOString works even when method is not locally present' | ||||
|         ); | ||||
| 
 | ||||
|         var specificDate = new Date(6); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: specificDate }, | ||||
|                 { serializeDate: function (d) { return d.getTime() * 7; } } | ||||
|             ), | ||||
|             'a=42', | ||||
|             'custom serializeDate function called' | ||||
|         ); | ||||
| 
 | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('RFC 1738 spaces serialization', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC1738 }), 'a=b+c'); | ||||
|         st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC1738 }), 'a+b=c+d'); | ||||
|         st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC1738 }), 'a+b=a+b'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('RFC 3986 spaces serialization', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC3986 }), 'a=b%20c'); | ||||
|         st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC3986 }), 'a%20b=c%20d'); | ||||
|         st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC3986 }), 'a%20b=a%20b'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('Backward compatibility to RFC 3986', function (st) { | ||||
|         st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c'); | ||||
|         st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }), 'a%20b=a%20b'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('Edge cases and unknown formats', function (st) { | ||||
|         ['UFO1234', false, 1234, null, {}, []].forEach( | ||||
|             function (format) { | ||||
|                 st['throws']( | ||||
|                     function () { | ||||
|                         qs.stringify({ a: 'b c' }, { format: format }); | ||||
|                     }, | ||||
|                     new TypeError('Unknown format option provided.') | ||||
|                 ); | ||||
|             } | ||||
|         ); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('encodeValuesOnly', function (st) { | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, | ||||
|                 { encodeValuesOnly: true } | ||||
|             ), | ||||
|             'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h' | ||||
|         ); | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: 'b', c: ['d', 'e'], f: [['g'], ['h']] } | ||||
|             ), | ||||
|             'a=b&c%5B0%5D=d&c%5B1%5D=e&f%5B0%5D%5B0%5D=g&f%5B1%5D%5B0%5D=h' | ||||
|         ); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('encodeValuesOnly - strictNullHandling', function (st) { | ||||
|         st.equal( | ||||
|             qs.stringify( | ||||
|                 { a: { b: null } }, | ||||
|                 { encodeValuesOnly: true, strictNullHandling: true } | ||||
|             ), | ||||
|             'a[b]' | ||||
|         ); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('does not mutate the options argument', function (st) { | ||||
|         var options = {}; | ||||
|         qs.stringify({}, options); | ||||
|         st.deepEqual(options, {}); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('strictNullHandling works with custom filter', function (st) { | ||||
|         var filter = function (prefix, value) { | ||||
|             return value; | ||||
|         }; | ||||
| 
 | ||||
|         var options = { strictNullHandling: true, filter: filter }; | ||||
|         st.equal(qs.stringify({ key: null }, options), 'key'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.test('strictNullHandling works with null serializeDate', function (st) { | ||||
|         var serializeDate = function () { | ||||
|             return null; | ||||
|         }; | ||||
|         var options = { strictNullHandling: true, serializeDate: serializeDate }; | ||||
|         var date = new Date(); | ||||
|         st.equal(qs.stringify({ key: date }, options), 'key'); | ||||
|         st.end(); | ||||
|     }); | ||||
| 
 | ||||
|     t.end(); | ||||
| }); | ||||
							
								
								
									
										65
									
								
								node_modules/qs/test/utils.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								node_modules/qs/test/utils.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | |||
| 'use strict'; | ||||
| 
 | ||||
| var test = require('tape'); | ||||
| var utils = require('../lib/utils'); | ||||
| 
 | ||||
| test('merge()', function (t) { | ||||
|     t.deepEqual(utils.merge(null, true), [null, true], 'merges true into null'); | ||||
| 
 | ||||
|     t.deepEqual(utils.merge(null, [42]), [null, 42], 'merges null into an array'); | ||||
| 
 | ||||
|     t.deepEqual(utils.merge({ a: 'b' }, { a: 'c' }), { a: ['b', 'c'] }, 'merges two objects with the same key'); | ||||
| 
 | ||||
|     var oneMerged = utils.merge({ foo: 'bar' }, { foo: { first: '123' } }); | ||||
|     t.deepEqual(oneMerged, { foo: ['bar', { first: '123' }] }, 'merges a standalone and an object into an array'); | ||||
| 
 | ||||
|     var twoMerged = utils.merge({ foo: ['bar', { first: '123' }] }, { foo: { second: '456' } }); | ||||
|     t.deepEqual(twoMerged, { foo: { 0: 'bar', 1: { first: '123' }, second: '456' } }, 'merges a standalone and two objects into an array'); | ||||
| 
 | ||||
|     var sandwiched = utils.merge({ foo: ['bar', { first: '123', second: '456' }] }, { foo: 'baz' }); | ||||
|     t.deepEqual(sandwiched, { foo: ['bar', { first: '123', second: '456' }, 'baz'] }, 'merges an object sandwiched by two standalones into an array'); | ||||
| 
 | ||||
|     var nestedArrays = utils.merge({ foo: ['baz'] }, { foo: ['bar', 'xyzzy'] }); | ||||
|     t.deepEqual(nestedArrays, { foo: ['baz', 'bar', 'xyzzy'] }); | ||||
| 
 | ||||
|     var noOptionsNonObjectSource = utils.merge({ foo: 'baz' }, 'bar'); | ||||
|     t.deepEqual(noOptionsNonObjectSource, { foo: 'baz', bar: true }); | ||||
| 
 | ||||
|     t.test( | ||||
|         'avoids invoking array setters unnecessarily', | ||||
|         { skip: typeof Object.defineProperty !== 'function' }, | ||||
|         function (st) { | ||||
|             var setCount = 0; | ||||
|             var getCount = 0; | ||||
|             var observed = []; | ||||
|             Object.defineProperty(observed, 0, { | ||||
|                 get: function () { | ||||
|                     getCount += 1; | ||||
|                     return { bar: 'baz' }; | ||||
|                 }, | ||||
|                 set: function () { setCount += 1; } | ||||
|             }); | ||||
|             utils.merge(observed, [null]); | ||||
|             st.equal(setCount, 0); | ||||
|             st.equal(getCount, 1); | ||||
|             observed[0] = observed[0]; // eslint-disable-line no-self-assign
 | ||||
|             st.equal(setCount, 1); | ||||
|             st.equal(getCount, 2); | ||||
|             st.end(); | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     t.end(); | ||||
| }); | ||||
| 
 | ||||
| test('assign()', function (t) { | ||||
|     var target = { a: 1, b: 2 }; | ||||
|     var source = { b: 3, c: 4 }; | ||||
|     var result = utils.assign(target, source); | ||||
| 
 | ||||
|     t.equal(result, target, 'returns the target'); | ||||
|     t.deepEqual(target, { a: 1, b: 3, c: 4 }, 'target and source are merged'); | ||||
|     t.deepEqual(source, { b: 3, c: 4 }, 'source is untouched'); | ||||
| 
 | ||||
|     t.end(); | ||||
| }); | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue