You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Cesium-Prequel/Specs/Core/DoubleEndedPriorityQueueSpe...

465 lines
12 KiB
JavaScript

import { DoubleEndedPriorityQueue } from "../../Source/Cesium.js";
describe("Core/DoubleEndedPriorityQueue", function () {
function comparator(a, b) {
return a - b;
}
it("constructor throws without options", function () {
expect(function () {
return new DoubleEndedPriorityQueue();
}).toThrowDeveloperError();
});
it("constructor throws if maximum length is less than zero", function () {
expect(function () {
return new DoubleEndedPriorityQueue({
comparator: comparator,
maximumLength: -1,
});
}).toThrowDeveloperError();
});
it("constructor throws without comparator", function () {
expect(function () {
return new DoubleEndedPriorityQueue({
comparator: undefined,
});
}).toThrowDeveloperError();
});
it("gets comparator", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
var returnedComparator = queue.comparator;
expect(returnedComparator).toEqual(comparator);
});
it("uses different comparator", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: function (a, b) {
return b - a;
},
});
queue.insert(1);
queue.insert(2);
// The comparator is flipped, so 2 is considered the minimum and 1 is considered the maximum
expect(queue.length).toEqual(2);
expect(queue.getMinimum()).toEqual(2);
expect(queue.getMaximum()).toEqual(1);
});
it("checks state of default empty queue", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
expect(queue.length).toEqual(0);
expect(queue.maximumLength).toBeUndefined();
expect(queue.internalArray.length).toEqual(0);
expect(queue.getMinimum()).toBeUndefined();
expect(queue.getMaximum()).toBeUndefined();
});
it("inserts one element into queue", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
queue.insert(1);
expect(queue.length).toEqual(1);
expect(queue.internalArray.length).toEqual(1);
expect(queue.getMinimum()).toEqual(1);
expect(queue.getMaximum()).toEqual(1);
});
it("inserts two elements into queue", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
queue.insert(1);
queue.insert(2);
expect(queue.length).toEqual(2);
expect(queue.internalArray.length).toEqual(2);
expect(queue.getMinimum()).toEqual(1);
expect(queue.getMaximum()).toEqual(2);
});
it("inserts three elements into queue", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
queue.insert(1);
queue.insert(2);
queue.insert(3);
expect(queue.length).toEqual(3);
expect(queue.internalArray.length).toEqual(3);
expect(queue.getMinimum()).toEqual(1);
expect(queue.getMaximum()).toEqual(3);
});
it("inserts four elements into queue", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
queue.insert(1);
queue.insert(2);
queue.insert(3);
queue.insert(4);
expect(queue.length).toEqual(4);
expect(queue.internalArray.length).toEqual(4);
expect(queue.getMinimum()).toEqual(1);
expect(queue.getMaximum()).toEqual(4);
});
it("insert removes and returns minimum element when the queue is full", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
maximumLength: 1,
});
var nothing = queue.insert(1);
var removed = queue.insert(2);
expect(queue.length).toEqual(1);
expect(queue.maximumLength).toEqual(1);
expect(queue.internalArray.length).toEqual(1);
expect(queue.getMinimum()).toEqual(2);
expect(queue.getMaximum()).toEqual(2);
expect(nothing).toBeUndefined();
expect(removed).toEqual(1);
});
it("insert returns undefined when new element is less than or equal priority to the minimum element and the queue is full", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: function (a, b) {
return a.value - b.value;
},
maximumLength: 2,
});
var obj1 = { value: 1, id: 0 };
var obj2 = { value: 2, id: 0 };
var obj3 = { value: 1, id: 1 };
var obj4 = { value: 0, id: 1 };
var result1 = queue.insert(obj1);
var result2 = queue.insert(obj2);
var result3 = queue.insert(obj3); // ignored because equal priority to minimum
var result4 = queue.insert(obj4); // ignored because lower priority than minimum
expect(queue.length).toEqual(2);
expect(queue.maximumLength).toEqual(2);
expect(queue.internalArray.length).toEqual(2);
expect(queue.getMinimum().id).toEqual(0);
expect(result1).toBeUndefined();
expect(result2).toBeUndefined();
expect(result3).toEqual(obj3);
expect(result4).toEqual(obj4);
});
it("remove and return minimum element", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
queue.insert(1);
queue.insert(2);
queue.insert(3);
var minimumValue = queue.removeMinimum();
expect(queue.length).toEqual(2);
expect(minimumValue).toEqual(1);
expect(queue.getMinimum()).toEqual(2);
// check that the element was dereferenced
expect(queue.internalArray[2]).toBeUndefined();
});
it("removeMinimum returns undefined when queue is empty", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
var minimumValue = queue.removeMinimum();
expect(minimumValue).toBeUndefined();
});
it("remove and return maximum element", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
queue.insert(1);
queue.insert(2);
queue.insert(3);
var maximumValue = queue.removeMaximum();
expect(queue.length).toEqual(2);
expect(maximumValue).toEqual(3);
expect(queue.getMaximum()).toEqual(2);
// check that the element was dereferenced
expect(queue.internalArray[2]).toBeUndefined();
});
it("removeMaximum returns undefined when queue is empty", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
var maximumValue = queue.removeMaximum();
expect(maximumValue).toBeUndefined();
});
it("clones queue", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
maximumLength: 4,
});
queue.insert(1);
queue.insert(2);
var clone = queue.clone();
expect(clone.length).toEqual(queue.length);
expect(clone.maximumLength).toEqual(queue.maximumLength);
expect(clone.comparator).toEqual(queue.comparator);
expect(clone.getMaximum()).toEqual(queue.getMaximum());
expect(clone.getMinimum()).toEqual(queue.getMinimum());
});
it("resets queue", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
queue.insert(1);
queue.insert(2);
queue.reset();
expect(queue.length).toEqual(0);
expect(queue.getMinimum()).toBeUndefined();
expect(queue.getMaximum()).toBeUndefined();
// check that the elements were dereferenced
expect(queue.internalArray.length).toEqual(0);
});
it("resets queue with maximum length", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
maximumLength: 1,
});
queue.insert(1);
queue.reset();
expect(queue.length).toEqual(0);
expect(queue.getMinimum()).toBeUndefined();
expect(queue.getMaximum()).toBeUndefined();
// check that the element was dereferenced but the array stayed the same size
expect(queue.internalArray.length).toEqual(1);
expect(queue.internalArray[0]).toBeUndefined();
});
it("creates queue with maximum length of zero", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
maximumLength: 0,
});
queue.insert(1);
expect(queue.length).toEqual(0);
expect(queue.maximumLength).toEqual(0);
expect(queue.internalArray.length).toEqual(0);
expect(queue.getMinimum()).toBeUndefined();
expect(queue.getMaximum()).toBeUndefined();
});
it("creates queue with maximum length of one", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
maximumLength: 1,
});
queue.insert(1);
queue.insert(2);
expect(queue.length).toEqual(1);
expect(queue.maximumLength).toEqual(1);
expect(queue.internalArray.length).toEqual(1);
expect(queue.getMinimum()).toEqual(2);
expect(queue.getMaximum()).toEqual(2);
});
it("throws when maximum length is set to less than zero", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
expect(function () {
queue.maximumLength = -1;
}).toThrowDeveloperError();
});
it("sets maximum length to undefined", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
queue.maximumLength = 2;
queue.insert(1);
queue.insert(2);
queue.maximumLength = undefined;
queue.insert(3);
expect(queue.length).toEqual(3);
expect(queue.maximumLength).toBeUndefined();
expect(queue.getMinimum()).toEqual(1);
expect(queue.getMaximum()).toEqual(3);
});
it("sets maximum length to less than current length", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
var maximumLength = 5;
for (var i = 0; i < maximumLength * 2; i++) {
var value = i;
queue.insert(value);
}
queue.maximumLength = maximumLength;
expect(queue.length).toEqual(maximumLength);
expect(queue.maximumLength).toEqual(maximumLength);
expect(queue.internalArray.length).toEqual(maximumLength);
expect(queue.getMinimum()).toEqual(maximumLength);
expect(queue.getMaximum()).toEqual(maximumLength * 2 - 1);
});
function isValidQueue(queue) {
// 1) Remove successive minimum elements from the queue and check if they are sorted correctly
// 2) Remove successive maximum elements from the queue and check if they are sorted correctly
var minArray = [];
var maxArray = [];
var minQueue = queue.clone();
var maxQueue = queue.clone();
while (minQueue.length > 0) {
minArray.push(minQueue.removeMinimum());
}
while (maxQueue.length > 0) {
maxArray.push(maxQueue.removeMaximum());
}
if (minQueue.length !== 0 || maxQueue.length !== 0) {
return false;
}
var i;
for (i = 0; i < minArray.length - 1; i++) {
if (minArray[i] > minArray[i + 1]) {
return false;
}
}
for (i = 0; i < maxArray.length - 1; i++) {
if (maxArray[i] < maxArray[i + 1]) {
return false;
}
}
return true;
}
it("maintains priority with ascending insertions", function () {
var length = 200;
var maximumLength = 100;
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
maximumLength: maximumLength,
});
var pass = true;
for (var i = 0; i < length; ++i) {
var value = i;
queue.insert(value);
pass = pass && isValidQueue(queue);
}
expect(pass).toBe(true);
});
it("maintains priority with descending insertions", function () {
var length = 200;
var maximumLength = 100;
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
maximumLength: maximumLength,
});
var pass = true;
for (var i = 0; i < length; ++i) {
var value = length - 1 - i;
queue.insert(value);
pass = pass && isValidQueue(queue);
}
expect(pass).toBe(true);
});
it("maintains priority with random insertions", function () {
var length = 200;
var maximumLength = 100;
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
maximumLength: maximumLength,
});
var pass = true;
for (var i = 0; i < length; ++i) {
var value = Math.random();
queue.insert(value);
pass = pass && isValidQueue(queue);
}
expect(pass).toBe(true);
});
it("resorts queue", function () {
var queue = new DoubleEndedPriorityQueue({
comparator: comparator,
});
var i;
var length = 200;
for (i = 0; i < length; ++i) {
queue.insert(0);
}
// Change all of the queue values to random values to make it unsorted
var array = queue.internalArray;
for (i = 0; i < length; i++) {
array[i] = Math.random();
}
queue.resort();
var pass = isValidQueue(queue);
expect(pass).toBe(true);
});
});