qs 6.15.1 → 6.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/test/utils.js CHANGED
@@ -65,6 +65,7 @@ test('merge()', function (t) {
65
65
  observed[0] = observed[0]; // eslint-disable-line no-self-assign
66
66
  st.equal(setCount, 1);
67
67
  st.equal(getCount, 2);
68
+
68
69
  st.end();
69
70
  }
70
71
  );
@@ -78,6 +79,7 @@ test('merge()', function (t) {
78
79
  s2t.ok(utils.isOverflow(overflow), 'overflow object is marked');
79
80
  var merged = utils.merge(overflow, 'd');
80
81
  s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'adds primitive at next numeric index');
82
+
81
83
  s2t.end();
82
84
  });
83
85
 
@@ -93,6 +95,7 @@ test('merge()', function (t) {
93
95
  var obj = { foo: 'bar' };
94
96
  var merged = utils.merge(obj, 'baz');
95
97
  s2t.deepEqual(merged, { foo: 'bar', baz: true }, 'adds primitive as key with value true');
98
+
96
99
  s2t.end();
97
100
  });
98
101
 
@@ -110,6 +113,7 @@ test('merge()', function (t) {
110
113
  var merged = utils.merge('c', overflow);
111
114
  s2t.ok(utils.isOverflow(merged), 'result is also marked as overflow');
112
115
  s2t.deepEqual(merged, { 0: 'c', 1: 'a', 2: 'b' }, 'creates object with primitive at 0, source values shifted');
116
+
113
117
  s2t.end();
114
118
  });
115
119
 
@@ -119,6 +123,7 @@ test('merge()', function (t) {
119
123
  var merged = utils.merge('c', overflow, { plainObjects: true });
120
124
  s2t.ok(utils.isOverflow(merged), 'result is also marked as overflow');
121
125
  s2t.deepEqual(merged, { __proto__: null, 0: 'c', 1: 'a', 2: 'b' }, 'creates null-proto object with primitive at 0');
126
+
122
127
  s2t.end();
123
128
  });
124
129
 
@@ -128,6 +133,7 @@ test('merge()', function (t) {
128
133
  s2t.ok(utils.isOverflow(overflow), 'overflow object is marked');
129
134
  var merged = utils.merge('a', overflow);
130
135
  s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'shifts all source indices by 1');
136
+
131
137
  s2t.end();
132
138
  });
133
139
 
@@ -135,6 +141,7 @@ test('merge()', function (t) {
135
141
  var obj = { foo: 'bar' };
136
142
  var merged = utils.merge('a', obj);
137
143
  s2t.deepEqual(merged, ['a', { foo: 'bar' }], 'creates array with primitive and object');
144
+
138
145
  s2t.end();
139
146
  });
140
147
 
@@ -143,6 +150,7 @@ test('merge()', function (t) {
143
150
  var merged = utils.merge(arr, 'd', { arrayLimit: 1 });
144
151
  s2t.ok(utils.isOverflow(merged), 'result is marked as overflow');
145
152
  s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'converts to overflow object with primitive appended');
153
+
146
154
  s2t.end();
147
155
  });
148
156
 
