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