1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkDeque.h" 9 #include "Test.h" 10 11 static void assert_count(skiatest::Reporter* reporter, const SkDeque& deq, int count) { 12 if (0 == count) { 13 REPORTER_ASSERT(reporter, deq.empty()); 14 REPORTER_ASSERT(reporter, 0 == deq.count()); 15 REPORTER_ASSERT(reporter, sizeof(int) == deq.elemSize()); 16 REPORTER_ASSERT(reporter, NULL == deq.front()); 17 REPORTER_ASSERT(reporter, NULL == deq.back()); 18 } else { 19 REPORTER_ASSERT(reporter, !deq.empty()); 20 REPORTER_ASSERT(reporter, count == deq.count()); 21 REPORTER_ASSERT(reporter, sizeof(int) == deq.elemSize()); 22 REPORTER_ASSERT(reporter, deq.front()); 23 REPORTER_ASSERT(reporter, deq.back()); 24 if (1 == count) { 25 REPORTER_ASSERT(reporter, deq.back() == deq.front()); 26 } else { 27 REPORTER_ASSERT(reporter, deq.back() != deq.front()); 28 } 29 } 30 } 31 32 static void assert_iter(skiatest::Reporter* reporter, const SkDeque& deq, 33 int max, int min) { 34 // test forward iteration 35 SkDeque::Iter iter(deq, SkDeque::Iter::kFront_IterStart); 36 void* ptr; 37 38 int value = max; 39 while ((ptr = iter.next())) { 40 REPORTER_ASSERT(reporter, value == *(int*)ptr); 41 value -= 1; 42 } 43 REPORTER_ASSERT(reporter, value+1 == min); 44 45 // test reverse iteration 46 iter.reset(deq, SkDeque::Iter::kBack_IterStart); 47 48 value = min; 49 while ((ptr = iter.prev())) { 50 REPORTER_ASSERT(reporter, value == *(int*)ptr); 51 value += 1; 52 } 53 REPORTER_ASSERT(reporter, value-1 == max); 54 55 // test mixed iteration 56 iter.reset(deq, SkDeque::Iter::kFront_IterStart); 57 58 value = max; 59 // forward iteration half-way 60 for (int i = 0; i < deq.count()/2 && (ptr = iter.next()); i++) { 61 REPORTER_ASSERT(reporter, value == *(int*)ptr); 62 value -= 1; 63 } 64 // then back down w/ reverse iteration 65 while ((ptr = iter.prev())) { 66 REPORTER_ASSERT(reporter, value == *(int*)ptr); 67 value += 1; 68 } 69 REPORTER_ASSERT(reporter, value-1 == max); 70 } 71 72 // This helper is intended to only give the unit test access to SkDeque's 73 // private numBlocksAllocated method 74 class DequeUnitTestHelper { 75 public: 76 int fNumBlocksAllocated; 77 78 DequeUnitTestHelper(const SkDeque& deq) { 79 fNumBlocksAllocated = deq.numBlocksAllocated(); 80 } 81 }; 82 83 static void assert_blocks(skiatest::Reporter* reporter, 84 const SkDeque& deq, 85 int allocCount) { 86 DequeUnitTestHelper helper(deq); 87 88 if (0 == deq.count()) { 89 REPORTER_ASSERT(reporter, 1 == helper.fNumBlocksAllocated); 90 } else { 91 int expected = (deq.count() + allocCount - 1) / allocCount; 92 // A block isn't freed in the deque when it first becomes empty so 93 // sometimes an extra block lingers around 94 REPORTER_ASSERT(reporter, 95 expected == helper.fNumBlocksAllocated || 96 expected+1 == helper.fNumBlocksAllocated); 97 } 98 } 99 100 static void TestSub(skiatest::Reporter* reporter, int allocCount) { 101 SkDeque deq(sizeof(int), allocCount); 102 int i; 103 104 // test pushing on the front 105 106 assert_count(reporter, deq, 0); 107 for (i = 1; i <= 10; i++) { 108 *(int*)deq.push_front() = i; 109 } 110 assert_count(reporter, deq, 10); 111 assert_iter(reporter, deq, 10, 1); 112 assert_blocks(reporter, deq, allocCount); 113 114 for (i = 0; i < 5; i++) { 115 deq.pop_front(); 116 } 117 assert_count(reporter, deq, 5); 118 assert_iter(reporter, deq, 5, 1); 119 assert_blocks(reporter, deq, allocCount); 120 121 for (i = 0; i < 5; i++) { 122 deq.pop_front(); 123 } 124 assert_count(reporter, deq, 0); 125 assert_blocks(reporter, deq, allocCount); 126 127 // now test pushing on the back 128 129 for (i = 10; i >= 1; --i) { 130 *(int*)deq.push_back() = i; 131 } 132 assert_count(reporter, deq, 10); 133 assert_iter(reporter, deq, 10, 1); 134 assert_blocks(reporter, deq, allocCount); 135 136 for (i = 0; i < 5; i++) { 137 deq.pop_back(); 138 } 139 assert_count(reporter, deq, 5); 140 assert_iter(reporter, deq, 10, 6); 141 assert_blocks(reporter, deq, allocCount); 142 143 for (i = 0; i < 5; i++) { 144 deq.pop_back(); 145 } 146 assert_count(reporter, deq, 0); 147 assert_blocks(reporter, deq, allocCount); 148 149 // now test pushing/popping on both ends 150 151 *(int*)deq.push_front() = 5; 152 *(int*)deq.push_back() = 4; 153 *(int*)deq.push_front() = 6; 154 *(int*)deq.push_back() = 3; 155 *(int*)deq.push_front() = 7; 156 *(int*)deq.push_back() = 2; 157 *(int*)deq.push_front() = 8; 158 *(int*)deq.push_back() = 1; 159 assert_count(reporter, deq, 8); 160 assert_iter(reporter, deq, 8, 1); 161 assert_blocks(reporter, deq, allocCount); 162 } 163 164 DEF_TEST(Deque, reporter) { 165 // test it once with the default allocation count 166 TestSub(reporter, 1); 167 // test it again with a generous allocation count 168 TestSub(reporter, 10); 169 } 170