@@ -150,6 +158,78 @@ test('merge()', function (t) {
150
158
  var merged = utils.merge('a', ['b', 'c'], { arrayLimit: 1 });
151
159
  s2t.ok(utils.isOverflow(merged), 'result is marked as overflow');
152
160
  s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c' }, 'converts to overflow object');
161
+
162
+ s2t.end();
163
+ });
164
+
165
+ st.test('merges primitive into array at the arrayLimit boundary, consistently with combine', function (s2t) {
166
+ var merged = utils.merge(['a'], 'b', { arrayLimit: 1 });
167
+ s2t.ok(utils.isOverflow(merged), 'result is marked as overflow at the boundary');
168
+ s2t.deepEqual(merged, { 0: 'a', 1: 'b' }, 'converts to overflow object instead of a length-2 array');
169
+
170
+ s2t.end();
171
+ });
172
+
173
+ st.test('merges two arrays that exceed arrayLimit into an overflow object', function (s2t) {
174
+ var merged = utils.merge(['a'], ['b'], { arrayLimit: 1 });
175
+ s2t.ok(utils.isOverflow(merged), 'result is marked as overflow');
176
+ s2t.deepEqual(merged, { 0: 'a', 1: 'b' }, 'array-into-array merge enforces arrayLimit like combine');
177
+
178
+ s2t.end();
179
+ });
180
+
181
+ st.test('throws at the arrayLimit boundary when merging a primitive into an array with throwOnLimitExceeded', function (s2t) {
182
+ s2t['throws'](
183
+ function () { utils.merge(['a'], 'b', { arrayLimit: 1, throwOnLimitExceeded: true }); },
184
+ new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
185
+ 'throws when the resulting length would exceed arrayLimit'
186
+ );
187
+
188
+ s2t.end();
189
+ });
190
+
191
+ st.test('throws when merging two arrays past arrayLimit with throwOnLimitExceeded', function (s2t) {
192
+ s2t['throws'](
193
+ function () { utils.merge(['a'], ['b'], { arrayLimit: 1, throwOnLimitExceeded: true }); },
194
+ new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
195
+ 'array-into-array merge throws rather than silently exceeding arrayLimit'
196
+ );
197
+ s2t['throws'](
198
+ function () { utils.merge(['a', 'b', 'c'], ['d', 'e', 'f'], { arrayLimit: 2, throwOnLimitExceeded: true }); },
199
+ new RangeError('Array limit exceeded. Only 2 elements allowed in an array.'),
200
+ 'uses the plural message when arrayLimit is not 1'
201
+ );
202
+
203
+ s2t.end();
204
+ });
205
+
206
+ st.test('throws instead of merging primitive into over-limit array when throwOnLimitExceeded is set', function (s2t) {
207
+ s2t['throws'](
208
+ function () { utils.merge(['a', 'b', 'c'], 'd', { arrayLimit: 1, throwOnLimitExceeded: true }); },
209
+ new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
210
+ 'throws rather than converting to an overflow object'
211
+ );
212
+ s2t['throws'](
213
+ function () { utils.merge(['a', 'b', 'c'], 'd', { arrayLimit: 2, throwOnLimitExceeded: true }); },
214
+ new RangeError('Array limit exceeded. Only 2 elements allowed in an array.'),
215
+ 'uses the plural message when arrayLimit is not 1'
216
+ );
217
+
218
+ s2t.end();
219
+ });
220
+
221
+ st.test('throws instead of merging array into primitive when throwOnLimitExceeded is set', function (s2t) {
222
+ s2t['throws'](
223
+ function () { utils.merge('a', ['b', 'c'], { arrayLimit: 1, throwOnLimitExceeded: true }); },
224
+ new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
225
+ 'throws rather than converting to an overflow object'
226
+ );
227
+ s2t['throws'](
228
+ function () { utils.merge('a', ['b', 'c', 'd'], { arrayLimit: 2, throwOnLimitExceeded: true }); },
229
+ new RangeError('Array limit exceeded. Only 2 elements allowed in an array.'),
230
+ 'uses the plural message when arrayLimit is not 1'
231
+ );
232
+
153
233
  s2t.end();
154
234
  });
155
235
 
@@ -274,6 +354,47 @@ test('combine()', function (t) {
274
354
  st.end();
275
355
  });
276
356
 
