17d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com/*
27d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com * Copyright 2013 Google Inc.
37d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *
47d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com * Use of this source code is governed by a BSD-style license that can be
57d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com * found in the LICENSE file.
67d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com */
77d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
87d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com#include "SkTDStackNester.h"
97d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
107d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com#include "Test.h"
117d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
127d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com/**
137d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *  Test SkTDStackNester<int>::push(). Pushes the current count onto the stack,
147d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *  and checks that the count has increased by one.
157d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com */
167d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.comstatic void test_push(skiatest::Reporter* reporter, SkTDStackNester<int>* nester) {
177d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    SkASSERT(nester);
187d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    const int count = nester->count();
197d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    // test_pop depends on this value.
207d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    nester->push(count);
217d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, nester->count() == count + 1);
227d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com}
237d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
247d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com/**
257d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *  Test SkTDStackNester<int>::pop(). Pops the top element off the stack, and
267d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *  checks that the new count is one smaller, and that the popped element
277d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *  matches the new count (as was pushed by test_push).
287d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com */
297d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.comstatic void test_pop(skiatest::Reporter* reporter, SkTDStackNester<int>* nester) {
307d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    SkASSERT(nester);
317d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    const int count = nester->count();
327d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    // This test should not be called with a count <= 0.
337d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    SkASSERT(count > 0);
347d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    const int top = nester->top();
357d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    int value = -1;
367d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    nester->pop(&value);
377d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, top == value);
387d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    const int newCount = nester->count();
397d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, newCount == count - 1);
407d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    // Since test_push always pushes the count prior to the push, value should
417d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    // always be one less than count.
427d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, newCount == value);
437d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com}
447d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
457d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com/**
467d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *  Test nest() and unnest(). nest() is called, and it is confirmed that the
477d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *  count is now zero. Then test_push() is called inc times, followed by a call to
487d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *  unnest(). After this call, check that the count has returned to the initial count, and
497d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com *  that nestingLevel() has returned to its initial value.
507d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com */
517d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.comstatic void test_nest(skiatest::Reporter* reporter, SkTDStackNester<int>* nester, int inc) {
527d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    SkASSERT(nester);
537d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    SkASSERT(inc > 0);
547d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    const int initialCount = nester->count();
557d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    const int initialNesting = nester->nestingLevel();
567d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
577d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    nester->nest();
587d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, nester->count() == 0);
597d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, nester->nestingLevel() == initialNesting + 1);
607d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
617d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    for (int i = 0; i < inc; ++i) {
627d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com        test_push(reporter, nester);
637d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    }
647d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
657d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    nester->unnest();
667d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, nester->count() == initialCount);
677d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, nester->nestingLevel() == initialNesting);
687d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com}
697d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
707d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.comclass SkTDStackNesterTester {
717d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.compublic:
727d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    static int GetSlotCount() {
737d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com        return SkTDStackNester<int>::kSlotCount;
747d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    }
757d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com};
767d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
777d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.comstatic void test_stack_nester(skiatest::Reporter* reporter) {
787d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    SkTDStackNester<int> nester;
797d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    int count = nester.count();
807d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, 0 == count);
817d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, nester.nestingLevel() == 0);
827d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    REPORTER_ASSERT(reporter, nester.empty());
837d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
847d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    // Test nesting (with arbitrary number of pushes) from the beginning.
857d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    test_nest(reporter, &nester, 3);
867d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
877d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    const int slotCount = SkTDStackNesterTester::GetSlotCount();
887d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
897d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    // Test pushing beyond the boundary of the first Rec.
907d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    for (; count < 2 * slotCount; ++count) {
917d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com        if (3 == count) {
927d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com            // Test nesting (an arbitrary number of pushes) early on.
937d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com            test_nest(reporter, &nester, 7);
947d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com        } else if (slotCount - 4 == count) {
957d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com            // Test nesting across the boundary of a Rec.
967d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com            test_nest(reporter, &nester, 6);
977d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com        }
987d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com        test_push(reporter, &nester);
997d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    }
1007d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
1017d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    // Pop everything off the stack except for the last one, to confirm
1027d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    // that the destructor handles a remaining object.
1037d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    while (nester.count() > 1) {
1047d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com        test_pop(reporter, &nester);
1057d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    }
1067d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com}
1077d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com
1087d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.comDEF_TEST(TDStackNester, reporter) {
1097d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com    test_stack_nester(reporter);
1107d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com}
111