index.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. 'use strict';
  2. var test = require('tape');
  3. var mockProperty = require('mock-property');
  4. var hasSymbols = require('has-symbols/shams')();
  5. var isConcatSpreadable = hasSymbols && Symbol.isConcatSpreadable;
  6. var species = hasSymbols && Symbol.species;
  7. var boundFnsHaveConfigurableLengths = require('set-function-length/env').boundFnsHaveConfigurableLengths;
  8. var safeConcat = require('../');
  9. test('safe-array-concat', function (t) {
  10. t.equal(typeof safeConcat, 'function', 'is a function');
  11. t.equal(
  12. safeConcat.length,
  13. boundFnsHaveConfigurableLengths ? 1 : 0,
  14. 'has a length of ' + (boundFnsHaveConfigurableLengths ? 1 : '0 (function lengths are not configurable)')
  15. );
  16. t.deepEqual(
  17. safeConcat([1, 2], [3, 4], 'foo', 5, 6, [[7]]),
  18. [1, 2, 3, 4, 'foo', 5, 6, [7]],
  19. 'works with flat and nested arrays'
  20. );
  21. t.deepEqual(
  22. safeConcat(undefined, 1, 2),
  23. [undefined, 1, 2],
  24. 'first item as undefined is not the concat receiver, which would throw via ToObject'
  25. );
  26. t.deepEqual(
  27. safeConcat(null, 1, 2),
  28. [null, 1, 2],
  29. 'first item as null is not the concat receiver, which would throw via ToObject'
  30. );
  31. var arr = [1, 2];
  32. arr.constructor = function C() {
  33. return { args: arguments };
  34. };
  35. t.deepEqual(
  36. safeConcat(arr, 3, 4),
  37. [1, 2, 3, 4],
  38. 'first item as an array with a nonArray .constructor; ignores constructor'
  39. );
  40. t.test('has Symbol.species', { skip: !species }, function (st) {
  41. var speciesArr = [1, 2];
  42. // @ts-expect-error ts(2740) TS's `constructor` type requires a function
  43. speciesArr.constructor = {};
  44. // @ts-expect-error ts(2538) TS can't type narrow from tape's `skip`
  45. speciesArr.constructor[species] = function Species() {
  46. return { args: arguments };
  47. };
  48. st.deepEqual(
  49. safeConcat(speciesArr, 3, 4),
  50. [1, 2, 3, 4],
  51. 'first item as an array with a .constructor object with a Symbol.species; ignores constructor and species'
  52. );
  53. st.end();
  54. });
  55. t.test('has isConcatSpreadable', { skip: !isConcatSpreadable }, function (st) {
  56. // TS can't type narrow from tape's `skip`
  57. if (isConcatSpreadable) {
  58. st.teardown(mockProperty(String.prototype, isConcatSpreadable, { value: true }));
  59. var nonSpreadable = [1, 2];
  60. // @ts-expect-error ts(7015) TS can't handle expandos on an array
  61. nonSpreadable[isConcatSpreadable] = false;
  62. st.deepEqual(
  63. safeConcat(nonSpreadable, 3, 4, 'foo', Object('bar')),
  64. [1, 2, 3, 4, 'foo', Object('bar')],
  65. 'a non-concat-spreadable array is spreaded, and a concat-spreadable String is not spreaded'
  66. );
  67. st.teardown(mockProperty(Array.prototype, isConcatSpreadable, { value: false }));
  68. st.deepEqual(
  69. safeConcat([1, 2], 3, 4, 'foo', Object('bar')),
  70. [1, 2, 3, 4, 'foo', Object('bar')],
  71. 'all arrays marked non-concat-spreadable are still spreaded, and a concat-spreadable String is not spreaded'
  72. );
  73. }
  74. st.end();
  75. });
  76. t.end();
  77. });