зеркало из https://github.com/mozilla/pjs.git
225 строки
8.8 KiB
JavaScript
225 строки
8.8 KiB
JavaScript
/* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Mozilla Communicator client code, released March
|
|
* 31, 1998.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
*/
|
|
/**
|
|
File Name: 15.4.4.5-2.js
|
|
ECMA Section: Array.prototype.sort(comparefn)
|
|
Description:
|
|
|
|
This test file tests cases in which the compare function is supplied.
|
|
In this cases, the sort creates a reverse sort.
|
|
|
|
The elements of this array are sorted. The sort is not necessarily stable.
|
|
If comparefn is provided, it should be a function that accepts two arguments
|
|
x and y and returns a negative value if x < y, zero if x = y, or a positive
|
|
value if x > y.
|
|
|
|
1. Call the [[Get]] method of this object with argument "length".
|
|
2. Call ToUint32(Result(1)).
|
|
1. Perform an implementation-dependent sequence of calls to the
|
|
[[Get]] , [[Put]], and [[Delete]] methods of this object and
|
|
toSortCompare (described below), where the first argument for each call
|
|
to [[Get]], [[Put]] , or [[Delete]] is a nonnegative integer less
|
|
than Result(2) and where the arguments for calls to SortCompare are
|
|
results of previous calls to the [[Get]] method. After this sequence
|
|
is complete, this object must have the following two properties.
|
|
(1) There must be some mathematical permutation of the nonnegative
|
|
integers less than Result(2), such that for every nonnegative integer
|
|
j less than Result(2), if property old[j] existed, then new[(j)] is
|
|
exactly the same value as old[j],. but if property old[j] did not exist,
|
|
then new[(j)] either does not exist or exists with value undefined.
|
|
(2) If comparefn is not supplied or is a consistent comparison
|
|
function for the elements of this array, then for all nonnegative
|
|
integers j and k, each less than Result(2), if old[j] compares less
|
|
than old[k] (see SortCompare below), then (j) < (k). Here we use the
|
|
notation old[j] to refer to the hypothetical result of calling the [
|
|
[Get]] method of this object with argument j before this step is
|
|
executed, and the notation new[j] to refer to the hypothetical result
|
|
of calling the [[Get]] method of this object with argument j after this
|
|
step has been completely executed. A function is a consistent
|
|
comparison function for a set of values if (a) for any two of those
|
|
values (possibly the same value) considered as an ordered pair, it
|
|
always returns the same value when given that pair of values as its
|
|
two arguments, and the result of applying ToNumber to this value is
|
|
not NaN; (b) when considered as a relation, where the pair (x, y) is
|
|
considered to be in the relation if and only if applying the function
|
|
to x and y and then applying ToNumber to the result produces a
|
|
negative value, this relation is a partial order; and (c) when
|
|
considered as a different relation, where the pair (x, y) is considered
|
|
to be in the relation if and only if applying the function to x and y
|
|
and then applying ToNumber to the result produces a zero value (of either
|
|
sign), this relation is an equivalence relation. In this context, the
|
|
phrase "x compares less than y" means applying Result(2) to x and y and
|
|
then applying ToNumber to the result produces a negative value.
|
|
3.Return this object.
|
|
|
|
When the SortCompare operator is called with two arguments x and y, the following steps are taken:
|
|
1.If x and y are both undefined, return +0.
|
|
2.If x is undefined, return 1.
|
|
3.If y is undefined, return 1.
|
|
4.If the argument comparefn was not provided in the call to sort, go to step 7.
|
|
5.Call comparefn with arguments x and y.
|
|
6.Return Result(5).
|
|
7.Call ToString(x).
|
|
8.Call ToString(y).
|
|
9.If Result(7) < Result(8), return 1.
|
|
10.If Result(7) > Result(8), return 1.
|
|
11.Return +0.
|
|
|
|
Note that, because undefined always compared greater than any other value, undefined and nonexistent
|
|
property values always sort to the end of the result. It is implementation-dependent whether or not such
|
|
properties will exist or not at the end of the array when the sort is concluded.
|
|
|
|
Note that the sort function is intentionally generic; it does not require that its this value be an Array object.
|
|
Therefore it can be transferred to other kinds of objects for use as a method. Whether the sort function can be
|
|
applied successfully to a host object is implementation dependent .
|
|
|
|
Author: christine@netscape.com
|
|
Date: 12 november 1997
|
|
*/
|
|
|
|
|
|
var SECTION = "15.4.4.5-2";
|
|
var VERSION = "ECMA_1";
|
|
startTest();
|
|
var TITLE = "Array.prototype.sort(comparefn)";
|
|
|
|
writeHeaderToLog( SECTION + " "+ TITLE);
|
|
|
|
var testcases = new Array();
|
|
getTestCases();
|
|
test();
|
|
|
|
function test() {
|
|
for ( tc=0; tc < testcases.length; tc++ ) {
|
|
testcases[tc].passed = writeTestCaseResult(
|
|
testcases[tc].expect,
|
|
testcases[tc].actual,
|
|
testcases[tc].description +" = "+
|
|
testcases[tc].actual );
|
|
|
|
testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value ";
|
|
}
|
|
stopTest();
|
|
return ( testcases );
|
|
}
|
|
function getTestCases() {
|
|
var S = new Array();
|
|
var item = 0;
|
|
|
|
// array is empty.
|
|
S[item++] = "var A = new Array()";
|
|
|
|
// array contains one item
|
|
S[item++] = "var A = new Array( true )";
|
|
|
|
// length of array is 2
|
|
S[item++] = "var A = new Array( true, false, new Boolean(true), new Boolean(false), 'true', 'false' )";
|
|
|
|
S[item++] = "var A = new Array(); A[3] = 'undefined'; A[6] = null; A[8] = 'null'; A[0] = void 0";
|
|
|
|
S[item] = "var A = new Array( ";
|
|
|
|
var limit = 0x0061;
|
|
for ( var i = 0x007A; i >= limit; i-- ) {
|
|
S[item] += "\'"+ String.fromCharCode(i) +"\'" ;
|
|
if ( i > limit ) {
|
|
S[item] += ",";
|
|
}
|
|
}
|
|
|
|
S[item] += ")";
|
|
|
|
for ( var i = 0; i < S.length; i++ ) {
|
|
CheckItems( S[i] );
|
|
}
|
|
|
|
}
|
|
function CheckItems( S ) {
|
|
eval( S );
|
|
var E = Sort( A );
|
|
|
|
testcases[testcases.length] = new TestCase( SECTION,
|
|
S +"; A.sort(Compare); A.length",
|
|
E.length,
|
|
eval( S + "; A.sort(Compare); A.length") );
|
|
|
|
for ( var i = 0; i < E.length; i++ ) {
|
|
testcases[testcases.length] = new TestCase(
|
|
SECTION,
|
|
"A["+i+ "].toString()",
|
|
E[i] +"",
|
|
A[i] +"");
|
|
|
|
if ( A[i] == void 0 && typeof A[i] == "undefined" ) {
|
|
testcases[testcases.length] = new TestCase(
|
|
SECTION,
|
|
"typeof A["+i+ "]",
|
|
typeof E[i],
|
|
typeof A[i] );
|
|
}
|
|
}
|
|
}
|
|
function Object_1( value ) {
|
|
this.array = value.split(",");
|
|
this.length = this.array.length;
|
|
for ( var i = 0; i < this.length; i++ ) {
|
|
this[i] = eval(this.array[i]);
|
|
}
|
|
this.sort = Array.prototype.sort;
|
|
this.getClass = Object.prototype.toString;
|
|
}
|
|
function Sort( a ) {
|
|
var r1 = a.length;
|
|
for ( i = 0; i < a.length; i++ ) {
|
|
for ( j = i+1; j < a.length; j++ ) {
|
|
var lo = a[i];
|
|
var hi = a[j];
|
|
var c = Compare( lo, hi );
|
|
if ( c == 1 ) {
|
|
a[i] = hi;
|
|
a[j] = lo;
|
|
}
|
|
}
|
|
}
|
|
return a;
|
|
}
|
|
function Compare( x, y ) {
|
|
if ( x == void 0 && y == void 0 && typeof x == "undefined" && typeof y == "undefined" ) {
|
|
return +0;
|
|
}
|
|
if ( x == void 0 && typeof x == "undefined" ) {
|
|
return 1;
|
|
}
|
|
if ( y == void 0 && typeof y == "undefined" ) {
|
|
return -1;
|
|
}
|
|
x = String(x);
|
|
y = String(y);
|
|
if ( x < y ) {
|
|
return 1;
|
|
}
|
|
if ( x > y ) {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|