summaryrefslogtreecommitdiff
path: root/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp')
-rw-r--r--Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp b/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp
new file mode 100644
index 000000000..4c0a14b47
--- /dev/null
+++ b/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <wtf/Ref.h>
+#include <wtf/RefCounter.h>
+#include <wtf/text/WTFString.h>
+
+namespace TestWebKitAPI {
+
+static const int IncrementExpected = 0xC0FFEE1;
+static const int DecrementExpected = 0xC0FFEE2;
+static const int CallbackNotExpected = 0xDECAF;
+
+enum TestCounterType { };
+typedef RefCounter<TestCounterType> TestCounter;
+typedef TestCounter::Token TokenType;
+
+TEST(WTF, RefCounter)
+{
+ // RefCounter API is pretty simple, containing the following 4 methods to test:
+ //
+ // 1) RefCounter(std::function<void()>);
+ // 2) ~RefCounter();
+ // 3) Ref<Count> token() const;
+ // 4) unsigned value() const;
+ //
+ // We'll test:
+ // 1) Construction:
+ // 1a) with a callback
+ // 1b) without a callback
+ // 2) Destruction where the RefCounter::Count has:
+ // 2a) a non-zero reference count (Count outlives RefCounter).
+ // 2b) a zero reference count (Count is deleted by RefCounter's destructor).
+ // 3) Call count to ref/deref the Count object, where:
+ // 3a) ref with callback from 0 -> 1.
+ // 3b) ref with callback from 1 -> >1.
+ // 3c) deref with callback from >1 -> 1.
+ // 3d) deref with callback from 1 -> 0.
+ // 3d) deref with callback from 1 -> 0.
+ // 3e) ref with callback from 1 -> >1 AFTER RefCounter has been destroyed.
+ // 3f) deref with callback from >1 -> 1 AFTER RefCounter has been destroyed.
+ // 3g) deref with callback from 1 -> 0 AFTER RefCounter has been destroyed.
+ // 3h) ref without callback
+ // 3i) deref without callback
+ // 3j) ref using a Ref rather than a RefPtr (make sure there is no unnecessary reference count churn).
+ // 3k) deref using a Ref rather than a RefPtr (make sure there is no unnecessary reference count churn).
+ // 4) Test the value of the counter:
+ // 4a) at construction.
+ // 4b) as read within the callback.
+ // 4c) as read after the ref/deref.
+
+ // These values will outlive the following block.
+ int callbackValue = CallbackNotExpected;
+ TokenType incTo1Again;
+
+ {
+ // Testing (1a) - Construction with a callback.
+ TestCounter* counterPtr = nullptr;
+ TestCounter counter([&](RefCounterEvent event) {
+ // Check that the callback is called at the expected times, and the correct number of times.
+ if (RefCounterEvent::Increment == event)
+ EXPECT_EQ(callbackValue, IncrementExpected);
+ if (RefCounterEvent::Decrement == event)
+ EXPECT_EQ(callbackValue, DecrementExpected);
+ // return the value of the counter in the callback.
+ callbackValue = counterPtr->value();
+ });
+ counterPtr = &counter;
+ // Testing (4a) - after construction value() is 0.
+ EXPECT_EQ(0, static_cast<int>(counter.value()));
+
+ // Testing (3a) - ref with callback from 0 -> 1.
+ callbackValue = IncrementExpected;
+ TokenType incTo1(counter.count());
+ // Testing (4b) & (4c) - values within & after callback.
+ EXPECT_EQ(1, callbackValue);
+ EXPECT_EQ(1, static_cast<int>(counter.value()));
+
+ // Testing (3b) - ref with callback from 1 -> 2.
+ callbackValue = IncrementExpected;
+ TokenType incTo2(incTo1);
+ // Testing (4b) & (4c) - values within & after callback.
+ EXPECT_EQ(2, callbackValue);
+ EXPECT_EQ(2, static_cast<int>(counter.value()));
+
+ // Testing (3c) - deref with callback from >1 -> 1.
+ callbackValue = DecrementExpected;
+ incTo1 = nullptr;
+ // Testing (4b) & (4c) - values within & after callback.
+ EXPECT_EQ(1, callbackValue);
+ EXPECT_EQ(1, static_cast<int>(counter.value()));
+
+ {
+ // Testing (3j) - ref using a Ref rather than a RefPtr.
+ callbackValue = IncrementExpected;
+ TokenType incTo2Again(counter.count());
+ // Testing (4b) & (4c) - values within & after callback.
+ EXPECT_EQ(2, callbackValue);
+ EXPECT_EQ(2, static_cast<int>(counter.value()));
+ // Testing (3k) - deref using a Ref rather than a RefPtr.
+
+ callbackValue = DecrementExpected;
+ }
+ EXPECT_EQ(1, callbackValue);
+ EXPECT_EQ(1, static_cast<int>(counter.value()));
+ // Testing (4b) & (4c) - values within & after callback.
+
+ // Testing (3d) - deref with callback from 1 -> 0.
+ callbackValue = DecrementExpected;
+ incTo2 = nullptr;
+ // Testing (4b) & (4c) - values within & after callback.
+ EXPECT_EQ(0, callbackValue);
+ EXPECT_EQ(0, static_cast<int>(counter.value()));
+
+ // Testing (2a) - Destruction where the TestCounter::Count has a non-zero reference count.
+ callbackValue = IncrementExpected;
+ incTo1Again = counter.count();
+ EXPECT_EQ(1, callbackValue);
+ EXPECT_EQ(1, static_cast<int>(counter.value()));
+ callbackValue = CallbackNotExpected;
+ }
+
+ // Testing (3e) - ref with callback from 1 -> >1 AFTER RefCounter has been destroyed.
+ TokenType incTo2Again = incTo1Again;
+ // Testing (3f) - deref with callback from >1 -> 1 AFTER RefCounter has been destroyed.
+ incTo1Again = nullptr;
+ // Testing (3g) - deref with callback from 1 -> 0 AFTER RefCounter has been destroyed.
+ incTo2Again = nullptr;
+
+ // Testing (1b) - Construction without a callback.
+ TestCounter counter;
+ // Testing (4a) - after construction value() is 0.
+ EXPECT_EQ(0, static_cast<int>(counter.value()));
+ // Testing (3h) - ref without callback
+ TokenType incTo1(counter.count());
+ // Testing (4c) - value as read after the ref.
+ EXPECT_EQ(1, static_cast<int>(counter.value()));
+ // Testing (3i) - deref without callback
+ incTo1 = nullptr;
+ // Testing (4c) - value as read after the deref.
+ EXPECT_EQ(0, static_cast<int>(counter.value()));
+ // Testing (2b) - Destruction where the RefCounter::Count has a zero reference count.
+ // ... not a lot to test here! - we can at least ensure this code path is run & we don't crash!
+}
+
+} // namespace TestWebKitAPI