| Index: tests/TDPQueueTest.cpp
|
| diff --git a/tests/TDPQueueTest.cpp b/tests/TDPQueueTest.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..70367a7b828c3cb061202e3fc1d89784b4fa445e
|
| --- /dev/null
|
| +++ b/tests/TDPQueueTest.cpp
|
| @@ -0,0 +1,156 @@
|
| +/*
|
| + * Copyright 2015 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SkTDPQueue.h"
|
| +#include "SkRandom.h"
|
| +#include "Test.h"
|
| +
|
| +namespace { bool intless(const int& a, const int& b) { return a < b; } }
|
| +
|
| +static void simple_test(skiatest::Reporter* reporter) {
|
| + SkTDPQueue<int, intless> heap;
|
| + REPORTER_ASSERT(reporter, 0 == heap.count());
|
| +
|
| + heap.insert(0);
|
| + REPORTER_ASSERT(reporter, 1 == heap.count());
|
| + REPORTER_ASSERT(reporter, 0 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 0 == heap.count());
|
| +
|
| + heap.insert(0);
|
| + heap.insert(1);
|
| + REPORTER_ASSERT(reporter, 2 == heap.count());
|
| + REPORTER_ASSERT(reporter, 0 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 1 == heap.count());
|
| + REPORTER_ASSERT(reporter, 1 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 0 == heap.count());
|
| +
|
| + heap.insert(2);
|
| + heap.insert(1);
|
| + heap.insert(0);
|
| + REPORTER_ASSERT(reporter, 3 == heap.count());
|
| + REPORTER_ASSERT(reporter, 0 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 2 == heap.count());
|
| + REPORTER_ASSERT(reporter, 1 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 1 == heap.count());
|
| + REPORTER_ASSERT(reporter, 2 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 0 == heap.count());
|
| +
|
| + heap.insert(2);
|
| + heap.insert(3);
|
| + heap.insert(0);
|
| + heap.insert(1);
|
| + REPORTER_ASSERT(reporter, 4 == heap.count());
|
| + REPORTER_ASSERT(reporter, 0 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 3 == heap.count());
|
| + REPORTER_ASSERT(reporter, 1 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 2 == heap.count());
|
| + REPORTER_ASSERT(reporter, 2 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 1 == heap.count());
|
| + REPORTER_ASSERT(reporter, 3 == heap.peek());
|
| + heap.pop();
|
| + REPORTER_ASSERT(reporter, 0 == heap.count());
|
| +}
|
| +
|
| +struct Dummy {
|
| + int fValue;
|
| + int fPriority;
|
| + mutable int fIndex;
|
| +
|
| + static bool LessP(Dummy* const& a, Dummy* const& b) { return a->fPriority < b->fPriority; }
|
| + static int* PQIndex(Dummy* const& dummy) { return &dummy->fIndex; }
|
| +
|
| + bool operator== (const Dummy& that) const {
|
| + return fValue == that.fValue && fPriority == that.fPriority;
|
| + }
|
| + bool operator!= (const Dummy& that) const { return !(*this == that); }
|
| +};
|
| +
|
| +void random_test(skiatest::Reporter* reporter) {
|
| + SkRandom random;
|
| + static const Dummy kSentinel = {-1, -1, -1};
|
| +
|
| + for (int i = 0; i < 100; ++i) {
|
| + // Create a random set of Dummy objects.
|
| + int count = random.nextULessThan(100);
|
| + SkTDArray<Dummy> array;
|
| + array.setReserve(count);
|
| + for (int j = 0; j < count; ++j) {
|
| + Dummy* dummy = array.append();
|
| + dummy->fPriority = random.nextS();
|
| + dummy->fValue = random.nextS();
|
| + dummy->fIndex = -1;
|
| + if (*dummy == kSentinel) {
|
| + array.pop();
|
| + --j;
|
| + }
|
| + }
|
| +
|
| + // Stick the dummy objects in the pqueue.
|
| + SkTDPQueue<Dummy*, Dummy::LessP, Dummy::PQIndex> pq;
|
| + for (int j = 0; j < count; ++j) {
|
| + pq.insert(&array[j]);
|
| + }
|
| + REPORTER_ASSERT(reporter, pq.count() == array.count());
|
| + for (int j = 0; j < count; ++j) {
|
| + // every item should have an entry in the queue.
|
| + REPORTER_ASSERT(reporter, -1 != array[j].fIndex);
|
| + }
|
| +
|
| + // Begin the test.
|
| + while (pq.count()) {
|
| + // Make sure the top of the queue is really the highest priority.
|
| + Dummy* top = pq.peek();
|
| + for (int k = 0; k < count; ++k) {
|
| + REPORTER_ASSERT(reporter, kSentinel == array[k] ||
|
| + array[k].fPriority >= top->fPriority);
|
| + }
|
| + // Do one of three random actions:
|
| + unsigned action = random.nextULessThan(3);
|
| + switch (action) {
|
| + case 0: { // pop the top,
|
| + Dummy* top = pq.peek();
|
| + REPORTER_ASSERT(reporter, array.begin() <= top && top < array.end());
|
| + pq.pop();
|
| + *top = kSentinel;
|
| + break;
|
| + }
|
| + case 1: { // remove a random element,
|
| + int item;
|
| + do {
|
| + item = random.nextULessThan(count);
|
| + } while (array[item] == kSentinel);
|
| + pq.remove(&array[item]);
|
| + array[item] = kSentinel;
|
| + break;
|
| + }
|
| + case 2: { // or change an element's priority.
|
| + int item;
|
| + do {
|
| + item = random.nextULessThan(count);
|
| + } while (array[item] == kSentinel);
|
| + array[item].fPriority = random.nextS();
|
| + pq.priorityDidChange(&array[item]);
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +DEF_TEST(TDPQueueTest, reporter) {
|
| + simple_test(reporter);
|
| + random_test(reporter);
|
| +}
|
|
|