Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / tests / ecma_5 / misc / function-definition-eval.js
1 /*
2  * Any copyright is dedicated to the Public Domain.
3  * http://creativecommons.org/licenses/publicdomain/
4  */
5
6 //-----------------------------------------------------------------------------
7 var BUGNUMBER = 577325;
8 var summary = 'Implement the ES5 algorithm for processing function statements';
9
10 print(BUGNUMBER + ": " + summary);
11
12 /**************
13  * BEGIN TEST *
14  **************/
15
16 var outer, desc;
17
18 ///////////////////////////////////////////////////
19 // Function definitions over accessor properties //
20 ///////////////////////////////////////////////////
21
22 var getCalled, setCalled;
23
24 // configurable properties get blown away
25
26 getCalled = false, setCalled = false;
27 Object.defineProperty(this, "acc1",
28                       {
29                         get: function() { getCalled = true; throw "FAIL get 1"; },
30                         set: function(v) { setCalled = true; throw "FAIL set 1 " + v; },
31                         configurable: true,
32                         enumerable: false
33                       });
34
35 // does not throw
36 outer = undefined;
37 eval("function acc1() { throw 'FAIL redefined 1'; } outer = acc1;");
38 assertEq(getCalled, false);
39 assertEq(setCalled, false);
40 assertEq(typeof acc1, "function");
41 assertEq(acc1, outer);
42 desc = Object.getOwnPropertyDescriptor(this, "acc1");
43 assertEq(desc.value, acc1);
44 assertEq(desc.writable, true);
45 assertEq(desc.enumerable, true);
46 assertEq(desc.configurable, true);
47
48
49 getCalled = false, setCalled = false;
50 Object.defineProperty(this, "acc2",
51                       {
52                         get: function() { getCalled = true; throw "FAIL get 2"; },
53                         set: function(v) { setCalled = true; throw "FAIL set 2 " + v; },
54                         configurable: true,
55                         enumerable: true
56                       });
57
58 // does not throw
59 outer = undefined;
60 eval("function acc2() { throw 'FAIL redefined 2'; } outer = acc2;");
61 assertEq(getCalled, false);
62 assertEq(setCalled, false);
63 assertEq(typeof acc2, "function");
64 assertEq(acc2, outer);
65 desc = Object.getOwnPropertyDescriptor(this, "acc2");
66 assertEq(desc.value, acc2);
67 assertEq(desc.writable, true);
68 assertEq(desc.enumerable, true);
69 assertEq(desc.configurable, true);
70
71
72 // non-configurable properties produce a TypeError
73
74 getCalled = false, setCalled = false;
75 Object.defineProperty(this, "acc3",
76                       {
77                         get: function() { getCalled = true; throw "FAIL get 3"; },
78                         set: function(v) { setCalled = true; throw "FAIL set 3 " + v; },
79                         configurable: false,
80                         enumerable: true
81                       });
82
83 outer = undefined;
84 try
85 {
86   eval("function acc3() { throw 'FAIL redefined 3'; }; outer = acc3");
87   throw new Error("should have thrown trying to redefine global function " +
88                   "over a non-configurable, enumerable accessor");
89 }
90 catch (e)
91 {
92   assertEq(e instanceof TypeError, true,
93            "global function definition, when that function would overwrite " +
94            "a non-configurable, enumerable accessor, must throw a TypeError " +
95            "per ES5+errata: " + e);
96   desc = Object.getOwnPropertyDescriptor(this, "acc3");
97   assertEq(typeof desc.get, "function");
98   assertEq(typeof desc.set, "function");
99   assertEq(desc.enumerable, true);
100   assertEq(desc.configurable, false);
101   assertEq(outer, undefined);
102   assertEq(getCalled, false);
103   assertEq(setCalled, false);
104 }
105
106
107 getCalled = false, setCalled = false;
108 Object.defineProperty(this, "acc4",
109                       {
110                         get: function() { getCalled = true; throw "FAIL get 4"; },
111                         set: function(v) { setCalled = true; throw "FAIL set 4 " + v; },
112                         configurable: false,
113                         enumerable: false
114                       });
115
116 outer = undefined;
117 try
118 {
119   eval("function acc4() { throw 'FAIL redefined 4'; }; outer = acc4");
120   throw new Error("should have thrown trying to redefine global function " +
121                   "over a non-configurable, non-enumerable accessor");
122 }
123 catch (e)
124 {
125   assertEq(e instanceof TypeError, true,
126            "global function definition, when that function would overwrite " +
127            "a non-configurable, non-enumerable accessor, must throw a " +
128            "TypeError per ES5+errata: " + e);
129   desc = Object.getOwnPropertyDescriptor(this, "acc4");
130   assertEq(typeof desc.get, "function");
131   assertEq(typeof desc.set, "function");
132   assertEq(desc.enumerable, false);
133   assertEq(desc.configurable, false);
134   assertEq(outer, undefined);
135   assertEq(getCalled, false);
136   assertEq(setCalled, false);
137 }
138
139
140 ///////////////////////////////////////////////
141 // Function definitions over data properties //
142 ///////////////////////////////////////////////
143
144
145 // configurable properties, regardless of other attributes, get blown away
146
147 Object.defineProperty(this, "data1",
148                       {
149                         configurable: true,
150                         enumerable: true,
151                         writable: true,
152                         value: "data1"
153                       });
154
155 outer = undefined;
156 eval("function data1() { return 'data1 function'; } outer = data1;");
157 assertEq(typeof data1, "function");
158 assertEq(data1, outer);
159 desc = Object.getOwnPropertyDescriptor(this, "data1");
160 assertEq(desc.configurable, true);
161 assertEq(desc.enumerable, true);
162 assertEq(desc.writable, true);
163 assertEq(desc.value, data1);
164
165
166 Object.defineProperty(this, "data2",
167                       {
168                         configurable: true,
169                         enumerable: true,
170                         writable: false,
171                         value: "data2"
172                       });
173
174 outer = undefined;
175 eval("function data2() { return 'data2 function'; } outer = data2;");
176 assertEq(typeof data2, "function");
177 assertEq(data2, outer);
178 desc = Object.getOwnPropertyDescriptor(this, "data2");
179 assertEq(desc.configurable, true);
180 assertEq(desc.enumerable, true);
181 assertEq(desc.writable, true);
182 assertEq(desc.value, data2);
183
184
185 Object.defineProperty(this, "data3",
186                       {
187                         configurable: true,
188                         enumerable: false,
189                         writable: true,
190                         value: "data3"
191                       });
192
193 outer = undefined;
194 eval("function data3() { return 'data3 function'; } outer = data3;");
195 assertEq(typeof data3, "function");
196 assertEq(data3, outer);
197 desc = Object.getOwnPropertyDescriptor(this, "data3");
198 assertEq(desc.configurable, true);
199 assertEq(desc.enumerable, true);
200 assertEq(desc.writable, true);
201 assertEq(desc.value, data3);
202
203
204 Object.defineProperty(this, "data4",
205                       {
206                         configurable: true,
207                         enumerable: false,
208                         writable: false,
209                         value: "data4"
210                       });
211
212 outer = undefined;
213 eval("function data4() { return 'data4 function'; } outer = data4;");
214 assertEq(typeof data4, "function");
215 assertEq(data4, outer);
216 desc = Object.getOwnPropertyDescriptor(this, "data4");
217 assertEq(desc.value, data4);
218 assertEq(desc.writable, true);
219 assertEq(desc.enumerable, true);
220 assertEq(desc.configurable, true);
221
222
223 // non-configurable data properties are trickier
224
225 Object.defineProperty(this, "data5",
226                       {
227                         configurable: false,
228                         enumerable: true,
229                         writable: true,
230                         value: "data5"
231                       });
232
233 outer = undefined;
234 eval("function data5() { return 'data5 function'; } outer = data5;");
235 assertEq(typeof data5, "function");
236 assertEq(data5, outer);
237 desc = Object.getOwnPropertyDescriptor(this, "data5");
238 assertEq(desc.configurable, false);
239 assertEq(desc.enumerable, true);
240 assertEq(desc.writable, true);
241 assertEq(desc.value, data5);
242
243
244 Object.defineProperty(this, "data6",
245                       {
246                         configurable: false,
247                         enumerable: true,
248                         writable: false,
249                         value: "data6"
250                       });
251
252 outer = undefined;
253 try
254 {
255   eval("function data6() { return 'data6 function'; } outer = data6;");
256   throw new Error("should have thrown trying to redefine global function " +
257                   "over a non-configurable, enumerable, non-writable accessor");
258 }
259 catch (e)
260 {
261   assertEq(e instanceof TypeError, true,
262            "global function definition, when that function would overwrite " +
263            "a non-configurable, enumerable, non-writable data property, must " +
264            "throw a TypeError per ES5+errata: " + e);
265   assertEq(data6, "data6");
266   assertEq(outer, undefined);
267   desc = Object.getOwnPropertyDescriptor(this, "data6");
268   assertEq(desc.configurable, false);
269   assertEq(desc.enumerable, true);
270   assertEq(desc.writable, false);
271   assertEq(desc.value, "data6");
272 }
273
274
275 Object.defineProperty(this, "data7",
276                       {
277                         configurable: false,
278                         enumerable: false,
279                         writable: true,
280                         value: "data7"
281                       });
282
283 outer = undefined;
284 try
285 {
286   eval("function data7() { return 'data7 function'; } outer = data7;");
287   throw new Error("should have thrown trying to redefine global function " +
288                   "over a non-configurable, non-enumerable, writable data" +
289                   "property");
290 }
291 catch (e)
292 {
293   assertEq(e instanceof TypeError, true,
294            "global function definition, when that function would overwrite " +
295            "a non-configurable, non-enumerable, writable data property, must " +
296            "throw a TypeError per ES5+errata: " + e);
297   assertEq(data7, "data7");
298   assertEq(outer, undefined);
299   desc = Object.getOwnPropertyDescriptor(this, "data7");
300   assertEq(desc.configurable, false);
301   assertEq(desc.enumerable, false);
302   assertEq(desc.writable, true);
303   assertEq(desc.value, "data7");
304 }
305
306
307 Object.defineProperty(this, "data8",
308                       {
309                         configurable: false,
310                         enumerable: false,
311                         writable: false,
312                         value: "data8"
313                       });
314
315 outer = undefined;
316 try
317 {
318   eval("function data8() { return 'data8 function'; } outer = data8;");
319   throw new Error("should have thrown trying to redefine global function " +
320                   "over a non-configurable, non-enumerable, non-writable data" +
321                   "property");
322 }
323 catch (e)
324 {
325   assertEq(e instanceof TypeError, true,
326            "global function definition, when that function would overwrite " +
327            "a non-configurable, non-enumerable, non-writable data property, " +
328            "must throw a TypeError per ES5+errata: " + e);
329   assertEq(data8, "data8");
330   assertEq(outer, undefined);
331   desc = Object.getOwnPropertyDescriptor(this, "data8");
332   assertEq(desc.configurable, false);
333   assertEq(desc.enumerable, false);
334   assertEq(desc.writable, false);
335   assertEq(desc.value, "data8");
336 }
337
338 /******************************************************************************/
339
340 if (typeof reportCompare === "function")
341   reportCompare(true, true);
342
343 print("All tests passed!");