mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-26 07:22:21 +00:00
This fixes that Weak Heap Sort isn't stable and thus might swap equal values, which sometimes results in not deep equal arrays of strings, for example. Insertion sort is stable, so it is used for references instead.
682 lines
18 KiB
TypeScript
682 lines
18 KiB
TypeScript
import "allocator/arena";
|
|
import { Array } from "array";
|
|
import { defaultComparator } from "internal/array";
|
|
|
|
// Obtains the internal capacity of an array from its backing buffer.
|
|
function internalCapacity<T>(array: Array<T>): i32 {
|
|
// the memory region used by the backing buffer might still be larger in that the ArrayBuffer
|
|
// pre-allocates a power of 2 sized buffer itself and reuses it as long as it isn't exceeded.
|
|
var buffer: ArrayBuffer = array.buffer_;
|
|
return buffer.byteLength >> alignof<T>();
|
|
}
|
|
|
|
var arr = new Array<i32>();
|
|
|
|
// Array#push/pop //////////////////////////////////////////////////////////////////////////////////
|
|
|
|
assert(arr.length == 0);
|
|
assert(internalCapacity<i32>(arr) == 0);
|
|
|
|
arr.push(42);
|
|
|
|
assert(arr[0] == 42);
|
|
assert(arr.length == 1);
|
|
assert(internalCapacity<i32>(arr) == 1);
|
|
|
|
var i = arr.pop();
|
|
|
|
assert(i == 42);
|
|
assert(arr.length == 0);
|
|
assert(internalCapacity<i32>(arr) == 1);
|
|
|
|
arr.push(43);
|
|
|
|
assert(arr.length == 1);
|
|
assert(internalCapacity<i32>(arr) == 1);
|
|
assert(arr[0] == 43);
|
|
|
|
arr.push(44);
|
|
|
|
assert(arr.length == 2);
|
|
assert(internalCapacity<i32>(arr) == 2);
|
|
assert(arr[0] == 43);
|
|
assert(arr[1] == 44);
|
|
|
|
arr.push(45);
|
|
|
|
assert(arr.length == 3);
|
|
assert(internalCapacity<i32>(arr) == 3);
|
|
assert(arr[0] == 43);
|
|
assert(arr[1] == 44);
|
|
assert(arr[2] == 45);
|
|
|
|
// Array#unshift ///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
arr.unshift(42);
|
|
|
|
assert(arr.length == 4);
|
|
assert(internalCapacity<i32>(arr) == 4);
|
|
assert(arr[0] == 42);
|
|
assert(arr[1] == 43);
|
|
assert(arr[2] == 44);
|
|
assert(arr[3] == 45);
|
|
|
|
arr.unshift(41);
|
|
|
|
assert(arr.length == 5);
|
|
assert(internalCapacity<i32>(arr) == 5);
|
|
assert(arr[0] == 41);
|
|
assert(arr[1] == 42);
|
|
assert(arr[2] == 43);
|
|
assert(arr[3] == 44);
|
|
assert(arr[4] == 45);
|
|
|
|
// Array#shift /////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
i = arr.shift();
|
|
|
|
assert(i == 41);
|
|
assert(arr.length == 4);
|
|
assert(internalCapacity<i32>(arr) == 5);
|
|
assert(arr[0] == 42);
|
|
assert(arr[1] == 43);
|
|
assert(arr[2] == 44);
|
|
assert(arr[3] == 45);
|
|
|
|
i = arr.pop();
|
|
|
|
assert(i == 45);
|
|
assert(arr.length == 3);
|
|
assert(internalCapacity<i32>(arr) == 5);
|
|
assert(arr[0] == 42);
|
|
assert(arr[1] == 43);
|
|
assert(arr[2] == 44);
|
|
|
|
// Array#reverse ///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
arr.reverse();
|
|
|
|
assert(arr.length == 3);
|
|
assert(internalCapacity<i32>(arr) == 5);
|
|
assert(arr[0] == 44);
|
|
assert(arr[1] == 43);
|
|
assert(arr[2] == 42);
|
|
|
|
arr.push(43);
|
|
arr.push(44);
|
|
|
|
// Array#indexOf ///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
i = arr.indexOf(44);
|
|
|
|
assert(i == 0);
|
|
|
|
i = arr.indexOf(42);
|
|
|
|
assert(i == 2);
|
|
|
|
i = arr.indexOf(45);
|
|
|
|
assert(i == - 1);
|
|
|
|
i = arr.indexOf(43, 100);
|
|
|
|
assert(i == - 1);
|
|
|
|
i = arr.indexOf(43, -100);
|
|
|
|
assert(i == 1);
|
|
|
|
i = arr.indexOf(43, -2);
|
|
|
|
assert(i == 3);
|
|
|
|
i = arr.indexOf(43, -4);
|
|
|
|
assert(i == 1);
|
|
|
|
i = arr.indexOf(43, 0);
|
|
|
|
assert(i == 1);
|
|
|
|
i = arr.indexOf(43, 1);
|
|
|
|
assert(i == 1);
|
|
|
|
i = arr.indexOf(43, 2);
|
|
|
|
assert(i == 3);
|
|
|
|
// Array#includes //////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var includes = arr.includes(44);
|
|
|
|
assert(includes == true);
|
|
|
|
includes = arr.includes(42);
|
|
|
|
assert(includes == true);
|
|
|
|
includes = arr.includes(45);
|
|
|
|
assert(includes == false);
|
|
|
|
includes = arr.includes(43, 100);
|
|
|
|
assert(includes == false);
|
|
|
|
includes = arr.includes(43, -100);
|
|
|
|
assert(includes == true);
|
|
|
|
includes = arr.includes(43, -2);
|
|
|
|
assert(includes == true);
|
|
|
|
includes = arr.includes(43, -4);
|
|
|
|
assert(includes == true);
|
|
|
|
includes = arr.includes(43, 0);
|
|
|
|
assert(includes == true);
|
|
|
|
includes = arr.includes(43, 1);
|
|
|
|
assert(includes == true);
|
|
|
|
includes = arr.includes(43, 2);
|
|
|
|
assert(includes == true);
|
|
|
|
arr.splice(1, 1);
|
|
|
|
assert(arr.length == 4);
|
|
assert(internalCapacity<i32>(arr) == 5);
|
|
assert(arr[0] == 44);
|
|
assert(arr[1] == 42);
|
|
|
|
// Array#findIndex /////////////////////////////////////////////////////////////////////////////////
|
|
|
|
arr[0] = 0;
|
|
arr[1] = 1;
|
|
arr[2] = 2;
|
|
arr[3] = 3;
|
|
|
|
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => value == 0);
|
|
assert(i == 0);
|
|
|
|
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => value == 1);
|
|
assert(i == 1);
|
|
|
|
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => value == 100);
|
|
assert(i == -1);
|
|
|
|
// Test side effect push
|
|
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => {
|
|
array.push(100); // push side effect should not affect this method by spec
|
|
return value == 100;
|
|
});
|
|
// array should be changed, but this method result should be calculated for old array length
|
|
assert(i == -1);
|
|
assert(arr.length == 8);
|
|
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => value == 100);
|
|
assert(i != -1);
|
|
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
|
|
// Test side effect pop
|
|
i = arr.findIndex((value: i32, index: i32, array: Array<i32>): bool => {
|
|
array.pop(); // poped items shouldn't be looked up, and we shouldn't go out of bounds
|
|
return value == 100;
|
|
});
|
|
// only 2 first items was looked up, since last 2 was removed by .pop()
|
|
assert(i == -1);
|
|
assert(arr.length == 2);
|
|
|
|
arr.push(2);
|
|
arr.push(3);
|
|
|
|
// Array#every /////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var every = arr.every((value: i32, index: i32, array: Array<i32>): bool => value >= 0);
|
|
assert(every == true);
|
|
|
|
every = arr.every((value: i32, index: i32, array: Array<i32>): bool => value <= 0);
|
|
assert(every == false);
|
|
|
|
// Test side effect push
|
|
every = arr.every((value: i32, index: i32, array: Array<i32>): bool => {
|
|
array.push(100); // push side effect should not affect this method by spec
|
|
return value < 10;
|
|
});
|
|
// array should be changed, but this method result should be calculated for old array length
|
|
assert(every == true);
|
|
assert(arr.length == 8);
|
|
every = arr.every((value: i32, index: i32, array: Array<i32>): bool => value < 10);
|
|
assert(every == false);
|
|
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
|
|
// Test side effect pop
|
|
every = arr.every((value: i32, index: i32, array: Array<i32>): bool => {
|
|
array.pop(); //poped items shouldn't be looked up, and we shouldn't go out of bounds
|
|
return value < 3;
|
|
});
|
|
// only 2 first items was looked up, since last 2 was removed by .pop()
|
|
assert(every == true);
|
|
assert(arr.length == 2);
|
|
|
|
arr.push(2);
|
|
arr.push(3);
|
|
|
|
// Array#some //////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var some = arr.some((value: i32, index: i32, array: Array<i32>): bool => value >= 3);
|
|
assert(some == true);
|
|
|
|
some = arr.some((value: i32, index: i32, array: Array<i32>): bool => value <= -1);
|
|
assert(some == false);
|
|
|
|
// Test side effect push
|
|
some = arr.some((value: i32, index: i32, array: Array<i32>): bool => {
|
|
array.push(100); // push side effect should not affect this method by spec
|
|
return value > 10;
|
|
});
|
|
// array should be changed, but this method result should be calculated for old array length
|
|
assert(some == false);
|
|
assert(arr.length == 8);
|
|
some = arr.some((value: i32, index: i32, array: Array<i32>): bool => value > 10);
|
|
assert(some == true);
|
|
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
|
|
// Test side effect pop
|
|
some = arr.some((value: i32, index: i32, array: Array<i32>): bool => {
|
|
array.pop(); // poped items shouldn't be looked up, and we shouldn't go out of bounds
|
|
return value > 3;
|
|
});
|
|
// only 2 first items was looked up, since last 2 was removed by .pop()
|
|
assert(some == false);
|
|
assert(arr.length == 2);
|
|
|
|
arr.push(2);
|
|
arr.push(3);
|
|
|
|
// Array#forEach ///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
i = 0;
|
|
arr.forEach((value: i32, index: i32, array: Array<i32>): void => { i += value; });
|
|
assert(i == 6);
|
|
|
|
// Test side effect push
|
|
i = 0;
|
|
arr.forEach((value: i32, index: i32, array: Array<i32>): void => {
|
|
array.push(100); //push side effect should not affect this method by spec
|
|
i += value;
|
|
});
|
|
// array should be changed, but this method result should be calculated for old array length
|
|
assert(i == 6);
|
|
assert(arr.length == 8);
|
|
i = 0;
|
|
arr.forEach((value: i32, index: i32, array: Array<i32>): void => { i += value; });
|
|
assert(i == 406);
|
|
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
|
|
// Test side effect pop
|
|
i = 0;
|
|
arr.forEach((value: i32, index: i32, array: Array<i32>): void => {
|
|
array.pop(); //poped items shouldn't be looked up, and we shouldn't go out of bounds
|
|
i += value;
|
|
});
|
|
// only 2 first items was looked up, since last 2 was removed by .pop()
|
|
assert(i == 1);
|
|
assert(arr.length == 2);
|
|
|
|
arr.push(2);
|
|
arr.push(3);
|
|
|
|
|
|
// Array#map ///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var newArr: f32[] = arr.map<f32>((value: i32, index: i32, array: Array<i32>): f32 => <f32>value);
|
|
assert(newArr.length == 4);
|
|
assert(newArr[0] == <f32>arr[0]);
|
|
|
|
// Test side effect push
|
|
i = 0;
|
|
arr.map<i32>((value: i32, index: i32, array: Array<i32>): i32 => {
|
|
array.push(100); //push side effect should not affect this method by spec
|
|
i += value;
|
|
return value;
|
|
});
|
|
assert(i == 6);
|
|
assert(arr.length == 8);
|
|
|
|
i = 0;
|
|
arr.map<i32>((value: i32, index: i32, array: Array<i32>): i32 => {
|
|
i += value;
|
|
return value;
|
|
});
|
|
assert(i == 406);
|
|
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
|
|
// Test side effect pop
|
|
i = 0;
|
|
arr.map<i32>((value: i32, index: i32, array: Array<i32>): i32 => {
|
|
array.pop(); //poped items shouldn't be looked up, and we shouldn't go out of bounds
|
|
i += value;
|
|
return value;
|
|
});
|
|
// only 2 first items was looked up, since last 2 was removed by .pop()
|
|
assert(i == 1);
|
|
assert(arr.length == 2);
|
|
|
|
arr.push(2);
|
|
arr.push(3);
|
|
|
|
// Array#filter ////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var filteredArr: i32[] = arr.filter((value: i32, index: i32, array: Array<i32>): bool => value >= 2);
|
|
assert(filteredArr.length == 2);
|
|
|
|
// Test side effect push
|
|
i = 0;
|
|
arr.filter((value: i32, index: i32, array: Array<i32>): bool => {
|
|
array.push(100); //push side effect should not affect this method by spec
|
|
i += value;
|
|
return value >= 2;
|
|
});
|
|
assert(i == 6);
|
|
assert(arr.length == 8);
|
|
|
|
i = 0;
|
|
arr.filter((value: i32, index: i32, array: Array<i32>): bool => {
|
|
i += value;
|
|
return value >= 2;
|
|
});
|
|
assert(i == 406);
|
|
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
|
|
// Test side effect pop
|
|
i = 0;
|
|
arr.filter((value: i32, index: i32, array: Array<i32>): bool => {
|
|
array.pop(); //poped items shouldn't be looked up, and we shouldn't go out of bounds
|
|
i += value;
|
|
return value >= 2;
|
|
});
|
|
// only 2 first items was looked up, since last 2 was removed by .pop()
|
|
assert(i == 1);
|
|
assert(arr.length == 2);
|
|
|
|
arr.push(2);
|
|
arr.push(3);
|
|
|
|
// Array#reduce ////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
|
|
assert(i == 6);
|
|
|
|
// init value
|
|
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 4);
|
|
assert(i == 10);
|
|
|
|
var boolVal = arr.reduce<bool>(((prev: bool, current: i32, index: i32, array: Array<i32>): bool => prev || current > 2), false);
|
|
assert(boolVal == true);
|
|
|
|
boolVal = arr.reduce<bool>(((prev: bool, current: i32, index: i32, array: Array<i32>): bool => prev || current > 100), false);
|
|
assert(boolVal == false);
|
|
|
|
// Test side effect push
|
|
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => {
|
|
array.push(1); // push side effect should not affect this method by spec
|
|
return prev + current;
|
|
}), 0);
|
|
// array should be changed, but this method result should be calculated for old array length
|
|
assert(i == 6);
|
|
assert(arr.length == 8);
|
|
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
|
|
assert(i == 10);
|
|
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
|
|
// Test side effect pop
|
|
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => {
|
|
array.pop(); //poped items shouldn't be reduced, and we shouldn't go out of bounds
|
|
return prev + current;
|
|
}), 0);
|
|
// only 2 first items was reduced, since last 2 was removed by .pop()
|
|
assert(i == 1);
|
|
assert(arr.length == 2);
|
|
|
|
arr.push(2);
|
|
arr.push(3);
|
|
|
|
// Array#reduceRight ///////////////////////////////////////////////////////////////////////////////
|
|
|
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
|
|
assert(i == 6);
|
|
|
|
// init value
|
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 4);
|
|
assert(i == 10);
|
|
|
|
boolVal = arr.reduceRight<bool>(((prev: bool, current: i32, index: i32, array: Array<i32>): bool => prev || current > 2), false);
|
|
assert(boolVal == true);
|
|
|
|
boolVal = arr.reduceRight<bool>(((prev: bool, current: i32, index: i32, array: Array<i32>): bool => prev || current > 100), false);
|
|
assert(boolVal == false);
|
|
|
|
// Test side effect push
|
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => {
|
|
array.push(1); // push side effect should not affect this method by spec
|
|
return prev + current;
|
|
}), 0);
|
|
// array should be changed, but this method result should be calculated for old array length
|
|
assert(i == 6);
|
|
assert(arr.length == 8);
|
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
|
|
assert(i == 10);
|
|
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
arr.pop();
|
|
|
|
// Test side effect pop
|
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => {
|
|
array.pop(); // poped items should be reduced
|
|
return prev + current;
|
|
}), 0);
|
|
|
|
assert(i == 6);
|
|
assert(arr.length == 0);
|
|
|
|
arr.push(0);
|
|
arr.push(1);
|
|
arr.push(2);
|
|
arr.push(3);
|
|
|
|
// Array#sort //////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Checks if an array is properly sorted
|
|
function isSorted<T>(data: Array<T>, comparator: (a: T, b: T) => i32 = defaultComparator<T>()): bool {
|
|
for (let i: i32 = 1, len: i32 = data.length; i < len; i++) {
|
|
if (comparator(data[i - 1], data[i]) > 0) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Checks if two arrays are equal
|
|
function isArraysEqual<T>(a: Array<T>, b: Array<T>, len: i32 = 0): bool {
|
|
if (!len) {
|
|
if (a.length != b.length) return false;
|
|
len = a.length;
|
|
}
|
|
for (let i = 0; i < len; i++) {
|
|
if (a[i] != b[i]) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function createReverseOrderedArray(size: i32): Array<i32> {
|
|
var arr = new Array<i32>(size);
|
|
for (let i = 0; i < arr.length; i++) {
|
|
arr[i] = arr.length - 1 - i;
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
NativeMath.seedRandom(reinterpret<u64>(JSMath.random()));
|
|
|
|
function createRandomOrderedArray(size: i32): Array<i32> {
|
|
var arr = new Array<i32>(size);
|
|
for (let i = 0; i < arr.length; i++) {
|
|
arr[i] = <i32>(NativeMath.random() * arr.length);
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
function createReverseOrderedNestedArray(size: i32): Array<Array<i32>> {
|
|
var arr = new Array<Array<i32>>(size);
|
|
for (let i: i32 = 0; i < arr.length; i++) {
|
|
arr[i] = new Array<i32>(1);
|
|
arr[i][0] = arr.length - 1 - i;
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
class Proxy<T> {
|
|
constructor(public x: T) {}
|
|
}
|
|
|
|
function createReverseOrderedElementsArray(size: i32): Proxy<i32>[] {
|
|
var arr = new Array<Proxy<i32>>(size);
|
|
for (let i: i32 = 0; i < arr.length; i++) {
|
|
arr[i] = new Proxy<i32>(arr.length - 1 - i);
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-,.+/\\[]{}()<>*&$%^@#!?";
|
|
|
|
function createRandomString(len: i32): string {
|
|
var result = "";
|
|
|
|
for (let i = 0; i < len; i++) {
|
|
result += charset.charAt(<i32>(NativeMath.floor(NativeMath.random() * charset.length)));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function createRandomStringArray(size: i32): string[] {
|
|
var arr = new Array<string>(size);
|
|
for (let i: i32 = 0; i < arr.length; i++) {
|
|
arr[i] = createRandomString(<i32>(NativeMath.random() * 32));
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
function assertSorted<T>(arr: Array<T>, comparator: (a: T, b: T) => i32): void {
|
|
assert(isSorted<T>(arr.sort(comparator), comparator));
|
|
}
|
|
|
|
function assertSortedDefault<T>(arr: Array<T>): void {
|
|
assertSorted<T>(arr, defaultComparator<T>());
|
|
}
|
|
|
|
var reversed0: Array<i32> = [];
|
|
var reversed1: Array<i32> = [1];
|
|
var reversed2: Array<i32> = [2, 1];
|
|
var reversed4: Array<i32> = [3, 2, 1, 0];
|
|
|
|
var expected4: Array<i32> = [0, 1, 2, 3];
|
|
|
|
var reversed64 = createReverseOrderedArray(64);
|
|
var reversed128 = createReverseOrderedArray(128);
|
|
var reversed1024 = createReverseOrderedArray(1024);
|
|
var reversed10000 = createReverseOrderedArray(10000);
|
|
|
|
var randomized512 = createRandomOrderedArray(512);
|
|
|
|
// Test sorting with with default comparator
|
|
|
|
assertSortedDefault<i32>(reversed0);
|
|
|
|
assertSortedDefault<i32>(reversed1);
|
|
assert(isArraysEqual<i32>(reversed1, <i32[]>[1]));
|
|
|
|
assertSortedDefault<i32>(reversed2);
|
|
assert(isArraysEqual<i32>(reversed2, <i32[]>[1, 2]));
|
|
|
|
assertSortedDefault<i32>(reversed4);
|
|
assert(isArraysEqual<i32>(reversed4, expected4));
|
|
|
|
assertSortedDefault<i32>(reversed64);
|
|
assert(isArraysEqual<i32>(reversed64, expected4, 4));
|
|
|
|
assertSortedDefault<i32>(reversed128);
|
|
assert(isArraysEqual<i32>(reversed128, expected4, 4));
|
|
|
|
assertSortedDefault<i32>(reversed1024);
|
|
assert(isArraysEqual<i32>(reversed1024, expected4, 4));
|
|
|
|
assertSortedDefault<i32>(reversed10000);
|
|
assert(isArraysEqual<i32>(reversed10000, expected4, 4));
|
|
|
|
assertSortedDefault<i32>(randomized512);
|
|
|
|
// Test sorting with custom comparator
|
|
|
|
var randomized64 = createRandomOrderedArray(64);
|
|
var randomized257 = createRandomOrderedArray(257);
|
|
|
|
assertSorted<i32>(randomized64, (a: i32, b: i32): i32 => a - b);
|
|
assertSorted<i32>(randomized64, (a: i32, b: i32): i32 => b - a);
|
|
|
|
assertSorted<i32>(randomized257, (a: i32, b: i32): i32 => a - b);
|
|
assertSorted<i32>(randomized257, (a: i32, b: i32): i32 => b - a);
|
|
|
|
// Test sorting complex objects
|
|
|
|
var reversedNested512 = createReverseOrderedNestedArray(512);
|
|
assertSorted<i32[]>(reversedNested512, (a: i32[], b: i32[]): i32 => a[0] - b[0]);
|
|
|
|
// Test sorting reference elements
|
|
var reversedElements512 = createReverseOrderedElementsArray(512);
|
|
assertSorted<Proxy<i32>>(reversedElements512, (a: Proxy<i32>, b: Proxy<i32>): i32 => a.x - b.x);
|
|
|
|
// Test sorting strings
|
|
|
|
var randomStringsActual: string[] = ["a", "b", "a", "ab", "ba", "", null];
|
|
var randomStringsExpected: string[] = ["", "a", "a", "ab", "b", "ba", null];
|
|
assertSorted<string>(randomStringsActual, (a: string, b: string): i32 => <i32>(a > b) - <i32>(a < b));
|
|
assert(isArraysEqual<string>(randomStringsActual, randomStringsExpected));
|
|
|
|
var randomStrings400 = createRandomStringArray(400);
|
|
assertSorted<string>(randomStrings400, (a: string, b: string): i32 => <i32>(a > b) - <i32>(a < b));
|