357
+ t.test('with throwOnLimitExceeded', function (st) {
358
+ st.test('throws when concatenation exceeds the limit', function (s2t) {
359
+ s2t['throws'](
360
+ function () { utils.combine(['a', 'b', 'c'], 'd', 3, false, true); },
361
+ new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
362
+ 'throws instead of converting to an overflow object'
363
+ );
364
+ s2t['throws'](
365
+ function () { utils.combine([], 'a', 0, false, true); },
366
+ new RangeError('Array limit exceeded. Only 0 elements allowed in an array.'),
367
+ 'throws with the correct count at arrayLimit 0'
368
+ );
369
+ s2t.end();
370
+ });
371
+
372
+ st.test('throws when adding to an existing overflow object', function (s2t) {
373
+ var overflow = utils.combine(['a', 'b'], 'c', 0, false);
374
+ s2t.ok(utils.isOverflow(overflow), 'initial object is marked as overflow');
375
+
376
+ s2t['throws'](
377
+ function () { utils.combine(overflow, 'd', 0, false, true); },
378
+ new RangeError('Array limit exceeded. Only 0 elements allowed in an array.'),
379
+ 'throws rather than appending to the overflow object'
380
+ );
381
+ s2t['throws'](
382
+ function () { utils.combine(overflow, 'd', 1, false, true); },
383
+ new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
384
+ 'uses the singular message at arrayLimit 1'
385
+ );
386
+ s2t.end();
387
+ });
388
+
389
+ st.test('does not throw when within the limit', function (s2t) {
390
+ var combined = utils.combine(['a'], 'b', 5, false, true);
391
+ s2t.deepEqual(combined, ['a', 'b'], 'returns the array unchanged when under the limit');
392
+ s2t.end();
393
+ });
394
+
395
+ st.end();
396
+ });
397
+
277
398
  t.test('with existing overflow object', function (st) {
278
399
  st.test('adds to existing overflow object at next index', function (s2t) {
279
400
  // Create overflow object first via combine: 3 elements (indices 0-2) with limit 0
@@ -372,6 +493,79 @@ test('encode', function (t) {
372
493
  'encodes a long string'
373
494
  );
374
495
 
496
+ var boundary = '';
497
+ var expected = '';
498
+ for (var j = 0; j < 1023; j++) {
499
+ boundary += 'a';
500
+ expected += 'a';
501
+ }
502
+ boundary += '😀';
503
+ expected += '%F0%9F%98%80';
504
+
505
+ t.equal(
506
+ utils.encode(boundary),
507
+ expected,
508
+ 'encodes a surrogate pair split across long-string chunks'
509
+ );
510
+
511
+ var laterBoundary = '';
512
+ var laterExpected = '';
513
+ for (var k = 0; k < 2047; k++) {
514
+ laterBoundary += 'a';
515
+ laterExpected += 'a';
516
+ }
517
+ laterBoundary += '😀';
518
+ laterExpected += '%F0%9F%98%80';
519
+
520
+ t.equal(
521
+ utils.encode(laterBoundary),
522
+ laterExpected,
523
+ 'encodes a surrogate pair split across a later chunk boundary'
524
+ );
525
+
526
+ var twoPairs = '';
527
+ for (k = 0; k < 1023; k++) {
528
+ twoPairs += 'a';
529
+ }
530
+ twoPairs += '😀';
531
+ for (k = 0; k < 1022; k++) {
532
+ twoPairs += 'b';
533
+ }
534
+ twoPairs += '😀';
535
+
536
+ t.equal(
537
+ (utils.encode(twoPairs).match(/%F0%9F%98%80/g) || []).length,
538
+ 2,
539
+ 'encodes two surrogate pairs each split across a chunk boundary'
540
+ );
541
+
542
+ var roundTrip = '';
543
+ for (k = 0; k < 1023; k++) {
544
+ roundTrip += 'a';
545
+ }
546
+ roundTrip += '😀';
547
+
548
+ t.equal(
549
+ decodeURIComponent(utils.encode(roundTrip)),
550
+ roundTrip,
551
+ 'a boundary-split surrogate pair round-trips through decodeURIComponent'
552
+ );
553
+
554
+ var loneBoundary = '';
555
+ var loneExpected = '';
556
+ for (k = 0; k < 1023; k++) {
557
+ loneBoundary += 'a';
558
+ loneExpected += 'a';
559
+ }
560
+ loneBoundary += '\uD83DX';
561
+ loneExpected += '%F0%9F%91%98';
562
+
563
+ t.equal(
564
+ utils.encode(loneBoundary),
565
+ loneExpected,
566
+ 'a lone high surrogate at a chunk boundary encodes the same as mid-chunk'
567
+ );
568
+
375
569
  t.equal(
376
570
  utils.encode('\x28\x29'),
377
571
  '%28%29',