1 /* 2 * Copyright 2013 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 "SkTDStackNester.h" 9 10 #include "Test.h" 11 12 /** 13 * Test SkTDStackNester<int>::push(). Pushes the current count onto the stack, 14 * and checks that the count has increased by one. 15 */ 16 static void test_push(skiatest::Reporter* reporter, SkTDStackNester<int>* nester) { 17 SkASSERT(nester); 18 const int count = nester->count(); 19 // test_pop depends on this value. 20 nester->push(count); 21 REPORTER_ASSERT(reporter, nester->count() == count + 1); 22 } 23 24 /** 25 * Test SkTDStackNester<int>::pop(). Pops the top element off the stack, and 26 * checks that the new count is one smaller, and that the popped element 27 * matches the new count (as was pushed by test_push). 28 */ 29 static void test_pop(skiatest::Reporter* reporter, SkTDStackNester<int>* nester) { 30 SkASSERT(nester); 31 const int count = nester->count(); 32 // This test should not be called with a count <= 0. 33 SkASSERT(count > 0); 34 const int top = nester->top(); 35 int value = -1; 36 nester->pop(&value); 37 REPORTER_ASSERT(reporter, top == value); 38 const int newCount = nester->count(); 39 REPORTER_ASSERT(reporter, newCount == count - 1); 40 // Since test_push always pushes the count prior to the push, value should 41 // always be one less than count. 42 REPORTER_ASSERT(reporter, newCount == value); 43 } 44 45 /** 46 * Test nest() and unnest(). nest() is called, and it is confirmed that the 47 * count is now zero. Then test_push() is called inc times, followed by a call to 48 * unnest(). After this call, check that the count has returned to the initial count, and 49 * that nestingLevel() has returned to its initial value. 50 */ 51 static void test_nest(skiatest::Reporter* reporter, SkTDStackNester<int>* nester, int inc) { 52 SkASSERT(nester); 53 SkASSERT(inc > 0); 54 const int initialCount = nester->count(); 55 const int initialNesting = nester->nestingLevel(); 56 57 nester->nest(); 58 REPORTER_ASSERT(reporter, nester->count() == 0); 59 REPORTER_ASSERT(reporter, nester->nestingLevel() == initialNesting + 1); 60 61 for (int i = 0; i < inc; ++i) { 62 test_push(reporter, nester); 63 } 64 65 nester->unnest(); 66 REPORTER_ASSERT(reporter, nester->count() == initialCount); 67 REPORTER_ASSERT(reporter, nester->nestingLevel() == initialNesting); 68 } 69 70 class SkTDStackNesterTester { 71 public: 72 static int GetSlotCount() { 73 return SkTDStackNester<int>::kSlotCount; 74 } 75 }; 76 77 static void test_stack_nester(skiatest::Reporter* reporter) { 78 SkTDStackNester<int> nester; 79 int count = nester.count(); 80 REPORTER_ASSERT(reporter, 0 == count); 81 REPORTER_ASSERT(reporter, nester.nestingLevel() == 0); 82 REPORTER_ASSERT(reporter, nester.empty()); 83 84 // Test nesting (with arbitrary number of pushes) from the beginning. 85 test_nest(reporter, &nester, 3); 86 87 const int slotCount = SkTDStackNesterTester::GetSlotCount(); 88 89 // Test pushing beyond the boundary of the first Rec. 90 for (; count < 2 * slotCount; ++count) { 91 if (3 == count) { 92 // Test nesting (an arbitrary number of pushes) early on. 93 test_nest(reporter, &nester, 7); 94 } else if (slotCount - 4 == count) { 95 // Test nesting across the boundary of a Rec. 96 test_nest(reporter, &nester, 6); 97 } 98 test_push(reporter, &nester); 99 } 100 101 // Pop everything off the stack except for the last one, to confirm 102 // that the destructor handles a remaining object. 103 while (nester.count() > 1) { 104 test_pop(reporter, &nester); 105 } 106 } 107 108 DEF_TEST(TDStackNester, reporter) { 109 test_stack_nester(reporter); 110 } 111