WebKitTools/WebKitAPITest/tests/WebViewDestruction.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2010 Apple Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  * 1.  Redistributions of source code must retain the above copyright
       
     8  *     notice, this list of conditions and the following disclaimer.
       
     9  * 2.  Redistributions in binary form must reproduce the above copyright
       
    10  *     notice, this list of conditions and the following disclaimer in the
       
    11  *     documentation and/or other materials provided with the distribution.
       
    12  *
       
    13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
       
    14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
       
    20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       
    22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    23  */
       
    24 
       
    25 #include "HostWindow.h"
       
    26 #include "Test.h"
       
    27 #include <WebCore/COMPtr.h>
       
    28 #include <WebKit/WebKit.h>
       
    29 #include <WebKit/WebKitCOMAPI.h>
       
    30 #include <wtf/PassOwnPtr.h>
       
    31 
       
    32 namespace WebKitAPITest {
       
    33 
       
    34 template <typename T>
       
    35 static HRESULT WebKitCreateInstance(REFCLSID clsid, T** object)
       
    36 {
       
    37     return WebKitCreateInstance(clsid, 0, __uuidof(T), reinterpret_cast<void**>(object));
       
    38 }
       
    39 
       
    40 static int webViewCount()
       
    41 {
       
    42     COMPtr<IWebKitStatistics> statistics;
       
    43     if (FAILED(WebKitCreateInstance(__uuidof(WebKitStatistics), &statistics)))
       
    44         return -1;
       
    45     int count;
       
    46     if (FAILED(statistics->webViewCount(&count)))
       
    47         return -1;
       
    48     return count;
       
    49 }
       
    50 
       
    51 static void createAndInitializeWebView(COMPtr<IWebView>& outWebView, HostWindow& window, HWND& viewWindow)
       
    52 {
       
    53     COMPtr<IWebView> webView;
       
    54     TEST_ASSERT(SUCCEEDED(WebKitCreateInstance(__uuidof(WebView), &webView)));
       
    55 
       
    56     TEST_ASSERT(window.initialize());
       
    57     TEST_ASSERT(SUCCEEDED(webView->setHostWindow(reinterpret_cast<OLE_HANDLE>(window.window()))));
       
    58     TEST_ASSERT(SUCCEEDED(webView->initWithFrame(window.clientRect(), 0, 0)));
       
    59 
       
    60     COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
       
    61     TEST_ASSERT(viewPrivate);
       
    62     TEST_ASSERT(SUCCEEDED(viewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))));
       
    63     TEST_ASSERT(IsWindow(viewWindow));
       
    64 
       
    65     outWebView.adoptRef(webView.releaseRef());
       
    66 }
       
    67 
       
    68 static void runMessagePump(DWORD timeoutMilliseconds)
       
    69 {
       
    70     DWORD startTickCount = GetTickCount();
       
    71     MSG msg;
       
    72     BOOL result;
       
    73     while ((result = PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) && GetTickCount() - startTickCount <= timeoutMilliseconds) {
       
    74         if (result == -1)
       
    75             break;
       
    76         TranslateMessage(&msg);
       
    77         DispatchMessage(&msg);
       
    78     }
       
    79 }
       
    80 
       
    81 static void finishWebViewDestructionTest(COMPtr<IWebView>& webView, HWND viewWindow)
       
    82 {
       
    83     // Allow window messages to be processed, because in some cases that would trigger a crash (e.g., <http://webkit.org/b/32827>).
       
    84     runMessagePump(50);
       
    85 
       
    86     // We haven't crashed. Release the WebView and ensure that its view window has been destroyed and the WebView doesn't leak.
       
    87     int currentWebViewCount = webViewCount();
       
    88     TEST_ASSERT(currentWebViewCount > 0);
       
    89 
       
    90     webView = 0;
       
    91 
       
    92     TEST_ASSERT(webViewCount() == currentWebViewCount - 1);
       
    93     TEST_ASSERT(!IsWindow(viewWindow));
       
    94 }
       
    95 
       
    96 // Tests that releasing a WebView without calling IWebView::initWithFrame works.
       
    97 TEST(WebViewDestruction, NoInitWithFrame)
       
    98 {
       
    99     COMPtr<IWebView> webView;
       
   100     TEST_ASSERT(SUCCEEDED(WebKitCreateInstance(__uuidof(WebView), &webView)));
       
   101 
       
   102     finishWebViewDestructionTest(webView, 0);
       
   103 }
       
   104 
       
   105 TEST(WebViewDestruction, CloseWithoutInitWithFrame)
       
   106 {
       
   107     COMPtr<IWebView> webView;
       
   108     TEST_ASSERT(SUCCEEDED(WebKitCreateInstance(__uuidof(WebView), &webView)));
       
   109 
       
   110     TEST_ASSERT(SUCCEEDED(webView->close()));
       
   111 
       
   112     finishWebViewDestructionTest(webView, 0);
       
   113 }
       
   114 
       
   115 // Tests that releasing a WebView without calling IWebView::close or DestroyWindow doesn't leak. <http://webkit.org/b/33162>
       
   116 TEST(WebViewDestruction, NoCloseOrDestroyViewWindow)
       
   117 {
       
   118     COMPtr<IWebView> webView;
       
   119     HostWindow window;
       
   120     HWND viewWindow;
       
   121     createAndInitializeWebView(webView, window, viewWindow);
       
   122 
       
   123     finishWebViewDestructionTest(webView, viewWindow);
       
   124 }
       
   125 
       
   126 // Tests that calling IWebView::close without calling DestroyWindow, then releasing a WebView doesn't crash. <http://webkit.org/b/32827>
       
   127 TEST(WebViewDestruction, CloseWithoutDestroyViewWindow)
       
   128 {
       
   129     COMPtr<IWebView> webView;
       
   130     HostWindow window;
       
   131     HWND viewWindow;
       
   132     createAndInitializeWebView(webView, window, viewWindow);
       
   133 
       
   134     TEST_ASSERT(SUCCEEDED(webView->close()));
       
   135 
       
   136     finishWebViewDestructionTest(webView, viewWindow);
       
   137 }
       
   138 
       
   139 TEST(WebViewDestruction, DestroyViewWindowWithoutClose)
       
   140 {
       
   141     COMPtr<IWebView> webView;
       
   142     HostWindow window;
       
   143     HWND viewWindow;
       
   144     createAndInitializeWebView(webView, window, viewWindow);
       
   145 
       
   146     DestroyWindow(viewWindow);
       
   147 
       
   148     finishWebViewDestructionTest(webView, viewWindow);
       
   149 }
       
   150 
       
   151 TEST(WebViewDestruction, CloseThenDestroyViewWindow)
       
   152 {
       
   153     COMPtr<IWebView> webView;
       
   154     HostWindow window;
       
   155     HWND viewWindow;
       
   156     createAndInitializeWebView(webView, window, viewWindow);
       
   157 
       
   158     TEST_ASSERT(SUCCEEDED(webView->close()));
       
   159     DestroyWindow(viewWindow);
       
   160 
       
   161     finishWebViewDestructionTest(webView, viewWindow);
       
   162 }
       
   163 
       
   164 TEST(WebViewDestruction, DestroyViewWindowThenClose)
       
   165 {
       
   166     COMPtr<IWebView> webView;
       
   167     HostWindow window;
       
   168     HWND viewWindow;
       
   169     createAndInitializeWebView(webView, window, viewWindow);
       
   170 
       
   171     DestroyWindow(viewWindow);
       
   172     TEST_ASSERT(SUCCEEDED(webView->close()));
       
   173 
       
   174     finishWebViewDestructionTest(webView, viewWindow);
       
   175 }
       
   176 
       
   177 TEST(WebViewDestruction, DestroyHostWindow)
       
   178 {
       
   179     COMPtr<IWebView> webView;
       
   180     HostWindow window;
       
   181     HWND viewWindow;
       
   182     createAndInitializeWebView(webView, window, viewWindow);
       
   183 
       
   184     DestroyWindow(window.window());
       
   185 
       
   186     finishWebViewDestructionTest(webView, viewWindow);
       
   187 }
       
   188 
       
   189 TEST(WebViewDestruction, DestroyHostWindowThenClose)
       
   190 {
       
   191     COMPtr<IWebView> webView;
       
   192     HostWindow window;
       
   193     HWND viewWindow;
       
   194     createAndInitializeWebView(webView, window, viewWindow);
       
   195 
       
   196     DestroyWindow(window.window());
       
   197     TEST_ASSERT(SUCCEEDED(webView->close()));
       
   198 
       
   199     finishWebViewDestructionTest(webView, viewWindow);
       
   200 }
       
   201 
       
   202 TEST(WebViewDestruction, CloseThenDestroyHostWindow)
       
   203 {
       
   204     COMPtr<IWebView> webView;
       
   205     HostWindow window;
       
   206     HWND viewWindow;
       
   207     createAndInitializeWebView(webView, window, viewWindow);
       
   208 
       
   209     TEST_ASSERT(SUCCEEDED(webView->close()));
       
   210     DestroyWindow(window.window());
       
   211 
       
   212     finishWebViewDestructionTest(webView, viewWindow);
       
   213 }
       
   214 
       
   215 // Tests that calling IWebView::mainFrame after calling IWebView::close doesn't crash. <http://webkit.org/b/32868>
       
   216 TEST(WebViewDestruction, MainFrameAfterClose)
       
   217 {
       
   218     COMPtr<IWebView> webView;
       
   219     HostWindow window;
       
   220     HWND viewWindow;
       
   221     createAndInitializeWebView(webView, window, viewWindow);
       
   222 
       
   223     TEST_ASSERT(SUCCEEDED(webView->close()));
       
   224     COMPtr<IWebFrame> mainFrame;
       
   225     TEST_ASSERT(SUCCEEDED(webView->mainFrame(&mainFrame)));
       
   226 
       
   227     finishWebViewDestructionTest(webView, viewWindow);
       
   228 }
       
   229 
       
   230 } // namespace WebKitAPITest