1/* ***** BEGIN LICENSE BLOCK *****
2* Version: NPL 1.1/GPL 2.0/LGPL 2.1
3*
4* The contents of this file are subject to the Netscape Public License
5* Version 1.1 (the "License"); you may not use this file except in
6* compliance with the License. You may obtain a copy of the License at
7* http://www.mozilla.org/NPL/
8*
9* Software distributed under the License is distributed on an "AS IS" basis,
10* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11* for the specific language governing rights and limitations under the
12* License.
13*
14* The Original Code is JavaScript Engine testing utilities.
15*
16* The Initial Developer of the Original Code is Netscape Communications Corp.
17* Portions created by the Initial Developer are Copyright (C) 2002
18* the Initial Developer. All Rights Reserved.
19*
20* Contributor(s): brendan@mozilla.org, pschwartau@netscape.com
21*
22* Alternatively, the contents of this file may be used under the terms of
23* either the GNU General Public License Version 2 or later (the "GPL"), or
24* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
25* in which case the provisions of the GPL or the LGPL are applicable instead
26* of those above. If you wish to allow use of your version of this file only
27* under the terms of either the GPL or the LGPL, and not to allow others to
28* use your version of this file under the terms of the NPL, indicate your
29* decision by deleting the provisions above and replace them with the notice
30* and other provisions required by the GPL or the LGPL. If you do not delete
31* the provisions above, a recipient may use your version of this file under
32* the terms of any one of the NPL, the GPL or the LGPL.
33*
34* ***** END LICENSE BLOCK *****
35*
36*
37* Date:    25 Mar 2002
38* SUMMARY: Array.prototype.sort() should not (re-)define .length
39* See http://bugzilla.mozilla.org/show_bug.cgi?id=130451
40*
41* From the ECMA-262 Edition 3 Final spec:
42*
43* NOTE: The sort function is intentionally generic; it does not require that
44* its |this| value be an Array object. Therefore, it can be transferred to
45* other kinds of objects for use as a method. Whether the sort function can
46* be applied successfully to a host object is implementation-dependent.
47*
48* The interesting parts of this testcase are the contrasting expectations for
49* Brendan's test below, when applied to Array objects vs. non-Array objects.
50*
51*/
52//-----------------------------------------------------------------------------
53var UBound = 0;
54var bug = 130451;
55var summary = 'Array.prototype.sort() should not (re-)define .length';
56var status = '';
57var statusitems = [];
58var actual = '';
59var actualvalues = [];
60var expect= '';
61var expectedvalues = [];
62var arr = [];
63var cmp = new Function();
64
65
66/*
67 * First: test Array.prototype.sort() on Array objects
68 */
69status = inSection(1);
70arr = [0,1,2,3];
71cmp = function(x,y) {return x-y;};
72actual = arr.sort(cmp).length;
73expect = 4;
74addThis();
75
76status = inSection(2);
77arr = [0,1,2,3];
78cmp = function(x,y) {return y-x;};
79actual = arr.sort(cmp).length;
80expect = 4;
81addThis();
82
83status = inSection(3);
84arr = [0,1,2,3];
85cmp = function(x,y) {return x-y;};
86arr.length = 1;
87actual = arr.sort(cmp).length;
88expect = 1;
89addThis();
90
91/*
92 * This test is by Brendan. Setting arr.length to
93 * 2 and then 4 should cause elements to be deleted.
94 */
95arr = [0,1,2,3];
96cmp = function(x,y) {return x-y;};
97arr.sort(cmp);
98
99status = inSection(4);
100actual = arr.join();
101expect = '0,1,2,3';
102addThis();
103
104status = inSection(5);
105actual = arr.length;
106expect = 4;
107addThis();
108
109status = inSection(6);
110arr.length = 2;
111actual = arr.join();
112expect = '0,1';
113addThis();
114
115status = inSection(7);
116arr.length = 4;
117actual = arr.join();
118expect = '0,1,,';  //<---- see how 2,3 have been lost
119addThis();
120
121
122
123/*
124 * Now test Array.prototype.sort() on non-Array objects
125 */
126status = inSection(8);
127var obj = new Object();
128obj.sort = Array.prototype.sort;
129obj.length = 4;
130obj[0] = 0;
131obj[1] = 1;
132obj[2] = 2;
133obj[3] = 3;
134cmp = function(x,y) {return x-y;};
135actual = obj.sort(cmp).length;
136expect = 4;
137addThis();
138
139
140/*
141 * Here again is Brendan's test. Unlike the array case
142 * above, the setting of obj.length to 2 and then 4
143 * should NOT cause elements to be deleted
144 */
145obj = new Object();
146obj.sort = Array.prototype.sort;
147obj.length = 4;
148obj[0] = 3;
149obj[1] = 2;
150obj[2] = 1;
151obj[3] = 0;
152cmp = function(x,y) {return x-y;};
153obj.sort(cmp);  //<---- this is what triggered the buggy behavior below
154obj.join = Array.prototype.join;
155
156status = inSection(9);
157actual = obj.join();
158expect = '0,1,2,3';
159addThis();
160
161status = inSection(10);
162actual = obj.length;
163expect = 4;
164addThis();
165
166status = inSection(11);
167obj.length = 2;
168actual = obj.join();
169expect = '0,1';
170addThis();
171
172/*
173 * Before this bug was fixed, |actual| held the value '0,1,,'
174 * as in the Array-object case at top. This bug only occurred
175 * if Array.prototype.sort() had been applied to |obj|,
176 * as we have done higher up.
177 */
178status = inSection(12);
179obj.length = 4;
180actual = obj.join();
181expect = '0,1,2,3';
182addThis();
183
184
185
186
187//-----------------------------------------------------------------------------
188test();
189//-----------------------------------------------------------------------------
190
191
192
193function addThis()
194{
195  statusitems[UBound] = status;
196  actualvalues[UBound] = actual;
197  expectedvalues[UBound] = expect;
198  UBound++;
199}
200
201
202function test()
203{
204  enterFunc('test');
205  printBugNumber(bug);
206  printStatus(summary);
207
208  for (var i=0; i<UBound; i++)
209  {
210    reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
211  }
212
213  exitFunc ('test');
214}
215