1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5function getStrictF() {
6  'use strict';
7  return function f(x) {};
8}
9
10
11function getSloppyF() {
12  return function f(x) {};
13}
14
15
16function getStrictGenerator() {
17  'use strict';
18  return function* f(x) {};
19}
20
21
22function getSloppyGenerator() {
23  return function* f(x) {};
24}
25
26
27function test(testFunction) {
28  testFunction(getStrictF());
29  testFunction(getSloppyF());
30  testFunction(getStrictGenerator());
31  testFunction(getSloppyGenerator());
32}
33
34
35function testDescriptor(f) {
36  var descr = Object.getOwnPropertyDescriptor(f, 'length');
37  assertTrue(descr.configurable);
38  assertFalse(descr.enumerable);
39  assertEquals(1, descr.value);
40  assertFalse(descr.writable);
41}
42test(testDescriptor);
43
44
45function testSet(f) {
46  f.length = 2;
47  assertEquals(1, f.length);
48}
49test(testSet);
50
51
52function testSetStrict(f) {
53  'use strict';
54  assertThrows(function() {
55    f.length = 2;
56  }, TypeError);
57}
58test(testSetStrict);
59
60
61function testReconfigureAsDataProperty(f) {
62  Object.defineProperty(f, 'length', {
63    value: 2,
64  });
65  assertEquals(2, f.length);
66  Object.defineProperty(f, 'length', {
67    writable: true
68  });
69  f.length = 3;
70  assertEquals(3, f.length);
71
72  f.length = 42;
73  assertEquals(42, f.length);
74}
75test(testReconfigureAsDataProperty);
76
77
78function testReconfigureAsAccessorProperty(f) {
79  var length = 2;
80  Object.defineProperty(f, 'length', {
81    get: function() { return length; },
82    set: function(v) { length = v; }
83  });
84  assertEquals(2, f.length);
85  f.length = 3;
86  assertEquals(3, f.length);
87}
88test(testReconfigureAsAccessorProperty);
89
90
91(function testSetOnInstance() {
92  // This needs to come before testDelete below
93  assertTrue(Function.prototype.hasOwnProperty('length'));
94
95  function f() {}
96  delete f.length;
97  assertEquals(0, f.length);
98
99  f.length = 42;
100  assertEquals(0, f.length);  // non writable prototype property.
101  assertFalse(f.hasOwnProperty('length'));
102
103  Object.defineProperty(Function.prototype, 'length', {writable: true});
104
105  f.length = 123;
106  assertTrue(f.hasOwnProperty('length'));
107  assertEquals(123, f.length);
108})();
109
110
111(function testDelete() {
112  function f(x) {}
113  assertTrue(delete f.length);
114  assertFalse(f.hasOwnProperty('length'));
115  assertEquals(0, f.length);
116
117  assertTrue(delete Function.prototype.length);
118  assertEquals(undefined, f.length);
119})();
120