|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 /* |
|
7 * |
|
8 * Date: 25 Mar 2002 |
|
9 * SUMMARY: Array.prototype.sort() should not (re-)define .length |
|
10 * See http://bugzilla.mozilla.org/show_bug.cgi?id=130451 |
|
11 * |
|
12 * From the ECMA-262 Edition 3 Final spec: |
|
13 * |
|
14 * NOTE: The sort function is intentionally generic; it does not require that |
|
15 * its |this| value be an Array object. Therefore, it can be transferred to |
|
16 * other kinds of objects for use as a method. Whether the sort function can |
|
17 * be applied successfully to a host object is implementation-dependent. |
|
18 * |
|
19 * The interesting parts of this testcase are the contrasting expectations for |
|
20 * Brendan's test below, when applied to Array objects vs. non-Array objects. |
|
21 * |
|
22 */ |
|
23 //----------------------------------------------------------------------------- |
|
24 var UBound = 0; |
|
25 var BUGNUMBER = 130451; |
|
26 var summary = 'Array.prototype.sort() should not (re-)define .length'; |
|
27 var status = ''; |
|
28 var statusitems = []; |
|
29 var actual = ''; |
|
30 var actualvalues = []; |
|
31 var expect= ''; |
|
32 var expectedvalues = []; |
|
33 var arr = []; |
|
34 var cmp = new Function(); |
|
35 |
|
36 |
|
37 /* |
|
38 * First: test Array.prototype.sort() on Array objects |
|
39 */ |
|
40 status = inSection(1); |
|
41 arr = [0,1,2,3]; |
|
42 cmp = function(x,y) {return x-y;}; |
|
43 actual = arr.sort(cmp).length; |
|
44 expect = 4; |
|
45 addThis(); |
|
46 |
|
47 status = inSection(2); |
|
48 arr = [0,1,2,3]; |
|
49 cmp = function(x,y) {return y-x;}; |
|
50 actual = arr.sort(cmp).length; |
|
51 expect = 4; |
|
52 addThis(); |
|
53 |
|
54 status = inSection(3); |
|
55 arr = [0,1,2,3]; |
|
56 cmp = function(x,y) {return x-y;}; |
|
57 arr.length = 1; |
|
58 actual = arr.sort(cmp).length; |
|
59 expect = 1; |
|
60 addThis(); |
|
61 |
|
62 /* |
|
63 * This test is by Brendan. Setting arr.length to |
|
64 * 2 and then 4 should cause elements to be deleted. |
|
65 */ |
|
66 arr = [0,1,2,3]; |
|
67 cmp = function(x,y) {return x-y;}; |
|
68 arr.sort(cmp); |
|
69 |
|
70 status = inSection(4); |
|
71 actual = arr.join(); |
|
72 expect = '0,1,2,3'; |
|
73 addThis(); |
|
74 |
|
75 status = inSection(5); |
|
76 actual = arr.length; |
|
77 expect = 4; |
|
78 addThis(); |
|
79 |
|
80 status = inSection(6); |
|
81 arr.length = 2; |
|
82 actual = arr.join(); |
|
83 expect = '0,1'; |
|
84 addThis(); |
|
85 |
|
86 status = inSection(7); |
|
87 arr.length = 4; |
|
88 actual = arr.join(); |
|
89 expect = '0,1,,'; //<---- see how 2,3 have been lost |
|
90 addThis(); |
|
91 |
|
92 |
|
93 |
|
94 /* |
|
95 * Now test Array.prototype.sort() on non-Array objects |
|
96 */ |
|
97 status = inSection(8); |
|
98 var obj = new Object(); |
|
99 obj.sort = Array.prototype.sort; |
|
100 obj.length = 4; |
|
101 obj[0] = 0; |
|
102 obj[1] = 1; |
|
103 obj[2] = 2; |
|
104 obj[3] = 3; |
|
105 cmp = function(x,y) {return x-y;}; |
|
106 actual = obj.sort(cmp).length; |
|
107 expect = 4; |
|
108 addThis(); |
|
109 |
|
110 |
|
111 /* |
|
112 * Here again is Brendan's test. Unlike the array case |
|
113 * above, the setting of obj.length to 2 and then 4 |
|
114 * should NOT cause elements to be deleted |
|
115 */ |
|
116 obj = new Object(); |
|
117 obj.sort = Array.prototype.sort; |
|
118 obj.length = 4; |
|
119 obj[0] = 3; |
|
120 obj[1] = 2; |
|
121 obj[2] = 1; |
|
122 obj[3] = 0; |
|
123 cmp = function(x,y) {return x-y;}; |
|
124 obj.sort(cmp); //<---- this is what triggered the buggy behavior below |
|
125 obj.join = Array.prototype.join; |
|
126 |
|
127 status = inSection(9); |
|
128 actual = obj.join(); |
|
129 expect = '0,1,2,3'; |
|
130 addThis(); |
|
131 |
|
132 status = inSection(10); |
|
133 actual = obj.length; |
|
134 expect = 4; |
|
135 addThis(); |
|
136 |
|
137 status = inSection(11); |
|
138 obj.length = 2; |
|
139 actual = obj.join(); |
|
140 expect = '0,1'; |
|
141 addThis(); |
|
142 |
|
143 /* |
|
144 * Before this bug was fixed, |actual| held the value '0,1,,' |
|
145 * as in the Array-object case at top. This bug only occurred |
|
146 * if Array.prototype.sort() had been applied to |obj|, |
|
147 * as we have done higher up. |
|
148 */ |
|
149 status = inSection(12); |
|
150 obj.length = 4; |
|
151 actual = obj.join(); |
|
152 expect = '0,1,2,3'; |
|
153 addThis(); |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 //----------------------------------------------------------------------------- |
|
159 test(); |
|
160 //----------------------------------------------------------------------------- |
|
161 |
|
162 |
|
163 |
|
164 function addThis() |
|
165 { |
|
166 statusitems[UBound] = status; |
|
167 actualvalues[UBound] = actual; |
|
168 expectedvalues[UBound] = expect; |
|
169 UBound++; |
|
170 } |
|
171 |
|
172 |
|
173 function test() |
|
174 { |
|
175 enterFunc('test'); |
|
176 printBugNumber(BUGNUMBER); |
|
177 printStatus(summary); |
|
178 |
|
179 for (var i=0; i<UBound; i++) |
|
180 { |
|
181 reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); |
|
182 } |
|
183 |
|
184 exitFunc ('test'); |
|
185 } |