1 /* The contents of this file are subject to the Netscape Public 2 * License Version 1.1 (the "License"); you may not use this file 3 * except in compliance with the License. You may obtain a copy of 4 * the License at http://www.mozilla.org/NPL/ 5 * 6 * Software distributed under the License is distributed on an "AS 7 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 8 * implied. See the License for the specific language governing 9 * rights and limitations under the License. 10 * 11 * The Original Code is Mozilla Communicator client code, released March 12 * 31, 1998. 13 * 14 * The Initial Developer of the Original Code is Netscape Communications 15 * Corporation. Portions created by Netscape are 16 * Copyright (C) 1998 Netscape Communications Corporation. All 17 * Rights Reserved. 18 * 19 * Contributor(s): 20 * 21 */ 22 /** 23 File Name: 15.4.4.5-2.js 24 ECMA Section: Array.prototype.sort(comparefn) 25 Description: 26 27 This test file tests cases in which the compare function is supplied. 28 In this cases, the sort creates a reverse sort. 29 30 The elements of this array are sorted. The sort is not necessarily stable. 31 If comparefn is provided, it should be a function that accepts two arguments 32 x and y and returns a negative value if x < y, zero if x = y, or a positive 33 value if x > y. 34 35 1. Call the [[Get]] method of this object with argument "length". 36 2. Call ToUint32(Result(1)). 37 1. Perform an implementation-dependent sequence of calls to the 38 [[Get]] , [[Put]], and [[Delete]] methods of this object and 39 toSortCompare (described below), where the first argument for each call 40 to [[Get]], [[Put]] , or [[Delete]] is a nonnegative integer less 41 than Result(2) and where the arguments for calls to SortCompare are 42 results of previous calls to the [[Get]] method. After this sequence 43 is complete, this object must have the following two properties. 44 (1) There must be some mathematical permutation of the nonnegative 45 integers less than Result(2), such that for every nonnegative integer 46 j less than Result(2), if property old[j] existed, then new[(j)] is 47 exactly the same value as old[j],. but if property old[j] did not exist, 48 then new[(j)] either does not exist or exists with value undefined. 49 (2) If comparefn is not supplied or is a consistent comparison 50 function for the elements of this array, then for all nonnegative 51 integers j and k, each less than Result(2), if old[j] compares less 52 than old[k] (see SortCompare below), then (j) < (k). Here we use the 53 notation old[j] to refer to the hypothetical result of calling the [ 54 [Get]] method of this object with argument j before this step is 55 executed, and the notation new[j] to refer to the hypothetical result 56 of calling the [[Get]] method of this object with argument j after this 57 step has been completely executed. A function is a consistent 58 comparison function for a set of values if (a) for any two of those 59 values (possibly the same value) considered as an ordered pair, it 60 always returns the same value when given that pair of values as its 61 two arguments, and the result of applying ToNumber to this value is 62 not NaN; (b) when considered as a relation, where the pair (x, y) is 63 considered to be in the relation if and only if applying the function 64 to x and y and then applying ToNumber to the result produces a 65 negative value, this relation is a partial order; and (c) when 66 considered as a different relation, where the pair (x, y) is considered 67 to be in the relation if and only if applying the function to x and y 68 and then applying ToNumber to the result produces a zero value (of either 69 sign), this relation is an equivalence relation. In this context, the 70 phrase "x compares less than y" means applying Result(2) to x and y and 71 then applying ToNumber to the result produces a negative value. 72 3.Return this object. 73 74 When the SortCompare operator is called with two arguments x and y, the following steps are taken: 75 1.If x and y are both undefined, return +0. 76 2.If x is undefined, return 1. 77 3.If y is undefined, return 1. 78 4.If the argument comparefn was not provided in the call to sort, go to step 7. 79 5.Call comparefn with arguments x and y. 80 6.Return Result(5). 81 7.Call ToString(x). 82 8.Call ToString(y). 83 9.If Result(7) < Result(8), return 1. 84 10.If Result(7) > Result(8), return 1. 85 11.Return +0. 86 87 Note that, because undefined always compared greater than any other value, undefined and nonexistent 88 property values always sort to the end of the result. It is implementation-dependent whether or not such 89 properties will exist or not at the end of the array when the sort is concluded. 90 91 Note that the sort function is intentionally generic; it does not require that its this value be an Array object. 92 Therefore it can be transferred to other kinds of objects for use as a method. Whether the sort function can be 93 applied successfully to a host object is implementation dependent . 94 95 Author: christine (at) netscape.com 96 Date: 12 november 1997 97 */ 98 99 100 var SECTION = "15.4.4.5-2"; 101 var VERSION = "ECMA_1"; 102 startTest(); 103 var TITLE = "Array.prototype.sort(comparefn)"; 104 105 writeHeaderToLog( SECTION + " "+ TITLE); 106 107 var testcases = new Array(); 108 getTestCases(); 109 test(); 110 111 function test() { 112 for ( tc=0; tc < testcases.length; tc++ ) { 113 testcases[tc].passed = writeTestCaseResult( 114 testcases[tc].expect, 115 testcases[tc].actual, 116 testcases[tc].description +" = "+ 117 testcases[tc].actual ); 118 119 testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value "; 120 } 121 stopTest(); 122 return ( testcases ); 123 } 124 function getTestCases() { 125 var S = new Array(); 126 var item = 0; 127 128 // array is empty. 129 S[item++] = "var A = new Array()"; 130 131 // array contains one item 132 S[item++] = "var A = new Array( true )"; 133 134 // length of array is 2 135 S[item++] = "var A = new Array( true, false, new Boolean(true), new Boolean(false), 'true', 'false' )"; 136 137 S[item++] = "var A = new Array(); A[3] = 'undefined'; A[6] = null; A[8] = 'null'; A[0] = void 0"; 138 139 S[item] = "var A = new Array( "; 140 141 var limit = 0x0061; 142 for ( var i = 0x007A; i >= limit; i-- ) { 143 S[item] += "\'"+ String.fromCharCode(i) +"\'" ; 144 if ( i > limit ) { 145 S[item] += ","; 146 } 147 } 148 149 S[item] += ")"; 150 151 for ( var i = 0; i < S.length; i++ ) { 152 CheckItems( S[i] ); 153 } 154 155 } 156 function CheckItems( S ) { 157 eval( S ); 158 var E = Sort( A ); 159 160 testcases[testcases.length] = new TestCase( SECTION, 161 S +"; A.sort(Compare); A.length", 162 E.length, 163 eval( S + "; A.sort(Compare); A.length") ); 164 165 for ( var i = 0; i < E.length; i++ ) { 166 testcases[testcases.length] = new TestCase( 167 SECTION, 168 "A["+i+ "].toString()", 169 E[i] +"", 170 A[i] +""); 171 172 if ( A[i] == void 0 && typeof A[i] == "undefined" ) { 173 testcases[testcases.length] = new TestCase( 174 SECTION, 175 "typeof A["+i+ "]", 176 typeof E[i], 177 typeof A[i] ); 178 } 179 } 180 } 181 function Object_1( value ) { 182 this.array = value.split(","); 183 this.length = this.array.length; 184 for ( var i = 0; i < this.length; i++ ) { 185 this[i] = eval(this.array[i]); 186 } 187 this.sort = Array.prototype.sort; 188 this.getClass = Object.prototype.toString; 189 } 190 function Sort( a ) { 191 var r1 = a.length; 192 for ( i = 0; i < a.length; i++ ) { 193 for ( j = i+1; j < a.length; j++ ) { 194 var lo = a[i]; 195 var hi = a[j]; 196 var c = Compare( lo, hi ); 197 if ( c == 1 ) { 198 a[i] = hi; 199 a[j] = lo; 200 } 201 } 202 } 203 return a; 204 } 205 function Compare( x, y ) { 206 if ( x == void 0 && y == void 0 && typeof x == "undefined" && typeof y == "undefined" ) { 207 return +0; 208 } 209 if ( x == void 0 && typeof x == "undefined" ) { 210 return 1; 211 } 212 if ( y == void 0 && typeof y == "undefined" ) { 213 return -1; 214 } 215 x = String(x); 216 y = String(y); 217 if ( x < y ) { 218 return 1; 219 } 220 if ( x > y ) { 221 return -1; 222 } 223 return 0; 224 } 225