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