es7-rest-property-helpers-test.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /**
  2. * Copyright 2013-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. * @emails sema@fb.com
  10. */
  11. /*jshint evil:true*/
  12. require('mock-modules').autoMockOff();
  13. describe('es7-rest-property-visitors', function() {
  14. var transformFn;
  15. var visitors;
  16. beforeEach(function() {
  17. require('mock-modules').dumpCache();
  18. transformFn = require('../../src/jstransform').transform;
  19. visitors = require('../es6-destructuring-visitors').visitorList;
  20. });
  21. function transform(code) {
  22. var lines = Array.prototype.join.call(arguments, '\n');
  23. return transformFn(visitors, lines).code;
  24. }
  25. // Semantic tests.
  26. it('picks off remaining properties from an object', function() {
  27. var code = transform(
  28. '({ x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 });',
  29. '([ x, y, z ]);'
  30. );
  31. expect(eval(code)).toEqual([1, 2, { a: 3, b: 4 }]);
  32. });
  33. it('picks off remaining properties from a nested object', function() {
  34. var code = transform(
  35. 'var complex = {',
  36. ' x: { a: 1, b: 2, c: 3 },',
  37. ' y: [4, 5, 6]',
  38. '};',
  39. 'var {',
  40. ' x: { a: xa, ...xbc },',
  41. ' y: [y0, ...y12]',
  42. '} = complex;',
  43. '([ xa, xbc, y0, y12 ]);'
  44. );
  45. expect(eval(code)).toEqual([ 1, { b: 2, c: 3 }, 4, [5, 6] ]);
  46. });
  47. it('only extracts own properties', function() {
  48. var code = transform(
  49. 'var obj = Object.create({ x: 1 });',
  50. 'obj.y = 2;',
  51. '({ ...y } = obj);',
  52. '(y);'
  53. );
  54. expect(eval(code)).toEqual({ y: 2 });
  55. });
  56. it('only extracts own properties, except when they are explicit', function() {
  57. var code = transform(
  58. 'var obj = Object.create({ x: 1, y: 2 });',
  59. 'obj.z = 3;',
  60. '({ y, ...z } = obj);',
  61. '([ y, z ]);'
  62. );
  63. expect(eval(code)).toEqual([ 2, { z: 3 } ]);
  64. });
  65. it('avoids passing extra properties when they are picked off', function() {
  66. var code = transform(
  67. 'function base({ a, b, x }) { return [ a, b, x ]; }',
  68. 'function wrapper({ x, y, ...restConfig }) {',
  69. ' return base(restConfig);',
  70. '}',
  71. 'wrapper({ x: 1, y: 2, a: 3, b: 4 });'
  72. );
  73. expect(eval(code)).toEqual([ 3, 4, undefined ]);
  74. });
  75. // Syntax tests.
  76. it('throws on leading rest properties', function () {
  77. expect(() => transform('({ ...x, y, z } = obj)')).toThrow();
  78. });
  79. it('throws on multiple rest properties', function () {
  80. expect(() => transform('({ x, ...y, ...z } = obj)')).toThrow();
  81. });
  82. // TODO: Ideally identifier reuse should fail to transform
  83. // it('throws on identifier reuse', function () {
  84. // expect(() => transform('({ x: { ...z }, y: { ...z } } = obj)')).toThrow();
  85. // });
  86. });