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