summaryrefslogtreecommitdiff
path: root/Tools/TestWebKitAPI
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-10-17 16:21:14 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-10-17 16:21:14 +0200
commit8995b83bcbfbb68245f779b64e5517627c6cc6ea (patch)
tree17985605dab9263cc2444bd4d45f189e142cca7c /Tools/TestWebKitAPI
parentb9c9652036d5e9f1e29c574f40bc73a35c81ace6 (diff)
downloadqtwebkit-8995b83bcbfbb68245f779b64e5517627c6cc6ea.tar.gz
Imported WebKit commit cf4f8fc6f19b0629f51860cb2d4b25e139d07e00 (http://svn.webkit.org/repository/webkit/trunk@131592)
New snapshot that includes the build fixes for Mac OS X 10.6 and earlier as well as the previously cherry-picked changes
Diffstat (limited to 'Tools/TestWebKitAPI')
-rw-r--r--Tools/TestWebKitAPI/CMakeLists.txt1
-rw-r--r--Tools/TestWebKitAPI/GNUmakefile.am1
-rw-r--r--Tools/TestWebKitAPI/PlatformEfl.cmake1
-rw-r--r--Tools/TestWebKitAPI/TestWebKitAPI.gypi1
-rw-r--r--Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj8
-rw-r--r--Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp32
-rw-r--r--Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp738
-rw-r--r--Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp4
-rw-r--r--Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp4
-rw-r--r--Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp4
-rw-r--r--Tools/TestWebKitAPI/Tests/WebKit2/WKURL.cpp43
-rw-r--r--Tools/TestWebKitAPI/Tests/WebKit2ObjC/UserContentTest.mm263
12 files changed, 1096 insertions, 4 deletions
diff --git a/Tools/TestWebKitAPI/CMakeLists.txt b/Tools/TestWebKitAPI/CMakeLists.txt
index a23c0d105..c4e427e1d 100644
--- a/Tools/TestWebKitAPI/CMakeLists.txt
+++ b/Tools/TestWebKitAPI/CMakeLists.txt
@@ -74,6 +74,7 @@ ADD_EXECUTABLE(test_wtf
${TESTWEBKITAPI_DIR}/Tests/WTF/IntegerToStringConversion.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/MathExtras.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/MetaAllocator.cpp
+ ${TESTWEBKITAPI_DIR}/Tests/WTF/MemoryInstrumentationTest.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/RedBlackTree.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/SaturatedArithmeticOperations.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/StringBuilder.cpp
diff --git a/Tools/TestWebKitAPI/GNUmakefile.am b/Tools/TestWebKitAPI/GNUmakefile.am
index 8e2f19674..d294d0629 100644
--- a/Tools/TestWebKitAPI/GNUmakefile.am
+++ b/Tools/TestWebKitAPI/GNUmakefile.am
@@ -58,6 +58,7 @@ Programs_TestWebKitAPI_TestWTF_SOURCES = \
Tools/TestWebKitAPI/Tests/WTF/IntegerToStringConversion.cpp \
Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp \
Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp \
+ Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp \
Tools/TestWebKitAPI/Tests/WTF/RedBlackTree.cpp \
Tools/TestWebKitAPI/Tests/WTF/SaturatedArithmeticOperations.cpp \
Tools/TestWebKitAPI/Tests/WTF/StringBuilder.cpp \
diff --git a/Tools/TestWebKitAPI/PlatformEfl.cmake b/Tools/TestWebKitAPI/PlatformEfl.cmake
index 968a61983..7defb1138 100644
--- a/Tools/TestWebKitAPI/PlatformEfl.cmake
+++ b/Tools/TestWebKitAPI/PlatformEfl.cmake
@@ -66,6 +66,7 @@ SET(test_webkit2_api_BINARIES
WKConnection
WKString
WKStringJSString
+ WKURL
WillSendSubmitEvent
)
diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.gypi b/Tools/TestWebKitAPI/TestWebKitAPI.gypi
index 924dc1278..2c07940c8 100644
--- a/Tools/TestWebKitAPI/TestWebKitAPI.gypi
+++ b/Tools/TestWebKitAPI/TestWebKitAPI.gypi
@@ -38,6 +38,7 @@
'Tests/WTF/HashMap.cpp',
'Tests/WTF/MathExtras.cpp',
'Tests/WTF/MediaTime.cpp',
+ 'Tests/WTF/MemoryInstrumentationTest.cpp',
'Tests/WTF/RedBlackTree.cpp',
'Tests/WTF/SaturatedArithmeticOperations.cpp',
'Tests/WTF/StringBuilder.cpp',
diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
index e144f5f37..77eee845d 100644
--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
@@ -31,6 +31,7 @@
26DF5A6315A2A27E003689C2 /* CancelLoadFromResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 26DF5A6115A2A22B003689C2 /* CancelLoadFromResourceLoadDelegate.html */; };
26F1B44415CA434F00D1E4BF /* AtomicString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F1B44215CA434F00D1E4BF /* AtomicString.cpp */; };
26F1B44515CA434F00D1E4BF /* StringImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F1B44315CA434F00D1E4BF /* StringImpl.cpp */; };
+ 2943BE86161DFEB800999E3D /* UserContentTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2943BE84161DFEB800999E3D /* UserContentTest.mm */; };
333B9CE21277F23100FEFCE3 /* PreventEmptyUserAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */; };
33BE5AF5137B5A6C00705813 /* MouseMoveAfterCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BE5AF4137B5A6C00705813 /* MouseMoveAfterCrash.cpp */; };
33BE5AF9137B5AAE00705813 /* MouseMoveAfterCrash_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33BE5AF8137B5AAE00705813 /* MouseMoveAfterCrash_Bundle.cpp */; };
@@ -50,6 +51,7 @@
440A1D3914A0103A008A66F2 /* KURL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 440A1D3814A0103A008A66F2 /* KURL.cpp */; };
4BFDFFA71314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDFFA61314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp */; };
4BFDFFA9131477770061F24B /* HitTestResultNodeHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDFFA8131477770061F24B /* HitTestResultNodeHandle.cpp */; };
+ 4F4D2C0E1626FE2700320FE1 /* MemoryInstrumentationTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4D2C0D1626FE2700320FE1 /* MemoryInstrumentationTest.cpp */; };
51393E201523944A005F39C5 /* DOMWindowExtensionBasic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51393E1E1523944A005F39C5 /* DOMWindowExtensionBasic.cpp */; };
51393E221523952D005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51393E1D1523944A005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp */; };
5142B2711517C88B00C32B19 /* ContextMenuCanCopyURL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5142B2701517C88B00C32B19 /* ContextMenuCanCopyURL.mm */; };
@@ -266,6 +268,7 @@
26DF5A6115A2A22B003689C2 /* CancelLoadFromResourceLoadDelegate.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = CancelLoadFromResourceLoadDelegate.html; sourceTree = "<group>"; };
26F1B44215CA434F00D1E4BF /* AtomicString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AtomicString.cpp; path = WTF/AtomicString.cpp; sourceTree = "<group>"; };
26F1B44315CA434F00D1E4BF /* StringImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringImpl.cpp; path = WTF/StringImpl.cpp; sourceTree = "<group>"; };
+ 2943BE84161DFEB800999E3D /* UserContentTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = UserContentTest.mm; path = WebKit2ObjC/UserContentTest.mm; sourceTree = "<group>"; };
333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreventEmptyUserAgent.cpp; sourceTree = "<group>"; };
33BE5AF4137B5A6C00705813 /* MouseMoveAfterCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseMoveAfterCrash.cpp; sourceTree = "<group>"; };
33BE5AF8137B5AAE00705813 /* MouseMoveAfterCrash_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseMoveAfterCrash_Bundle.cpp; sourceTree = "<group>"; };
@@ -286,6 +289,7 @@
44A622C114A0E2B60048515B /* WTFStringUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFStringUtilities.h; sourceTree = "<group>"; };
4BFDFFA61314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HitTestResultNodeHandle_Bundle.cpp; sourceTree = "<group>"; };
4BFDFFA8131477770061F24B /* HitTestResultNodeHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HitTestResultNodeHandle.cpp; sourceTree = "<group>"; };
+ 4F4D2C0D1626FE2700320FE1 /* MemoryInstrumentationTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemoryInstrumentationTest.cpp; path = WTF/MemoryInstrumentationTest.cpp; sourceTree = "<group>"; };
51393E1D1523944A005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMWindowExtensionBasic_Bundle.cpp; sourceTree = "<group>"; };
51393E1E1523944A005F39C5 /* DOMWindowExtensionBasic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMWindowExtensionBasic.cpp; sourceTree = "<group>"; };
5142B2701517C88B00C32B19 /* ContextMenuCanCopyURL.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContextMenuCanCopyURL.mm; sourceTree = "<group>"; };
@@ -529,6 +533,7 @@
BC3C4C6F14575B1D0025FB62 /* WebKit2 Objective-C */ = {
isa = PBXGroup;
children = (
+ 2943BE84161DFEB800999E3D /* UserContentTest.mm */,
BC3C4C7D14587AA60025FB62 /* WKBrowsingContextGroupTest.mm */,
BC3C4C7014575B6A0025FB62 /* WKBrowsingContextLoadDelegateTest.mm */,
);
@@ -639,6 +644,7 @@
26F1B44215CA434F00D1E4BF /* AtomicString.cpp */,
26A2C72E15E2E73C005B1A14 /* CString.cpp */,
CD5497B315857F0C00B5BC30 /* MediaTime.cpp */,
+ 4F4D2C0D1626FE2700320FE1 /* MemoryInstrumentationTest.cpp */,
0FC6C4CE141034AD005B7F0C /* MetaAllocator.cpp */,
0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */,
A7A966DA140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp */,
@@ -987,6 +993,8 @@
BC9099941256ACF100083756 /* WKStringJSString.cpp in Sources */,
265AF55015D1E48A00B0CB4A /* WTFString.cpp in Sources */,
9318778915EEC57700A9CCE3 /* NewFirstVisuallyNonEmptyLayoutForImages.cpp in Sources */,
+ 2943BE86161DFEB800999E3D /* UserContentTest.mm in Sources */,
+ 4F4D2C0E1626FE2700320FE1 /* MemoryInstrumentationTest.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp b/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp
index b9f4c1fdd..db6ca814f 100644
--- a/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp
+++ b/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp
@@ -49,4 +49,36 @@ TEST(WTF, HashTableIteratorComparison)
ASSERT_FALSE(map.end() == begin);
}
+struct TestDoubleHashTraits : HashTraits<double> {
+ static const int minimumTableSize = 8;
+};
+
+typedef HashMap<double, int64_t, DefaultHash<double>::Hash, TestDoubleHashTraits> DoubleHashMap;
+
+static int bucketForKey(double key)
+{
+ return DefaultHash<double>::Hash::hash(key) & (TestDoubleHashTraits::minimumTableSize - 1);
+}
+
+TEST(WTF, DoubleHashCollisions)
+{
+ // The "clobber" key here is one that ends up stealing the bucket that the -0 key
+ // originally wants to be in. This makes the 0 and -0 keys collide and the test then
+ // fails unless the FloatHash::equals() implementation can distinguish them.
+ const double clobberKey = 6;
+ const double zeroKey = 0;
+ const double negativeZeroKey = -zeroKey;
+
+ DoubleHashMap map;
+
+ map.add(clobberKey, 1);
+ map.add(zeroKey, 2);
+ map.add(negativeZeroKey, 3);
+
+ ASSERT_EQ(bucketForKey(clobberKey), bucketForKey(negativeZeroKey));
+ ASSERT_EQ(map.get(clobberKey), 1);
+ ASSERT_EQ(map.get(zeroKey), 2);
+ ASSERT_EQ(map.get(negativeZeroKey), 3);
+}
+
} // namespace TestWebKitAPI
diff --git a/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp b/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp
new file mode 100644
index 000000000..7847d7d26
--- /dev/null
+++ b/Tools/TestWebKitAPI/Tests/WTF/MemoryInstrumentationTest.cpp
@@ -0,0 +1,738 @@
+/*
+ * Copyright (C) 2012 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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 <gtest/gtest.h>
+
+#include <wtf/ArrayBuffer.h>
+#include <wtf/HashCountedSet.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/MemoryInstrumentation.h>
+#include <wtf/MemoryInstrumentationArrayBufferView.h>
+#include <wtf/MemoryInstrumentationHashCountedSet.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
+#include <wtf/MemoryInstrumentationHashSet.h>
+#include <wtf/MemoryInstrumentationString.h>
+#include <wtf/MemoryInstrumentationVector.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuffer.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/StringImpl.h>
+#include <wtf/text/WTFString.h>
+
+namespace {
+enum TestEnum { ONE = 1, TWO, THREE, MY_ENUM_MAX };
+}
+
+namespace WTF {
+
+template<> struct DefaultHash<TestEnum> {
+ typedef IntHash<unsigned> Hash;
+};
+
+template<> struct HashTraits<TestEnum> : GenericHashTraits<TestEnum> {
+ static const bool emptyValueIsZero = true;
+ static const bool needsDestruction = false;
+ static void constructDeletedValue(TestEnum& slot) { slot = static_cast<TestEnum>(MY_ENUM_MAX + 1); }
+ static bool isDeletedValue(TestEnum value) { return value == (MY_ENUM_MAX + 1); }
+};
+
+}
+
+namespace {
+
+using WTF::MemoryObjectInfo;
+using WTF::MemoryClassInfo;
+using WTF::MemoryObjectType;
+
+MemoryObjectType TestType = "TestType";
+
+class InstrumentationTestHelper : public WTF::MemoryInstrumentation {
+public:
+ InstrumentationTestHelper()
+ : MemoryInstrumentation(&m_client)
+ { }
+
+ virtual void processDeferredInstrumentedPointers();
+ virtual void deferInstrumentedPointer(PassOwnPtr<InstrumentedPointerBase>);
+
+ size_t visitedObjects() const { return m_client.visitedObjects(); }
+ size_t reportedSizeForAllTypes() const { return m_client.reportedSizeForAllTypes(); }
+ size_t totalSize(const MemoryObjectType objectType) const { return m_client.totalSize(objectType); }
+
+private:
+ class Client : public WTF::MemoryInstrumentationClient {
+ public:
+ virtual void countObjectSize(MemoryObjectType objectType, size_t size)
+ {
+ TypeToSizeMap::AddResult result = m_totalSizes.add(objectType, size);
+ if (!result.isNewEntry)
+ result.iterator->value += size;
+ }
+ virtual bool visited(const void* object) { return !m_visitedObjects.add(object).isNewEntry; }
+ virtual void checkCountedObject(const void*) { }
+
+ size_t visitedObjects() const { return m_visitedObjects.size(); }
+ size_t totalSize(const MemoryObjectType objectType) const
+ {
+ TypeToSizeMap::const_iterator i = m_totalSizes.find(objectType);
+ return i == m_totalSizes.end() ? 0 : i->value;
+ }
+
+ size_t reportedSizeForAllTypes() const
+ {
+ size_t size = 0;
+ for (TypeToSizeMap::const_iterator i = m_totalSizes.begin(); i != m_totalSizes.end(); ++i)
+ size += i->value;
+ return size;
+ }
+
+ private:
+ typedef HashMap<MemoryObjectType, size_t> TypeToSizeMap;
+ TypeToSizeMap m_totalSizes;
+ WTF::HashSet<const void*> m_visitedObjects;
+ };
+
+ Client m_client;
+ Vector<OwnPtr<InstrumentedPointerBase> > m_deferredInstrumentedPointers;
+};
+
+void InstrumentationTestHelper::processDeferredInstrumentedPointers()
+{
+ while (!m_deferredInstrumentedPointers.isEmpty()) {
+ OwnPtr<InstrumentedPointerBase> pointer = m_deferredInstrumentedPointers.last().release();
+ m_deferredInstrumentedPointers.removeLast();
+ pointer->process(this);
+ }
+}
+
+void InstrumentationTestHelper::deferInstrumentedPointer(PassOwnPtr<InstrumentedPointerBase> pointer)
+{
+ m_deferredInstrumentedPointers.append(pointer);
+}
+
+class NotInstrumented {
+public:
+ NotInstrumented(const char* = 0) { }
+ char m_data[42];
+};
+
+class Instrumented {
+public:
+ Instrumented() : m_notInstrumented(new NotInstrumented) { }
+ virtual ~Instrumented() { delete m_notInstrumented; }
+
+ virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_notInstrumented);
+ }
+ NotInstrumented* m_notInstrumented;
+};
+
+TEST(MemoryInstrumentationTest, sizeOf)
+{
+ InstrumentationTestHelper helper;
+ Instrumented instrumented;
+ helper.addRootObject(instrumented);
+ EXPECT_EQ(sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, nullCheck)
+{
+ InstrumentationTestHelper helper;
+ Instrumented* instrumented = 0;
+ helper.addRootObject(instrumented);
+ EXPECT_EQ(0u, helper.reportedSizeForAllTypes());
+ EXPECT_EQ(0u, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, ptrVsRef)
+{
+ {
+ InstrumentationTestHelper helper;
+ Instrumented instrumented;
+ helper.addRootObject(&instrumented);
+ EXPECT_EQ(sizeof(Instrumented) + sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+ }
+ {
+ InstrumentationTestHelper helper;
+ Instrumented instrumented;
+ helper.addRootObject(instrumented);
+ EXPECT_EQ(sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+ }
+}
+
+TEST(MemoryInstrumentationTest, ownPtr)
+{
+ InstrumentationTestHelper helper;
+ OwnPtr<Instrumented> instrumented(adoptPtr(new Instrumented));
+ helper.addRootObject(instrumented);
+ EXPECT_EQ(sizeof(Instrumented) + sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+}
+
+class InstrumentedRefPtr : public RefCounted<InstrumentedRefPtr> {
+public:
+ InstrumentedRefPtr() : m_notInstrumented(new NotInstrumented) { }
+ virtual ~InstrumentedRefPtr() { delete m_notInstrumented; }
+ static PassRefPtr<InstrumentedRefPtr> create() { return adoptRef(new InstrumentedRefPtr()); }
+
+ virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_notInstrumented);
+ }
+ NotInstrumented* m_notInstrumented;
+};
+
+TEST(MemoryInstrumentationTest, refPtr)
+{
+ InstrumentationTestHelper helper;
+ RefPtr<InstrumentedRefPtr> instrumentedRefPtr(adoptRef(new InstrumentedRefPtr));
+ helper.addRootObject(instrumentedRefPtr);
+ EXPECT_EQ(sizeof(InstrumentedRefPtr) + sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+}
+
+class InstrumentedWithOwnPtr : public Instrumented {
+public:
+ InstrumentedWithOwnPtr() : m_notInstrumentedOwnPtr(adoptPtr(new NotInstrumented)) { }
+
+ virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ Instrumented::reportMemoryUsage(memoryObjectInfo);
+ info.addMember(m_notInstrumentedOwnPtr);
+ }
+ OwnPtr<NotInstrumented> m_notInstrumentedOwnPtr;
+};
+
+TEST(MemoryInstrumentationTest, ownPtrNotInstrumented)
+{
+ InstrumentationTestHelper helper;
+ InstrumentedWithOwnPtr instrumentedWithOwnPtr;
+ helper.addRootObject(instrumentedWithOwnPtr);
+ EXPECT_EQ(2u * sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+}
+
+class InstrumentedUndefined {
+public:
+ InstrumentedUndefined() : m_data(0) { }
+
+ void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this);
+ }
+ int m_data;
+};
+
+class InstrumentedDOM {
+public:
+ InstrumentedDOM() : m_instrumentedUndefined(adoptPtr(new InstrumentedUndefined)) { }
+
+ void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_instrumentedUndefined);
+ }
+ OwnPtr<InstrumentedUndefined> m_instrumentedUndefined;
+};
+
+TEST(MemoryInstrumentationTest, ownerTypePropagation)
+{
+ InstrumentationTestHelper helper;
+ OwnPtr<InstrumentedDOM> instrumentedDOM(adoptPtr(new InstrumentedDOM));
+ helper.addRootObject(instrumentedDOM);
+ EXPECT_EQ(sizeof(InstrumentedDOM) + sizeof(InstrumentedUndefined), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(sizeof(InstrumentedDOM) + sizeof(InstrumentedUndefined), helper.totalSize(TestType));
+ EXPECT_EQ(2u, helper.visitedObjects());
+}
+
+class NonVirtualInstrumented {
+public:
+ void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_instrumented);
+ }
+
+ Instrumented m_instrumented;
+};
+
+TEST(MemoryInstrumentationTest, visitFirstMemberInNonVirtualClass)
+{
+ InstrumentationTestHelper helper;
+ NonVirtualInstrumented nonVirtualInstrumented;
+ helper.addRootObject(&nonVirtualInstrumented);
+ EXPECT_EQ(sizeof(NonVirtualInstrumented) + sizeof(NotInstrumented), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+}
+
+template<typename T>
+class InstrumentedOwner {
+public:
+ template<typename V>
+ InstrumentedOwner(const V& value) : m_value(value) { }
+ InstrumentedOwner() { }
+ void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_value);
+ }
+
+ T m_value;
+};
+
+TEST(MemoryInstrumentationTest, visitStrings)
+{
+ { // 8-bit string.
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<String> stringInstrumentedOwner("String");
+ helper.addRootObject(stringInstrumentedOwner);
+ EXPECT_EQ(sizeof(StringImpl) + stringInstrumentedOwner.m_value.length(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+ }
+
+ { // 8-bit string with 16bit shadow.
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<String> stringInstrumentedOwner("String");
+ stringInstrumentedOwner.m_value.characters();
+ helper.addRootObject(stringInstrumentedOwner);
+ EXPECT_EQ(sizeof(StringImpl) + stringInstrumentedOwner.m_value.length() * (sizeof(LChar) + sizeof(UChar)), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+ }
+
+ { // 16 bit string.
+ InstrumentationTestHelper helper;
+ String string("String");
+ InstrumentedOwner<String> stringInstrumentedOwner(String(string.characters(), string.length()));
+ helper.addRootObject(stringInstrumentedOwner);
+ EXPECT_EQ(sizeof(StringImpl) + stringInstrumentedOwner.m_value.length() * sizeof(UChar), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+ }
+
+ { // ASCIILiteral
+ InstrumentationTestHelper helper;
+ ASCIILiteral literal("String");
+ InstrumentedOwner<String> stringInstrumentedOwner(literal);
+ helper.addRootObject(stringInstrumentedOwner);
+ EXPECT_EQ(sizeof(StringImpl), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+ }
+
+ { // Zero terminated internal buffer.
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<String> stringInstrumentedOwner("string");
+ stringInstrumentedOwner.m_value.charactersWithNullTermination();
+ helper.addRootObject(stringInstrumentedOwner);
+ EXPECT_EQ(sizeof(StringImpl) + (stringInstrumentedOwner.m_value.length() + 1) * (sizeof(LChar) + sizeof(UChar)), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+ }
+
+ { // Substring
+ InstrumentationTestHelper helper;
+ String baseString("String");
+ baseString.characters(); // Force 16 shadow creation.
+ InstrumentedOwner<String> stringInstrumentedOwner(baseString.substringSharingImpl(1, 4));
+ helper.addRootObject(stringInstrumentedOwner);
+ EXPECT_EQ(sizeof(StringImpl) * 2 + baseString.length() * (sizeof(LChar) + sizeof(UChar)), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(3u, helper.visitedObjects());
+ }
+
+ { // Owned buffer.
+ InstrumentationTestHelper helper;
+ StringBuffer<LChar> buffer(6);
+ InstrumentedOwner<String> stringInstrumentedOwner(String::adopt(buffer));
+ helper.addRootObject(stringInstrumentedOwner);
+ EXPECT_EQ(sizeof(StringImpl) + stringInstrumentedOwner.m_value.length(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+ }
+
+ {
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<AtomicString> atomicStringInstrumentedOwner("AtomicString");
+ atomicStringInstrumentedOwner.m_value.string().characters(); // Force 16bit shadow creation.
+ helper.addRootObject(atomicStringInstrumentedOwner);
+ EXPECT_EQ(sizeof(StringImpl) + atomicStringInstrumentedOwner.m_value.length() * (sizeof(LChar) + sizeof(UChar)), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+ }
+
+ {
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<CString> cStringInstrumentedOwner("CString");
+ helper.addRootObject(cStringInstrumentedOwner);
+ EXPECT_EQ(sizeof(WTF::CStringBuffer) + cStringInstrumentedOwner.m_value.length(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+ }
+}
+
+class TwoPointersToRefPtr {
+public:
+ TwoPointersToRefPtr(const RefPtr<StringImpl>& value) : m_ptr1(&value), m_ptr2(&value) { }
+ void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_ptr1);
+ info.addMember(m_ptr2);
+ }
+
+ const RefPtr<StringImpl>* m_ptr1;
+ const RefPtr<StringImpl>* m_ptr2;
+};
+
+TEST(MemoryInstrumentationTest, refPtrPtr)
+{
+ InstrumentationTestHelper helper;
+ RefPtr<StringImpl> refPtr;
+ TwoPointersToRefPtr root(refPtr);
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(RefPtr<StringImpl>), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+}
+
+class TwoPointersToOwnPtr {
+public:
+ TwoPointersToOwnPtr(const OwnPtr<NotInstrumented>& value) : m_ptr1(&value), m_ptr2(&value) { }
+ void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_ptr1);
+ info.addMember(m_ptr2);
+ }
+
+ const OwnPtr<NotInstrumented>* m_ptr1;
+ const OwnPtr<NotInstrumented>* m_ptr2;
+};
+
+TEST(MemoryInstrumentationTest, ownPtrPtr)
+{
+ InstrumentationTestHelper helper;
+ OwnPtr<NotInstrumented> ownPtr;
+ TwoPointersToOwnPtr root(ownPtr);
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(OwnPtr<NotInstrumented>), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+}
+
+template<typename T>
+class InstrumentedTemplate {
+public:
+ template<typename V>
+ InstrumentedTemplate(const V& value) : m_value(value) { }
+
+ template<typename MemoryObjectInfo>
+ void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ typename MemoryObjectInfo::ClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_value);
+ }
+
+ T m_value;
+};
+
+TEST(MemoryInstrumentationTest, detectReportMemoryUsageMethod)
+{
+ {
+ InstrumentationTestHelper helper;
+
+ OwnPtr<InstrumentedTemplate<String> > value(adoptPtr(new InstrumentedTemplate<String>("")));
+ InstrumentedOwner<InstrumentedTemplate<String>* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(InstrumentedTemplate<String>) + sizeof(StringImpl), helper.reportedSizeForAllTypes());
+ // FIXME: it is failing on Chromium Canary bots but works fine locally.
+ // EXPECT_EQ(2, helper.visitedObjects());
+ }
+ {
+ InstrumentationTestHelper helper;
+
+ OwnPtr<InstrumentedTemplate<NotInstrumented> > value(adoptPtr(new InstrumentedTemplate<NotInstrumented>("")));
+ InstrumentedOwner<InstrumentedTemplate<NotInstrumented>* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(InstrumentedTemplate<NotInstrumented>), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+ }
+}
+
+TEST(MemoryInstrumentationTest, vectorZeroInlineCapacity)
+{
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<Vector<int> > vectorOwner(16);
+ helper.addRootObject(vectorOwner);
+ EXPECT_EQ(16 * sizeof(int), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, vectorFieldWithInlineCapacity)
+{
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<Vector<int, 4> > vectorOwner;
+ helper.addRootObject(vectorOwner);
+ EXPECT_EQ(static_cast<size_t>(0), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(0u, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, vectorFieldWithInlineCapacityResized)
+{
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<Vector<int, 4> > vectorOwner;
+ vectorOwner.m_value.reserveCapacity(8);
+ helper.addRootObject(vectorOwner);
+ EXPECT_EQ(8u * sizeof(int), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, heapAllocatedVectorWithInlineCapacity)
+{
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<OwnPtr<Vector<int, 4> > > vectorOwner;
+ vectorOwner.m_value = adoptPtr(new Vector<int, 4>());
+ helper.addRootObject(vectorOwner);
+ EXPECT_EQ(sizeof(Vector<int, 4>), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, heapAllocatedVectorWithInlineCapacityResized)
+{
+ InstrumentationTestHelper helper;
+ InstrumentedOwner<OwnPtr<Vector<int, 4> > > vectorOwner;
+ vectorOwner.m_value = adoptPtr(new Vector<int, 4>());
+ vectorOwner.m_value->reserveCapacity(8);
+ helper.addRootObject(vectorOwner);
+ EXPECT_EQ(8u * sizeof(int) + sizeof(Vector<int, 4>), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, vectorWithInstrumentedType)
+{
+ InstrumentationTestHelper helper;
+
+ typedef Vector<String> StringVector;
+ OwnPtr<StringVector> value = adoptPtr(new StringVector());
+ size_t count = 10;
+ for (size_t i = 0; i < count; ++i)
+ value->append("string");
+ InstrumentedOwner<StringVector* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(StringVector) + sizeof(String) * value->capacity() + (sizeof(StringImpl) + 6) * value->size(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(count + 2, (size_t)helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashSetWithInstrumentedType)
+{
+ InstrumentationTestHelper helper;
+
+ typedef HashSet<String> ValueType;
+ OwnPtr<ValueType> value = adoptPtr(new ValueType());
+ size_t count = 10;
+ for (size_t i = 0; i < count; ++i)
+ value->add(String::number(i));
+ InstrumentedOwner<ValueType* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(ValueType) + sizeof(String) * value->capacity() + (sizeof(StringImpl) + 1) * value->size(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(count + 1, (size_t)helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithNotInstrumentedKeysAndValues)
+{
+ InstrumentationTestHelper helper;
+
+ typedef HashMap<int, int> IntToIntMap;
+ OwnPtr<IntToIntMap> value = adoptPtr(new IntToIntMap());
+ size_t count = 10;
+ for (size_t i = 1; i <= count; ++i)
+ value->set(i, i);
+ InstrumentedOwner<IntToIntMap* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(IntToIntMap) + sizeof(IntToIntMap::ValueType) * value->capacity(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(1u, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithInstrumentedKeys)
+{
+ InstrumentationTestHelper helper;
+
+ typedef HashMap<String, int> StringToIntMap;
+ OwnPtr<StringToIntMap> value = adoptPtr(new StringToIntMap());
+ size_t count = 10;
+ for (size_t i = 10; i < 10 + count; ++i)
+ value->set(String::number(i), i);
+ InstrumentedOwner<StringToIntMap* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(StringToIntMap) + sizeof(StringToIntMap::ValueType) * value->capacity() + (sizeof(StringImpl) + 2) * value->size(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithInstrumentedValues)
+{
+ InstrumentationTestHelper helper;
+
+ typedef HashMap<int, String> IntToStringMap;
+ OwnPtr<IntToStringMap> value = adoptPtr(new IntToStringMap());
+ size_t count = 10;
+ for (size_t i = 10; i < 10 + count; ++i)
+ value->set(i, String::number(i));
+ InstrumentedOwner<IntToStringMap* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(IntToStringMap) + sizeof(IntToStringMap::ValueType) * value->capacity() + (sizeof(StringImpl) + 2) * value->size(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithInstrumentedKeysAndValues)
+{
+ InstrumentationTestHelper helper;
+
+ typedef HashMap<String, String> StringToStringMap;
+ OwnPtr<StringToStringMap> value = adoptPtr(new StringToStringMap());
+ size_t count = 10;
+ for (size_t i = 10; i < 10 + count; ++i)
+ value->set(String::number(count + i), String::number(i));
+ InstrumentedOwner<StringToStringMap* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(StringToStringMap) + sizeof(StringToStringMap::ValueType) * value->capacity() + 2 * (sizeof(StringImpl) + 2) * value->size(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u * count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithInstrumentedPointerKeysAndPointerValues)
+{
+ InstrumentationTestHelper helper;
+
+ typedef HashMap<Instrumented*, Instrumented*> InstrumentedToInstrumentedMap;
+ OwnPtr<InstrumentedToInstrumentedMap> value(adoptPtr(new InstrumentedToInstrumentedMap()));
+ Vector<OwnPtr<Instrumented> > valuesVector;
+ size_t count = 10;
+ for (size_t i = 0; i < count; ++i) {
+ valuesVector.append(adoptPtr(new Instrumented()));
+ valuesVector.append(adoptPtr(new Instrumented()));
+ value->set(valuesVector[2 * i].get(), valuesVector[2 * i + 1].get());
+ }
+ InstrumentedOwner<InstrumentedToInstrumentedMap* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(InstrumentedToInstrumentedMap) + sizeof(InstrumentedToInstrumentedMap::ValueType) * value->capacity() + 2 * (sizeof(Instrumented) + sizeof(NotInstrumented)) * value->size(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u * 2u * count + 1, helper.visitedObjects());
+}
+
+class InstrumentedConvertibleToInt {
+public:
+ InstrumentedConvertibleToInt() : m_notInstrumented(0) { }
+ virtual ~InstrumentedConvertibleToInt() { }
+
+ virtual void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+ {
+ MemoryClassInfo info(memoryObjectInfo, this, TestType);
+ info.addMember(m_notInstrumented);
+ }
+
+ operator int() const { return 2012; }
+
+ NotInstrumented* m_notInstrumented;
+};
+
+// This test checks if reportMemoryUsage method will be called on a class
+// that can be implicitly cast to int. Currently objects of such classes are
+// treated as integers when they are stored in a HashMap by value and
+// reportMemoryUsage will not be called on them. We may fix that later.
+TEST(MemoryInstrumentationTest, hashMapWithValuesConvertibleToInt)
+{
+ InstrumentationTestHelper helper;
+
+ typedef HashMap<InstrumentedConvertibleToInt*, InstrumentedConvertibleToInt> TestMap;
+ OwnPtr<TestMap> value(adoptPtr(new TestMap()));
+ Vector<OwnPtr<InstrumentedConvertibleToInt> > keysVector;
+ Vector<OwnPtr<NotInstrumented> > valuesVector;
+ size_t count = 10;
+ for (size_t i = 0; i < count; ++i) {
+ keysVector.append(adoptPtr(new InstrumentedConvertibleToInt()));
+ valuesVector.append(adoptPtr(new NotInstrumented()));
+ value->set(keysVector[i].get(), InstrumentedConvertibleToInt()).iterator->value.m_notInstrumented = valuesVector[i].get();
+ }
+ InstrumentedOwner<TestMap* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(TestMap) + sizeof(TestMap::ValueType) * value->capacity() +
+ sizeof(InstrumentedConvertibleToInt) * count /* + sizeof(NotInstrumented) * count */, helper.reportedSizeForAllTypes());
+ EXPECT_EQ(count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashMapWithEnumKeysAndInstrumentedValues)
+{
+ InstrumentationTestHelper helper;
+
+ typedef HashMap<TestEnum, String> EnumToStringMap;
+ OwnPtr<EnumToStringMap> value(adoptPtr(new EnumToStringMap()));
+ size_t count = MY_ENUM_MAX;
+ for (size_t i = ONE; i <= count; ++i)
+ value->set(static_cast<TestEnum>(i), String::number(i));
+ InstrumentedOwner<EnumToStringMap* > root(value.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(EnumToStringMap) + sizeof(EnumToStringMap::ValueType) * value->capacity() + (sizeof(StringImpl) + 1) * value->size(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, hashCountedSetWithInstrumentedValues)
+{
+ InstrumentationTestHelper helper;
+
+ typedef HashCountedSet<Instrumented*> TestSet;
+ OwnPtr<TestSet> set(adoptPtr(new TestSet()));
+ Vector<OwnPtr<Instrumented> > keysVector;
+ size_t count = 10;
+ for (size_t i = 0; i < count; ++i) {
+ keysVector.append(adoptPtr(new Instrumented()));
+ for (size_t j = 0; j <= i; j++)
+ set->add(keysVector.last().get());
+ }
+ InstrumentedOwner<TestSet* > root(set.get());
+ helper.addRootObject(root);
+ EXPECT_EQ(sizeof(TestSet) + sizeof(HashMap<Instrumented*, unsigned>::ValueType) * set->capacity() + (sizeof(Instrumented) + sizeof(NotInstrumented)) * set->size(), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u * count + 1, helper.visitedObjects());
+}
+
+TEST(MemoryInstrumentationTest, arrayBuffer)
+{
+ InstrumentationTestHelper helper;
+
+ typedef InstrumentedTemplate<RefPtr<ArrayBuffer> > ValueType;
+ ValueType value(ArrayBuffer::create(1000, sizeof(int)));
+ helper.addRootObject(value);
+ EXPECT_EQ(sizeof(int) * 1000 + sizeof(ArrayBuffer), helper.reportedSizeForAllTypes());
+ EXPECT_EQ(2u, helper.visitedObjects());
+}
+
+} // namespace
+
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp
index 98bfab35a..5b1296f47 100644
--- a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp
+++ b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp
@@ -171,8 +171,8 @@ void DOMWindowExtensionBasic::willDestroyPage(WKBundleRef, WKBundlePageRef)
HashMap<WKBundleDOMWindowExtensionRef, int>::iterator it = m_extensionToRecordMap.begin();
HashMap<WKBundleDOMWindowExtensionRef, int>::iterator end = m_extensionToRecordMap.end();
for (; it != end; ++it) {
- updateExtensionStateRecord(it->first, Removed);
- WKRelease(it->first);
+ updateExtensionStateRecord(it->key, Removed);
+ WKRelease(it->key);
}
m_extensionToRecordMap.clear();
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp
index 8f6cd7b37..411e115ea 100644
--- a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp
+++ b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp
@@ -178,8 +178,8 @@ void DOMWindowExtensionNoCache::willDestroyPage(WKBundleRef, WKBundlePageRef)
HashMap<WKBundleDOMWindowExtensionRef, int>::iterator it = m_extensionToRecordMap.begin();
HashMap<WKBundleDOMWindowExtensionRef, int>::iterator end = m_extensionToRecordMap.end();
for (; it != end; ++it) {
- updateExtensionStateRecord(it->first, Removed);
- WKRelease(it->first);
+ updateExtensionStateRecord(it->key, Removed);
+ WKRelease(it->key);
}
m_extensionToRecordMap.clear();
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp
index f87da5878..d6a787061 100644
--- a/Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp
+++ b/Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp
@@ -89,7 +89,11 @@ TEST(WebKit2, SpacebarScrolling)
didNotHandleKeyDownEvent = false;
webView.simulateSpacebarKeyPress();
+ // This EXPECT_JS_TRUE test fails on Windows port
+ // https://bugs.webkit.org/show_bug.cgi?id=84961
+#if !PLATFORM(WIN)
EXPECT_JS_TRUE(webView.page(), "isDocumentScrolled()");
+#endif
EXPECT_JS_TRUE(webView.page(), "textFieldContainsSpace()");
#if PLATFORM(MAC)
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKURL.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKURL.cpp
new file mode 100644
index 000000000..f3ea83b6d
--- /dev/null
+++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKURL.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. 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"
+
+namespace TestWebKitAPI {
+
+TEST(WebKit2, WKURL)
+{
+ WKURLRef baseURL = WKURLCreateWithUTF8CString("http://trac.webkit.org");
+ WKURLRef URL = WKURLCreateWithBaseURL(baseURL, "wiki");
+ WKRelease(baseURL);
+
+ WKStringRef string = WKURLCopyString(URL);
+ EXPECT_TRUE(WKStringIsEqualToUTF8CString(string, "http://trac.webkit.org/wiki"));
+
+ WKRelease(string);
+ WKRelease(URL);
+}
+
+} // namespace TestWebKitAPI
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/UserContentTest.mm b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/UserContentTest.mm
new file mode 100644
index 000000000..d87ad5ed5
--- /dev/null
+++ b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/UserContentTest.mm
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#import "config.h"
+#import "Test.h"
+
+#import "PlatformUtilities.h"
+#import <JavaScriptCore/JSRetainPtr.h>
+#import <JavaScriptCore/JavaScriptCore.h>
+#import <WebKit2/WKSerializedScriptValue.h>
+#import <WebKit2/WKViewPrivate.h>
+#import <WebKit2/WebKit2.h>
+
+
+static bool testFinished = false;
+static NSString *htmlString = @"<body style='background-color: red'>";
+static NSString *userStyleSheet = @"body { background-color: green !important; }";
+static const char* backgroundColorScript = "window.getComputedStyle(document.body, null).getPropertyValue('background-color')";
+static const char* greenInRGB = "rgb(0, 128, 0)";
+static const char* redInRGB = "rgb(255, 0, 0)";
+static const char* userScriptTestProperty = "window._userScriptInstalled";
+
+typedef void (^OnLoadBlock)(WKBrowsingContextController *);
+
+@interface UserContentTestLoadDelegate : NSObject <WKBrowsingContextLoadDelegate>
+{
+ OnLoadBlock _onLoadBlock;
+}
+
+@property (nonatomic, copy) OnLoadBlock onLoadBlock;
+
+- (id)initWithBlockToRunOnLoad:(OnLoadBlock)block;
+
+@end
+
+@implementation UserContentTestLoadDelegate
+
+@synthesize onLoadBlock = _onLoadBlock;
+
+- (id)initWithBlockToRunOnLoad:(OnLoadBlock)block
+{
+ if (!(self = [super init]))
+ return nil;
+
+ self.onLoadBlock = block;
+ return self;
+}
+
+- (void)browsingContextControllerDidFinishLoad:(WKBrowsingContextController *)sender
+{
+ if (_onLoadBlock)
+ _onLoadBlock(sender);
+}
+
+@end
+
+namespace {
+ class WebKit2UserContentTest : public ::testing::Test {
+ public:
+ WKProcessGroup *processGroup;
+ WKBrowsingContextGroup *browsingContextGroup;
+
+ WebKit2UserContentTest()
+ : processGroup(nil)
+ , browsingContextGroup(nil)
+ {
+ }
+
+ virtual void SetUp()
+ {
+ processGroup = [[WKProcessGroup alloc] init];
+ browsingContextGroup = [[WKBrowsingContextGroup alloc] initWithIdentifier:@"UserContentIdentifier"];
+ }
+
+ virtual void TearDown()
+ {
+ [browsingContextGroup release];
+ [processGroup release];
+ }
+ };
+} // namespace
+
+static void expectScriptValueIsString(WKSerializedScriptValueRef serializedScriptValue, const char* expectedValue)
+{
+ JSGlobalContextRef scriptContext = JSGlobalContextCreate(0);
+
+ JSValueRef scriptValue = WKSerializedScriptValueDeserialize(serializedScriptValue, scriptContext, 0);
+ EXPECT_TRUE(JSValueIsString(scriptContext, scriptValue));
+
+ JSRetainPtr<JSStringRef> scriptString(Adopt, JSValueToStringCopy(scriptContext, scriptValue, 0));
+ EXPECT_TRUE(JSStringIsEqualToUTF8CString(scriptString.get(), expectedValue));
+
+ JSGlobalContextRelease(scriptContext);
+}
+
+static void expectScriptValueIsBoolean(WKSerializedScriptValueRef serializedScriptValue, bool expectedValue)
+{
+ JSGlobalContextRef scriptContext = JSGlobalContextCreate(0);
+
+ JSValueRef scriptValue = WKSerializedScriptValueDeserialize(serializedScriptValue, scriptContext, 0);
+ EXPECT_TRUE(JSValueIsBoolean(scriptContext, scriptValue));
+ EXPECT_EQ(JSValueToBoolean(scriptContext, scriptValue), expectedValue);
+
+ JSGlobalContextRelease(scriptContext);
+}
+
+static void expectScriptValueIsUndefined(WKSerializedScriptValueRef serializedScriptValue)
+{
+ JSGlobalContextRef scriptContext = JSGlobalContextCreate(0);
+
+ JSValueRef scriptValue = WKSerializedScriptValueDeserialize(serializedScriptValue, scriptContext, 0);
+ EXPECT_TRUE(JSValueIsUndefined(scriptContext, scriptValue));
+
+ JSGlobalContextRelease(scriptContext);
+}
+
+TEST_F(WebKit2UserContentTest, AddUserStyleSheetBeforeCreatingView)
+{
+ testFinished = false;
+ [browsingContextGroup addUserStyleSheet:userStyleSheet baseURL:nil whitelistedURLPatterns:nil blacklistedURLPatterns:nil mainFrameOnly:YES];
+
+ WKView *wkView = [[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) processGroup:processGroup browsingContextGroup:browsingContextGroup];
+ WKStringRef backgroundColorQuery = WKStringCreateWithUTF8CString(backgroundColorScript);
+ wkView.browsingContextController.loadDelegate = [[UserContentTestLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) {
+ WKPageRunJavaScriptInMainFrame_b(wkView.pageRef, backgroundColorQuery, ^(WKSerializedScriptValueRef serializedScriptValue, WKErrorRef error) {
+ expectScriptValueIsString(serializedScriptValue, greenInRGB);
+ testFinished = true;
+ WKRelease(backgroundColorQuery);
+ });
+ }];
+
+ [wkView.browsingContextController loadHTMLString:htmlString baseURL:nil];
+
+ TestWebKitAPI::Util::run(&testFinished);
+}
+
+TEST_F(WebKit2UserContentTest, AddUserStyleSheetAfterCreatingView)
+{
+ testFinished = false;
+
+ WKView *wkView = [[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) processGroup:processGroup browsingContextGroup:browsingContextGroup];
+ WKStringRef backgroundColorQuery = WKStringCreateWithUTF8CString(backgroundColorScript);
+ wkView.browsingContextController.loadDelegate = [[UserContentTestLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) {
+ WKPageRunJavaScriptInMainFrame_b(wkView.pageRef, backgroundColorQuery, ^(WKSerializedScriptValueRef serializedScriptValue, WKErrorRef error) {
+ expectScriptValueIsString(serializedScriptValue, greenInRGB);
+ testFinished = true;
+ WKRelease(backgroundColorQuery);
+ });
+ }];
+
+ [browsingContextGroup addUserStyleSheet:userStyleSheet baseURL:nil whitelistedURLPatterns:nil blacklistedURLPatterns:nil mainFrameOnly:YES];
+
+ [wkView.browsingContextController loadHTMLString:htmlString baseURL:nil];
+
+ TestWebKitAPI::Util::run(&testFinished);
+}
+
+TEST_F(WebKit2UserContentTest, RemoveAllUserStyleSheets)
+{
+ testFinished = false;
+ [browsingContextGroup addUserStyleSheet:userStyleSheet baseURL:nil whitelistedURLPatterns:nil blacklistedURLPatterns:nil mainFrameOnly:YES];
+
+ WKView *wkView = [[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) processGroup:processGroup browsingContextGroup:browsingContextGroup];
+ WKStringRef backgroundColorQuery = WKStringCreateWithUTF8CString(backgroundColorScript);
+ wkView.browsingContextController.loadDelegate = [[UserContentTestLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) {
+ WKPageRunJavaScriptInMainFrame_b(wkView.pageRef, backgroundColorQuery, ^(WKSerializedScriptValueRef serializedScriptValue, WKErrorRef error) {
+ expectScriptValueIsString(serializedScriptValue, redInRGB);
+ testFinished = true;
+ WKRelease(backgroundColorQuery);
+ });
+ }];
+
+ [browsingContextGroup removeAllUserStyleSheets];
+
+ [wkView.browsingContextController loadHTMLString:htmlString baseURL:nil];
+
+ TestWebKitAPI::Util::run(&testFinished);
+}
+
+TEST_F(WebKit2UserContentTest, AddUserScriptBeforeCreatingView)
+{
+ testFinished = false;
+ [browsingContextGroup addUserScript:[NSString stringWithFormat:@"%s = true;", userScriptTestProperty] baseURL:nil whitelistedURLPatterns:nil blacklistedURLPatterns:nil injectionTime:kWKInjectAtDocumentStart mainFrameOnly:YES];
+
+ WKView *wkView = [[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) processGroup:processGroup browsingContextGroup:browsingContextGroup];
+ WKStringRef userScriptTestPropertyString = WKStringCreateWithUTF8CString(userScriptTestProperty);
+ wkView.browsingContextController.loadDelegate = [[UserContentTestLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) {
+ WKPageRunJavaScriptInMainFrame_b(wkView.pageRef, userScriptTestPropertyString, ^(WKSerializedScriptValueRef serializedScriptValue, WKErrorRef error) {
+ expectScriptValueIsBoolean(serializedScriptValue, true);
+ testFinished = true;
+ WKRelease(userScriptTestPropertyString);
+ });
+ }];
+
+ [wkView.browsingContextController loadHTMLString:@"" baseURL:nil];
+
+ TestWebKitAPI::Util::run(&testFinished);
+}
+
+TEST_F(WebKit2UserContentTest, AddUserScriptAfterCreatingView)
+{
+ testFinished = false;
+
+ WKView *wkView = [[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) processGroup:processGroup browsingContextGroup:browsingContextGroup];
+ WKStringRef userScriptTestPropertyString = WKStringCreateWithUTF8CString(userScriptTestProperty);
+ wkView.browsingContextController.loadDelegate = [[UserContentTestLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) {
+ WKPageRunJavaScriptInMainFrame_b(wkView.pageRef, userScriptTestPropertyString, ^(WKSerializedScriptValueRef serializedScriptValue, WKErrorRef error) {
+ expectScriptValueIsBoolean(serializedScriptValue, true);
+ testFinished = true;
+ WKRelease(userScriptTestPropertyString);
+ });
+ }];
+
+ [browsingContextGroup addUserScript:[NSString stringWithFormat:@"%s = true;", userScriptTestProperty] baseURL:nil whitelistedURLPatterns:nil blacklistedURLPatterns:nil injectionTime:kWKInjectAtDocumentStart mainFrameOnly:YES];
+
+ [wkView.browsingContextController loadHTMLString:@"" baseURL:nil];
+
+ TestWebKitAPI::Util::run(&testFinished);
+}
+
+TEST_F(WebKit2UserContentTest, RemoveAllUserScripts)
+{
+ testFinished = false;
+ [browsingContextGroup addUserScript:[NSString stringWithFormat:@"%s = true;", userScriptTestProperty] baseURL:nil whitelistedURLPatterns:nil blacklistedURLPatterns:nil injectionTime:kWKInjectAtDocumentStart mainFrameOnly:YES];
+
+ WKView *wkView = [[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) processGroup:processGroup browsingContextGroup:browsingContextGroup];
+ WKStringRef userScriptTestPropertyString = WKStringCreateWithUTF8CString(userScriptTestProperty);
+ wkView.browsingContextController.loadDelegate = [[UserContentTestLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) {
+ WKPageRunJavaScriptInMainFrame_b(wkView.pageRef, userScriptTestPropertyString, ^(WKSerializedScriptValueRef serializedScriptValue, WKErrorRef error) {
+ expectScriptValueIsUndefined(serializedScriptValue);
+ testFinished = true;
+ WKRelease(userScriptTestPropertyString);
+ });
+ }];
+
+ [browsingContextGroup removeAllUserScripts];
+
+ [wkView.browsingContextController loadHTMLString:htmlString baseURL:nil];
+
+ TestWebKitAPI::Util::run(&testFinished);
+}