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