Skip to content

Commit

Permalink
RAB: Integrate staging tests for the .sort method (#4176)
Browse files Browse the repository at this point in the history
* Import relevant files from #3888

* Removing parts in resizableArrayBufferUtils.js and adding it in includes,
while applying review changes from PRs for previously tested methods.

* Renamed test files

* Some minor documentation fixes and removing onlyStrict flag
  • Loading branch information
ioannad authored Aug 6, 2024
1 parent c0942e0 commit ef72bd1
Show file tree
Hide file tree
Showing 8 changed files with 1,036 additions and 0 deletions.
69 changes: 69 additions & 0 deletions test/built-ins/Array/prototype/sort/comparefn-grow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2023 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-array.prototype.sort
description: >
Array.p.sort behaves correctly on TypedArrays backed by resizable buffers which
are grown by the comparison callback.
includes: [compareArray.js, resizableArrayBufferUtils.js]
features: [resizable-arraybuffer]
---*/

function ResizeAndCompare(rab, resizeTo) {
return (a, b) => {
rab.resize(resizeTo);
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
}

function WriteUnsortedData(taFull) {
for (let i = 0; i < taFull.length; ++i) {
WriteToTypedArray(taFull, i, 10 - i);
}
}

// Fixed length TA.
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT);
const resizeTo = 6 * ctor.BYTES_PER_ELEMENT;
const fixedLength = new ctor(rab, 0, 4);
const taFull = new ctor(rab, 0);
WriteUnsortedData(taFull);
Array.prototype.sort.call(fixedLength, ResizeAndCompare(rab, resizeTo));
// Growing doesn't affect the sorting.
assert.compareArray(ToNumbers(taFull), [
7,
8,
9,
10,
0,
0
]);
}

// Length-tracking TA.
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT);
const resizeTo = 6 * ctor.BYTES_PER_ELEMENT;
const lengthTracking = new ctor(rab, 0);
const taFull = new ctor(rab, 0);
WriteUnsortedData(taFull);
Array.prototype.sort.call(lengthTracking, ResizeAndCompare(rab, resizeTo));
// Growing doesn't affect the sorting. Only the elements that were part of
// the original TA are sorted.
assert.compareArray(ToNumbers(taFull), [
7,
8,
9,
10,
0,
0
]);
}
191 changes: 191 additions & 0 deletions test/built-ins/Array/prototype/sort/comparefn-resizable-buffer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
// Copyright 2023 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-array.prototype.sort
description: >
Array.p.sort behaves correctly on TypedArrays backed by resizable buffers and
is passed a user-provided comparison callback.
includes: [compareArray.js, resizableArrayBufferUtils.js]
features: [resizable-arraybuffer]
---*/

for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT);
const fixedLength = new ctor(rab, 0, 4);
const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2);
const lengthTracking = new ctor(rab, 0);
const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT);
const taFull = new ctor(rab, 0);
function WriteUnsortedData() {
// Write some data into the array.
for (let i = 0; i < taFull.length; ++i) {
WriteToTypedArray(taFull, i, 10 - i);
}
}
function OddBeforeEvenComparison(a, b) {
// Sort all odd numbers before even numbers.
a = Number(a);
b = Number(b);
if (a % 2 == 1 && b % 2 == 0) {
return -1;
}
if (a % 2 == 0 && b % 2 == 1) {
return 1;
}
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
// Orig. array: [10, 9, 8, 7]
// [10, 9, 8, 7] << fixedLength
// [8, 7] << fixedLengthWithOffset
// [10, 9, 8, 7, ...] << lengthTracking
// [8, 7, ...] << lengthTrackingWithOffset

WriteUnsortedData();
Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
7,
9,
8,
10
]);
WriteUnsortedData();
Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
10,
9,
7,
8
]);
WriteUnsortedData();
Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
7,
9,
8,
10
]);
WriteUnsortedData();
Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
10,
9,
7,
8
]);

// Shrink so that fixed length TAs go out of bounds.
rab.resize(3 * ctor.BYTES_PER_ELEMENT);

// Orig. array: [10, 9, 8]
// [10, 9, 8, ...] << lengthTracking
// [8, ...] << lengthTrackingWithOffset

WriteUnsortedData();
Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
10,
9,
8
]);
Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
10,
9,
8
]);

WriteUnsortedData();
Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
9,
8,
10
]);
WriteUnsortedData();
Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
10,
9,
8
]);

// Shrink so that the TAs with offset go out of bounds.
rab.resize(1 * ctor.BYTES_PER_ELEMENT);
WriteUnsortedData();
Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [10]);
Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [10]);
Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [10]);

WriteUnsortedData();
Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [10]);

// Shrink to zero.
rab.resize(0);
Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison);
Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison);
Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison);

Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), []);

// Grow so that all TAs are back in-bounds.
rab.resize(6 * ctor.BYTES_PER_ELEMENT);

// Orig. array: [10, 9, 8, 7, 6, 5]
// [10, 9, 8, 7] << fixedLength
// [8, 7] << fixedLengthWithOffset
// [10, 9, 8, 7, 6, 5, ...] << lengthTracking
// [8, 7, 6, 5, ...] << lengthTrackingWithOffset

WriteUnsortedData();
Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
7,
9,
8,
10,
6,
5
]);
WriteUnsortedData();
Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
10,
9,
7,
8,
6,
5
]);
WriteUnsortedData();
Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
5,
7,
9,
6,
8,
10
]);
WriteUnsortedData();
Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison);
assert.compareArray(ToNumbers(taFull), [
10,
9,
5,
7,
6,
8
]);
}
71 changes: 71 additions & 0 deletions test/built-ins/Array/prototype/sort/comparefn-shrink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2023 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-array.prototype.sort
description: >
Array.p.sort behaves correctly on TypedArrays backed by resizable buffers and
is shrunk by the comparison callback.
includes: [compareArray.js, resizableArrayBufferUtils.js]
features: [resizable-arraybuffer, Array.prototype.includes]
---*/

function ResizeAndCompare(rab, resizeTo) {
return (a, b) => {
rab.resize(resizeTo);
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
}

function WriteUnsortedData(taFull) {
for (let i = 0; i < taFull.length; ++i) {
WriteToTypedArray(taFull, i, 10 - i);
}
}

// Fixed length TA.
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT);
const resizeTo = 2 * ctor.BYTES_PER_ELEMENT;
const fixedLength = new ctor(rab, 0, 4);
const taFull = new ctor(rab, 0);
WriteUnsortedData(taFull);
Array.prototype.sort.call(fixedLength, ResizeAndCompare(rab, resizeTo));
// The data is unchanged.
assert.compareArray(ToNumbers(taFull), [
10,
9
]);
}

// Length-tracking TA.
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT);
const resizeTo = 2 * ctor.BYTES_PER_ELEMENT;
const lengthTracking = new ctor(rab, 0);
const taFull = new ctor(rab, 0);
WriteUnsortedData(taFull);
Array.prototype.sort.call(lengthTracking, ResizeAndCompare(rab, resizeTo));
// The sort result is implementation defined, but it contains 2 elements out
// of the 4 original ones.
const newData = ToNumbers(taFull);
assert.sameValue(newData.length, 2);
assert([
10,
9,
8,
7
].includes(newData[0]));
assert([
10,
9,
8,
7
].includes(newData[1]));
}
Loading

0 comments on commit ef72bd1

Please sign in to comment.