Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / tests / ecma_3 / Function / scope-001.js
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  * http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  *
15  * The Original Code is mozilla.org code.
16  *
17  * The Initial Developer of the Original Code is
18  * Netscape Communications Corporation.
19  * Portions created by the Initial Developer are Copyright (C) 1998
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s):
23  *   pschwartau@netscape.com, rogerl@netscape.com
24  *
25  * Alternatively, the contents of this file may be used under the terms of
26  * either the GNU General Public License Version 2 or later (the "GPL"), or
27  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28  * in which case the provisions of the GPL or the LGPL are applicable instead
29  * of those above. If you wish to allow use of your version of this file only
30  * under the terms of either the GPL or the LGPL, and not to allow others to
31  * use your version of this file under the terms of the MPL, indicate your
32  * decision by deleting the provisions above and replace them with the notice
33  * and other provisions required by the GPL or the LGPL. If you do not delete
34  * the provisions above, a recipient may use your version of this file under
35  * the terms of any one of the MPL, the GPL or the LGPL.
36  *
37  * ***** END LICENSE BLOCK ***** */
38
39 /*
40  * Date: 28 May 2001
41  *
42  * SUMMARY:  Functions are scoped statically, not dynamically
43  *
44  * See ECMA Section 10.1.4 Scope Chain and Identifier Resolution
45  * (This section defines the scope chain of an execution context)
46  *
47  * See ECMA Section 12.10 The with Statement
48  *
49  * See ECMA Section 13 Function Definition
50  * (This section defines the scope chain of a function object as that
51  *  of the running execution context when the function was declared)
52  */
53 //-----------------------------------------------------------------------------
54 var UBound = 0;
55 var BUGNUMBER = '(none)';
56 var summary = 'Testing that functions are scoped statically, not dynamically';
57 var self = this;  // capture a reference to the global object
58 var status = '';
59 var statusitems = [ ];
60 var actual = '';
61 var actualvalues = [ ];
62 var expect= '';
63 var expectedvalues = [ ];
64
65 /*
66  * In this section the expected value is 1, not 2.
67  *
68  * Why? f captures its scope chain from when it's declared, and imposes that chain
69  * when it's executed. In other words, f's scope chain is from when it was compiled.
70  * Since f is a top-level function, this is the global object only. Hence 'a' resolves to 1.
71  */
72 status = 'Section A of test';
73 var a = 1;
74 function f()
75 {
76   return a;
77 }
78 var obj = {a:2};
79 with (obj)
80 {
81   actual = f();
82 }
83 expect = 1;
84 addThis();
85
86
87 /*
88  * In this section the expected value is 2, not 1. That is because here
89  * f's associated scope chain now includes 'obj' before the global object.
90  */
91 status = 'Section B of test';
92 var a = 1;
93 var obj = {a:2};
94 with (obj)
95 {
96   function f()
97   {
98     return a;
99   }
100   actual = f();
101 }
102 expect = 2;
103 addThis();
104
105
106 /*
107  * Like Section B , except that we call f outside the with block.
108  * By the principles explained above, we still expect 2 -
109  */
110 status = 'Section C of test';
111 var a = 1;
112 var obj = {a:2};
113 with (obj)
114 {
115   function f()
116   {
117     return a;
118   }
119 }
120 actual = f();
121 expect = 2;
122 addThis();
123
124
125 /*
126  * Like Section C, but with one more level of indirection -
127  */
128 status = 'Section D of test';
129 var a = 1;
130 var obj = {a:2, obj:{a:3}};
131 with (obj)
132 {
133   with (obj)
134   {
135     function f()
136     {
137       return a;
138     }
139   }
140 }
141 actual = f();
142 expect = 3;
143 addThis();
144
145
146 /*
147  * Like Section C, but here we actually delete obj before calling f.
148  * We still expect 2 -
149  */
150 status = 'Section E of test';
151 var a = 1;
152 var obj = {a:2};
153 with (obj)
154 {
155   function f()
156   {
157     return a;
158   }
159 }
160 delete obj;
161 actual = f();
162 expect = 2;
163 addThis();
164
165
166 /*
167  * Like Section E. Here we redefine obj and call f under with (obj) -
168  * We still expect 2 -
169  */
170 status = 'Section F of test';
171 var a = 1;
172 var obj = {a:2};
173 with (obj)
174 {
175   function f()
176   {
177     return a;
178   }
179 }
180 delete obj;
181 var obj = {a:3};
182 with (obj)
183 {
184   actual = f();
185 }
186 expect = 2;  // NOT 3 !!!
187 addThis();
188
189
190 /*
191  * Explicitly verify that f exists at global level, even though
192  * it was defined under the with(obj) block -
193  */
194 status = 'Section G of test';
195 var a = 1;
196 var obj = {a:2};
197 with (obj)
198 {
199   function f()
200   {
201     return a;
202   }
203 }
204 actual = String([obj.hasOwnProperty('f'), self.hasOwnProperty('f')]);
205 expect = String([false, true]);
206 addThis();
207
208
209 /*
210  * Explicitly verify that f exists at global level, even though
211  * it was defined under the with(obj) block -
212  */
213 status = 'Section H of test';
214 var a = 1;
215 var obj = {a:2};
216 with (obj)
217 {
218   function f()
219   {
220     return a;
221   }
222 }
223 actual = String(['f' in obj, 'f' in self]);
224 expect = String([false, true]);
225 addThis();
226
227
228
229 //-------------------------------------------------------------------------------------------------
230 test();
231 //-------------------------------------------------------------------------------------------------
232
233
234 function addThis()
235 {
236   statusitems[UBound] = status;
237   actualvalues[UBound] = actual;
238   expectedvalues[UBound] = expect;
239   UBound++;
240   resetTestVars();
241 }
242
243
244 function resetTestVars()
245 {
246   delete a;
247   delete obj;
248   delete f;
249 }
250
251
252 function test()
253 {
254   enterFunc ('test');
255   printBugNumber(BUGNUMBER);
256   printStatus (summary);
257
258   for (var i = 0; i < UBound; i++)
259   {
260     reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
261   }
262
263   exitFunc ('test');
264 }