function-length-configurable.js 2.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

function getStrictF() {
  'use strict';
  return function f(x) {};
}


function getSloppyF() {
  return function f(x) {};
}


function getStrictGenerator() {
  'use strict';
  return function* f(x) {};
}


function getSloppyGenerator() {
  return function* f(x) {};
}


function test(testFunction) {
  testFunction(getStrictF());
  testFunction(getSloppyF());
  testFunction(getStrictGenerator());
  testFunction(getSloppyGenerator());
}


function testDescriptor(f) {
  var descr = Object.getOwnPropertyDescriptor(f, 'length');
  assertTrue(descr.configurable);
  assertFalse(descr.enumerable);
  assertEquals(1, descr.value);
  assertFalse(descr.writable);
}
test(testDescriptor);


function testSet(f) {
  f.length = 2;
  assertEquals(1, f.length);
}
test(testSet);


function testSetStrict(f) {
  'use strict';
  assertThrows(function() {
    f.length = 2;
  }, TypeError);
}
test(testSetStrict);


function testReconfigureAsDataProperty(f) {
  Object.defineProperty(f, 'length', {
    value: 2,
  });
  assertEquals(2, f.length);
  Object.defineProperty(f, 'length', {
    writable: true
  });
  f.length = 3;
  assertEquals(3, f.length);

  f.length = 42;
  assertEquals(42, f.length);
}
test(testReconfigureAsDataProperty);


function testReconfigureAsAccessorProperty(f) {
  var length = 2;
  Object.defineProperty(f, 'length', {
    get: function() { return length; },
    set: function(v) { length = v; }
  });
  assertEquals(2, f.length);
  f.length = 3;
  assertEquals(3, f.length);
}
test(testReconfigureAsAccessorProperty);


(function testSetOnInstance() {
  // This needs to come before testDelete below
  assertTrue(Function.prototype.hasOwnProperty('length'));

  function f() {}
  delete f.length;
  assertEquals(0, f.length);

  f.length = 42;
  assertEquals(0, f.length);  // non writable prototype property.
  assertFalse(f.hasOwnProperty('length'));

  Object.defineProperty(Function.prototype, 'length', {writable: true});

  f.length = 123;
  assertTrue(f.hasOwnProperty('length'));
  assertEquals(123, f.length);
})();


(function testDelete() {
  function f(x) {}
  assertTrue(delete f.length);
  assertFalse(f.hasOwnProperty('length'));
  assertEquals(0, f.length);

  assertTrue(delete Function.prototype.length);
  assertEquals(undefined, f.length);
})();