diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
commit | 881da28418d380042aa95a97f0cbd42560a64f7c (patch) | |
tree | a794dff3274695e99c651902dde93d934ea7a5af /Tools/TestWebKitAPI | |
parent | 7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff) | |
parent | 0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff) | |
download | qtwebkit-881da28418d380042aa95a97f0cbd42560a64f7c.tar.gz |
Merge 'wip/next' into dev
Change-Id: Iff9ee5e23bb326c4371ec8ed81d56f2f05d680e9
Diffstat (limited to 'Tools/TestWebKitAPI')
399 files changed, 29509 insertions, 12144 deletions
diff --git a/Tools/TestWebKitAPI/CMakeLists.txt b/Tools/TestWebKitAPI/CMakeLists.txt index 23f2184ce..c505fa25b 100644 --- a/Tools/TestWebKitAPI/CMakeLists.txt +++ b/Tools/TestWebKitAPI/CMakeLists.txt @@ -1,156 +1,228 @@ set(TESTWEBKITAPI_DIR "${TOOLS_DIR}/TestWebKitAPI") - -include_directories(${CMAKE_BINARY_DIR} - ${TESTWEBKITAPI_DIR} - ${CMAKE_SOURCE_DIR}/Source - ${DERIVED_SOURCES_WEBCORE_DIR} - ${DERIVED_SOURCES_WEBKIT2_DIR}/include - ${JAVASCRIPTCORE_DIR} - ${JAVASCRIPTCORE_DIR}/API - ${JAVASCRIPTCORE_DIR}/ForwardingHeaders - ${THIRDPARTY_DIR}/gtest/include - ${WEBCORE_DIR}/editing - ${WEBCORE_DIR}/platform - ${WEBCORE_DIR}/platform/graphics - ${WEBCORE_DIR}/platform/text - ${WEBCORE_DIR}/platform/network - ${WEBKIT2_DIR}/Shared - ${WEBKIT2_DIR}/Shared/API/c - ${WEBKIT2_DIR}/Shared/Plugins - ${WEBKIT2_DIR}/UIProcess - ${WEBKIT2_DIR}/WebProcess/InjectedBundle - ${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/c - ${WTF_DIR} +set(test_wtf_LIBRARIES + WTF${DEBUG_SUFFIX} + gtest ) -WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS() - -add_library(TestWebKitAPIInjectedBundle SHARED - ${bundle_harness_SOURCES} - ${TESTWEBKITAPI_DIR}/InjectedBundleController.cpp - ${TESTWEBKITAPI_DIR}/InjectedBundleMain.cpp - ${TESTWEBKITAPI_DIR}/PlatformUtilities.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/CanHandleRequest_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/DidAssociateFormControls_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/HitTestResultNodeHandle_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/InjectedBundleBasic_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/InjectedBundleFrameHitTest_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/LoadCanceledNoServerRedirectCallback_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/MouseMoveAfterCrash_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/ParentFrame_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/ShouldGoToBackForwardListItem_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/UserMessage_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/WKConnection_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/WillLoad_Bundle.cpp - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/WillSendSubmitEvent_Bundle.cpp +set(test_webcore_LIBRARIES + WTF${DEBUG_SUFFIX} + WebCore${DEBUG_SUFFIX} + gtest ) set(TestWebKitAPI_LIBRARIES - WTF - WebKit2 + WTF${DEBUG_SUFFIX} ) -target_link_libraries(TestWebKitAPIInjectedBundle ${TestWebKitAPI_LIBRARIES}) -add_dependencies(TestWebKitAPIInjectedBundle ${ForwardingHeadersForTestWebKitAPI_NAME} ${ForwardingNetworkHeadersForTestWebKitAPI_NAME}) - -get_property(TestWebKitAPIInjectedBundle_PATH TARGET TestWebKitAPIInjectedBundle PROPERTY LOCATION) - -add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1 - -DTEST_WEBKIT2_RESOURCES_DIR=\"${TESTWEBKITAPI_DIR}/Tests/WebKit2\" - -DTEST_INJECTED_BUNDLE_PATH=\"${TestWebKitAPIInjectedBundle_PATH}\" -) - -set(test_wtf_LIBRARIES - WTF +if (ENABLE_WEBKIT2) + set(test_webkit2_api_LIBRARIES + JavaScriptCore + TestWebKitAPIBase + WTF + WebKit2 + gtest + ) + list(APPEND TestWebKitAPI_LIBRARIES + WebKit2 + ) +else () + list(APPEND TestWebKitAPI_LIBRARIES + WebKit${DEBUG_SUFFIX} + ) +endif () + + +set(TestJavaScriptCore_LIBRARIES + JavaScriptCore gtest ) -add_executable(test_wtf - ${test_main_SOURCES} +set(TestWTF_SOURCES + ${TESTWEBKITAPI_DIR}/Counters.cpp ${TESTWEBKITAPI_DIR}/TestsController.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/AtomicString.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/CString.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/Condition.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/CheckedArithmeticOperations.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/DateMath.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/Deque.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/Functional.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/HashCountedSet.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/HashMap.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/HashSet.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/IntegerToStringConversion.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/ListHashSet.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/Lock.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/MD5.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/MathExtras.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/MediaTime.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/MetaAllocator.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/NakedPtr.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/OptionSet.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/ParkingLot.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/RedBlackTree.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/Ref.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/RefPtr.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/SHA1.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/SaturatedArithmeticOperations.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/StringBuilder.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/StringHasher.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/StringImpl.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/StringOperators.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/StringView.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/TemporaryChange.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/Vector.cpp - ${TESTWEBKITAPI_DIR}/Tests/WTF/VectorBasic.cpp - ${TESTWEBKITAPI_DIR}/Tests/WTF/VectorReverse.cpp ${TESTWEBKITAPI_DIR}/Tests/WTF/WTFString.cpp + ${TESTWEBKITAPI_DIR}/Tests/WTF/WorkQueue.cpp ) -target_link_libraries(test_wtf ${test_wtf_LIBRARIES}) -add_dependencies(test_wtf ${ForwardingHeadersForTestWebKitAPI_NAME} ${ForwardingNetworkHeadersForTestWebKitAPI_NAME}) -add_test(test_wtf ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_wtf) -set_tests_properties(test_wtf PROPERTIES TIMEOUT 60) +WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS() -set(test_webcore_LIBRARIES - gtest - WTF - WebCore +include_directories( + ${TESTWEBKITAPI_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/Source + ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR} + ${DERIVED_SOURCES_WEBCORE_DIR} + ${JAVASCRIPTCORE_DIR} + ${JAVASCRIPTCORE_DIR}/API + ${JAVASCRIPTCORE_DIR}/ForwardingHeaders + ${THIRDPARTY_DIR}/gtest/include + ${WEBCORE_DIR}/css + ${WEBCORE_DIR}/dom + ${WEBCORE_DIR}/editing + ${WEBCORE_DIR}/loader/cache + ${WEBCORE_DIR}/platform + ${WEBCORE_DIR}/platform/animation + ${WEBCORE_DIR}/platform/graphics + ${WEBCORE_DIR}/platform/text + ${WEBCORE_DIR}/platform/network + ${WEBCORE_DIR}/platform/network/soup + ${WEBCORE_DIR}/rendering/style + ${WEBKIT2_DIR}/Platform/IPC + ${WEBKIT2_DIR}/Shared + ${WEBKIT2_DIR}/Shared/API + ${WEBKIT2_DIR}/Shared/API/c + ${WEBKIT2_DIR}/Shared/Plugins + ${WEBKIT2_DIR}/UIProcess + ${WEBKIT2_DIR}/UIProcess/API + ${WEBKIT2_DIR}/WebProcess/InjectedBundle + ${WEBKIT2_DIR}/WebProcess/InjectedBundle/API/c + ${WTF_DIR} ) -foreach (testName ${test_webcore_BINARIES}) - add_executable(test_webcore_${testName} ${test_main_SOURCES} ${TESTWEBKITAPI_DIR}/TestsController.cpp ${TESTWEBKITAPI_DIR}/Tests/WebCore/${testName}.cpp) - add_test(test_webcore_${testName} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_webcore_${testName}) - set_tests_properties(test_webcore_${testName} PROPERTIES TIMEOUT 60) - target_link_libraries(test_webcore_${testName} ${test_webcore_LIBRARIES}) -endforeach () +if (ENABLE_WEBKIT2) + add_library(TestWebKitAPIInjectedBundle SHARED + ${bundle_harness_SOURCES} + ${TESTWEBKITAPI_DIR}/InjectedBundleController.cpp + ${TESTWEBKITAPI_DIR}/InjectedBundleMain.cpp + ${TESTWEBKITAPI_DIR}/PlatformUtilities.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/CanHandleRequest_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/DidAssociateFormControls_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/HitTestResultNodeHandle_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/InjectedBundleBasic_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/InjectedBundleFrameHitTest_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/LoadCanceledNoServerRedirectCallback_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/MouseMoveAfterCrash_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/ParentFrame_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/ShouldGoToBackForwardListItem_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/TextFieldDidBeginAndEndEditing_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/UserMessage_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/WillLoad_Bundle.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebKit2/WillSendSubmitEvent_Bundle.cpp + ) + + target_link_libraries(TestWebKitAPIInjectedBundle ${TestWebKitAPI_LIBRARIES}) + add_dependencies(TestWebKitAPIInjectedBundle WTF ${ForwardingHeadersForTestWebKitAPI_NAME}) + + get_property(TestWebKitAPIInjectedBundle_PATH TARGET TestWebKitAPIInjectedBundle PROPERTY LOCATION) +endif () + +if (WIN32) + add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=0) +else () + add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1) +endif () + +add_definitions(-DGTEST_HAS_RTTI=0 + -DTEST_WEBKIT2_RESOURCES_DIR=\"${TESTWEBKITAPI_DIR}/Tests/WebKit2\" + -DTEST_INJECTED_BUNDLE_PATH=\"${TestWebKitAPIInjectedBundle_PATH}\" +) + +# FIXME: This works around compatibility problems in the old version of the third-pary +# googletest source code checkout. It should be removed once we upgrade to a newer version. +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + add_definitions(-DGTEST_HAS_TR1_TUPLE=0) +endif () -add_library(TestWebKitAPIBase +add_executable(TestWTF ${test_main_SOURCES} - ${webkit2_api_harness_SOURCES} - ${TESTWEBKITAPI_DIR}/JavaScriptTest.cpp - ${TESTWEBKITAPI_DIR}/PlatformUtilities.cpp - ${TESTWEBKITAPI_DIR}/TestsController.cpp + ${TestWTF_SOURCES} ) -add_dependencies(TestWebKitAPIBase WebKit2 ${ForwardingHeadersForTestWebKitAPI_NAME} ${ForwardingNetworkHeadersForTestWebKitAPI_NAME}) +if (WIN32) + add_dependencies(TestWTF TestWTFLib) +endif () -set(test_webkit2_api_LIBRARIES - TestWebKitAPIBase - WTF - JavaScriptCore - WebKit2 - gtest +target_link_libraries(TestWTF ${test_wtf_LIBRARIES}) +add_dependencies(TestWTF WTF ${ForwardingHeadersForTestWebKitAPI_NAME} ${ForwardingNetworkHeadersForTestWebKitAPI_NAME}) +add_test(TestWTF ${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY_WTF}/TestWTF) +set_tests_properties(TestWTF PROPERTIES TIMEOUT 60) +set_target_properties(TestWTF PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY_WTF} ) -foreach (testName ${test_webkit2_api_BINARIES}) - get_filename_component(testBaseName ${testName} NAME) - add_executable(test_webkit2_api_${testBaseName} ${TESTWEBKITAPI_DIR}/Tests/WebKit2/${testName}.cpp) - add_test(test_webkit2_api_${testBaseName} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_webkit2_api_${testBaseName}) - set_tests_properties(test_webkit2_api_${testBaseName} PROPERTIES TIMEOUT 60) - target_link_libraries(test_webkit2_api_${testBaseName} ${test_webkit2_api_LIBRARIES}) +# FIXME: EFL is the only port that separates the WebCore binaries. Each port ought to do closer to the same thing. +foreach (testName ${test_webcore_BINARIES}) + add_executable(${testName} ${test_main_SOURCES} ${TESTWEBKITAPI_DIR}/TestsController.cpp ${TESTWEBKITAPI_DIR}/Tests/WebCore/${testName}.cpp) + add_test(${testName} ${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY}/WebCore/${testName}) + set_tests_properties(${testName} PROPERTIES TIMEOUT 60) + target_link_libraries(${testName} ${test_webcore_LIBRARIES}) + set_target_properties(${testName} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY}/WebCore + ) endforeach () -# We don't run tests that are expected to fail. We could use the WILL_FAIL -# property, but it reports failure when the test crashes or timeouts and would -# make the bot red. - -foreach (testName ${test_webkit2_api_fail_BINARIES}) - add_executable(test_webkit2_api_fail_${testName} ${TESTWEBKITAPI_DIR}/Tests/WebKit2/${testName}.cpp) - target_link_libraries(test_webkit2_api_fail_${testName} ${test_webkit2_api_LIBRARIES}) -endforeach () +if (ENABLE_WEBKIT2) + add_library(TestWebKitAPIBase + ${test_main_SOURCES} + ${webkit2_api_harness_SOURCES} + ${TESTWEBKITAPI_DIR}/JavaScriptTest.cpp + ${TESTWEBKITAPI_DIR}/PlatformUtilities.cpp + ${TESTWEBKITAPI_DIR}/TestsController.cpp + ) + + add_dependencies(TestWebKitAPIBase WebKit2 ${ForwardingHeadersForTestWebKitAPI_NAME} ${ForwardingNetworkHeadersForTestWebKitAPI_NAME}) + + foreach (testName ${test_webkit2_api_BINARIES}) + get_filename_component(testBaseName ${testName} NAME) + add_executable(${testBaseName} ${TESTWEBKITAPI_DIR}/Tests/WebKit2/${testName}.cpp) + add_test(${testBaseName} ${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY}/WebKit2/${testBaseName}) + set_tests_properties(${testBaseName} PROPERTIES TIMEOUT 60) + target_link_libraries(${testBaseName} ${test_webkit2_api_LIBRARIES}) + set_target_properties(${testBaseName} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY}/WebKit2 + ) + endforeach () + + # We don't run tests that are expected to fail. We could use the WILL_FAIL + # property, but it reports failure when the test crashes or timeouts and would + # make the bot red. + foreach (testName ${test_webkit2_api_fail_BINARIES}) + add_executable(${testName} ${TESTWEBKITAPI_DIR}/Tests/WebKit2/${testName}.cpp) + target_link_libraries(${testName} ${test_webkit2_api_LIBRARIES}) + set_target_properties(${testName} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY}/WebKit2/failure + ) + endforeach () +endif () diff --git a/Tools/TestWebKitAPI/Configurations/Base.xcconfig b/Tools/TestWebKitAPI/Configurations/Base.xcconfig deleted file mode 100644 index 834faa366..000000000 --- a/Tools/TestWebKitAPI/Configurations/Base.xcconfig +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2010 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. ``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 -// 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. - -CLANG_CXX_LANGUAGE_STANDARD = gnu++0x; -CLANG_CXX_LIBRARY = libc++; -CLANG_WARN_CXX0X_EXTENSIONS = NO; -HEADER_SEARCH_PATHS = ${BUILT_PRODUCTS_DIR}/usr/local/include $(WEBCORE_PRIVATE_HEADERS_DIR)/ForwardingHeaders $(WEBCORE_PRIVATE_HEADERS_DIR)/icu; -FRAMEWORK_SEARCH_PATHS = $(FRAMEWORK_SEARCH_PATHS_$(PLATFORM_NAME)); -FRAMEWORK_SEARCH_PATHS_macosx = $(SYSTEM_LIBRARY_DIR)/Frameworks/Quartz.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks; - -GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST GTEST_HAS_TR1_TUPLE=0 GTEST_HAS_RTTI=0 $(GCC_PREPROCESSOR_DEFINITIONS_$(PLATFORM_NAME)); -GCC_PREPROCESSOR_DEFINITIONS_macosx = ENABLE_DASHBOARD_SUPPORT; -DEBUG_INFORMATION_FORMAT = dwarf-with-dsym; -PREBINDING = NO -GCC_C_LANGUAGE_STANDARD = gnu99 -GCC_ENABLE_CPP_EXCEPTIONS = NO; -GCC_ENABLE_CPP_RTTI = NO; -GCC_PRECOMPILE_PREFIX_HEADER = YES -GCC_TREAT_WARNINGS_AS_ERRORS = YES -GCC_VERSION = com.apple.compilers.llvm.clang.1_0; -GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO -GCC_WARN_UNUSED_FUNCTION = YES -GCC_WARN_UNUSED_VARIABLE = YES -WARNING_CFLAGS = -Wall -W -Wno-unused-parameter -LINKER_DISPLAYS_MANGLED_NAMES = YES; -OTHER_CPLUSPLUSFLAGS = $(OTHER_CPLUSPLUSFLAGS) -ftemplate-depth=256; - -// DEBUG_DEFINES, GCC_OPTIMIZATION_LEVEL, STRIP_INSTALLED_PRODUCT and DEAD_CODE_STRIPPING vary between the debug and normal variants. -// We set up the values for each variant here, and have the Debug configuration in the Xcode project use the _debug variant. -DEBUG_DEFINES_debug = ; -DEBUG_DEFINES_normal = NDEBUG; -DEBUG_DEFINES = $(DEBUG_DEFINES_$(CURRENT_VARIANT)); - -SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx; - -TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); - - -TARGETING_SAME_OS_X_VERSION = $(TARGETING_SAME_OS_X_VERSION_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -TARGETING_SAME_OS_X_VERSION_1070_1070 = YES; -TARGETING_SAME_OS_X_VERSION_1080_1080 = YES; -TARGETING_SAME_OS_X_VERSION_1090_1090 = YES; - -// Don't build against an SDK unless we're targeting an older OS version. -SDKROOT = $(SDKROOT_TARGETING_SAME_OS_X_VERSION_$(TARGETING_SAME_OS_X_VERSION)); -SDKROOT_TARGETING_SAME_OS_X_VERSION_ = macosx; - -WEBKIT_UMBRELLA_FRAMEWORKS_DIR = $(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Versions/A/Frameworks; -WEBCORE_PRIVATE_HEADERS_DIR = $(WEBKIT_UMBRELLA_FRAMEWORKS_DIR)/WebCore.framework/PrivateHeaders; - -EXCLUDED_SOURCE_FILE_NAMES = $(EXCLUDED_SOURCE_FILE_NAMES_$(PLATFORM_NAME)); -EXCLUDED_SOURCE_FILE_NAMES_macosx = *IOS.h *IOS.cpp *IOS.mm; -EXCLUDED_SOURCE_FILE_NAMES_iphoneos = *Mac.h *Mac.cpp *Mac.mm *InjectedBundle* *PlatformUtilities* Tests/WebKit2/* Tests/WebKit2ObjC/* *_Bundle* JavaScriptTest.*; -EXCLUDED_SOURCE_FILE_NAMES_iphonesimulator = $(EXCLUDED_SOURCE_FILE_NAMES_iphoneos); diff --git a/Tools/TestWebKitAPI/Configurations/DebugRelease.xcconfig b/Tools/TestWebKitAPI/Configurations/DebugRelease.xcconfig deleted file mode 100644 index f681015b8..000000000 --- a/Tools/TestWebKitAPI/Configurations/DebugRelease.xcconfig +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2010 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. ``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 -// 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 "Base.xcconfig" - -ARCHS = $(ARCHS_STANDARD_32_64_BIT); - -ONLY_ACTIVE_ARCH = YES; - -MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(TARGET_MAC_OS_X_VERSION_MAJOR)) -MACOSX_DEPLOYMENT_TARGET_1070 = 10.7; -MACOSX_DEPLOYMENT_TARGET_1080 = 10.8; -MACOSX_DEPLOYMENT_TARGET_1090 = 10.9; - -WEBKIT_UMBRELLA_FRAMEWORKS_DIR = $(BUILT_PRODUCTS_DIR); diff --git a/Tools/TestWebKitAPI/Configurations/InjectedBundle.xcconfig b/Tools/TestWebKitAPI/Configurations/InjectedBundle.xcconfig deleted file mode 100644 index 164a05cff..000000000 --- a/Tools/TestWebKitAPI/Configurations/InjectedBundle.xcconfig +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2010 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. ``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 -// 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. - -PRODUCT_NAME = InjectedBundleTestWebKitAPI; diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig b/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig deleted file mode 100644 index 5fc6f7449..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2010 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. ``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 -// 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. - -PRODUCT_NAME = TestWebKitAPI; -GCC_ENABLE_OBJC_EXCEPTIONS = YES; - -OTHER_LDFLAGS = -lgtest -framework JavaScriptCore -framework WebKit $(OTHER_LDFLAGS_$(PLATFORM_NAME)); -OTHER_LDFLAGS_iphoneos = -framework WebCore; -OTHER_LDFLAGS_iphonesimulator = $(OTHER_LDFLAGS_iphoneos); -OTHER_LDFLAGS_macosx = -framework Cocoa -framework Carbon -framework WebKit2; diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPICFLite.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPICFLite.vsprops deleted file mode 100644 index 61b661413..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPICFLite.vsprops +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPICFLite"
- >
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="CFLite$(LibraryConfigSuffix).lib"
- />
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPICFNetwork.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPICFNetwork.vsprops deleted file mode 100644 index cc25b8669..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPICFNetwork.vsprops +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPICFNetwork"
- >
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="CFNetwork$(LibraryConfigSuffix).lib"
- />
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPICommon.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPICommon.vsprops deleted file mode 100644 index 57ec3506e..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPICommon.vsprops +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPICommon"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)\..";"$(ConfigurationBuildDir)\include";"$(ConfigurationBuildDir)\include\private\JavaScriptCore";"$(ConfigurationBuildDir)\include\WebCore\ForwardingHeaders";"$(ConfigurationBuildDir)\include\private";"$(WebKitLibrariesDir)\include";"$(ProjectDir)\..\..\..\Source\ThirdParty\gtest\include""
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="WebKit$(WebKitDLLConfigSuffix).lib JavaScriptCore$(WebKitDLLConfigSuffix).lib gtest.lib"
- SubSystem="1"
- />
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPICoreFoundation.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPICoreFoundation.vsprops deleted file mode 100644 index ee139c0bc..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPICoreFoundation.vsprops +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPICoreFoundation"
- >
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="CoreFoundation$(LibraryConfigSuffix).lib"
- />
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIDebug.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPIDebug.vsprops deleted file mode 100644 index 981225f35..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIDebug.vsprops +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPIDebug"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\TestWebKitAPICommon.vsprops;.\TestWebKitAPICoreFoundation.vsprops;.\TestWebKitAPICFNetwork.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIDebugAll.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPIDebugAll.vsprops deleted file mode 100644 index f70863b49..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIDebugAll.vsprops +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPIDebugAll"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops;.\TestWebKitAPICommon.vsprops;.\TestWebKitAPICoreFoundation.vsprops;.\TestWebKitAPICFNetwork.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIDebugCairoCFLite.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPIDebugCairoCFLite.vsprops deleted file mode 100644 index ba38ece12..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIDebugCairoCFLite.vsprops +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPIDebugCairoCFLite"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;..\Configurations\TestWebKitAPICommon.vsprops;..\Configurations\TestWebKitAPICFLite.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIInjectedBundleCommon.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPIInjectedBundleCommon.vsprops deleted file mode 100644 index 5e19c4621..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIInjectedBundleCommon.vsprops +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPIInjectedBundleCommon"
- >
- <Tool
- Name="VCLinkerTool"
- OutputFile="$(OutDir)\$(ProjectName)$(WebKitDLLConfigSuffix).dll"
- />
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIRelease.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPIRelease.vsprops deleted file mode 100644 index e5edd81d8..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIRelease.vsprops +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPIRelease"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\TestWebKitAPICommon.vsprops;.\TestWebKitAPICoreFoundation.vsprops;.\TestWebKitAPICFNetwork.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIReleaseCairoCFLite.vsprops b/Tools/TestWebKitAPI/Configurations/TestWebKitAPIReleaseCairoCFLite.vsprops deleted file mode 100644 index 1b97b644d..000000000 --- a/Tools/TestWebKitAPI/Configurations/TestWebKitAPIReleaseCairoCFLite.vsprops +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="TestWebKitAPIReleaseCairoCFLite"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops;..\Configurations\TestWebKitAPICommon.vsprops;..\Configurations\TestWebKitAPICFLite.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Tools/TestWebKitAPI/Tests/mac/TypingStyleCrash.mm b/Tools/TestWebKitAPI/Counters.cpp index a23623bb0..87aa4bba2 100644 --- a/Tools/TestWebKitAPI/Tests/mac/TypingStyleCrash.mm +++ b/Tools/TestWebKitAPI/Counters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,14 +24,11 @@ */ #include "config.h" +#include "Counters.h" -namespace TestWebKitAPI { +unsigned CopyMoveCounter::constructionCount = 0; +unsigned CopyMoveCounter::copyCount = 0; +unsigned CopyMoveCounter::moveCount = 0; -TEST(WebKit1, TypingStyleCrash) -{ - WebView *webView = [[WebView alloc] init]; - [webView typingStyle]; - [webView release]; -} - -} // namespace TestWebKitAPI +unsigned ConstructorDestructorCounter::constructionCount = 0; +unsigned ConstructorDestructorCounter::destructionCount = 0; diff --git a/Tools/TestWebKitAPI/Counters.h b/Tools/TestWebKitAPI/Counters.h new file mode 100644 index 000000000..1cfd7b71d --- /dev/null +++ b/Tools/TestWebKitAPI/Counters.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * Copyright (C) 2014 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. + */ + +#ifndef Counters_h +#define Counters_h + +struct CopyMoveCounter { + static unsigned constructionCount; + static unsigned copyCount; + static unsigned moveCount; + + struct TestingScope { + TestingScope() + { + constructionCount = 0; + copyCount = 0; + moveCount = 0; + } + }; + + CopyMoveCounter() { constructionCount++; } + CopyMoveCounter(const CopyMoveCounter&) { copyCount++; } + CopyMoveCounter& operator=(const CopyMoveCounter&) { copyCount++; return *this; } + CopyMoveCounter(CopyMoveCounter&&) { moveCount++; } + CopyMoveCounter& operator=(CopyMoveCounter&&) { moveCount++; return *this; } +}; + + +struct ConstructorDestructorCounter { + static unsigned constructionCount; + static unsigned destructionCount; + + struct TestingScope { + TestingScope() + { + constructionCount = 0; + destructionCount = 0; + } + }; + + ConstructorDestructorCounter() { constructionCount++; } + ~ConstructorDestructorCounter() { destructionCount++; } +}; + +template<typename T> +struct DeleterCounter { + static unsigned deleterCount; + + struct TestingScope { + TestingScope() + { + deleterCount = 0; + } + }; + + void operator()(T* p) const + { + deleterCount++; + delete p; + } +}; + +template<class T> unsigned DeleterCounter<T>::deleterCount = 0; + +#endif // Counters_h diff --git a/Tools/TestWebKitAPI/DerivedSources.pri b/Tools/TestWebKitAPI/DerivedSources.pri deleted file mode 100644 index cb391ad59..000000000 --- a/Tools/TestWebKitAPI/DerivedSources.pri +++ /dev/null @@ -1,12 +0,0 @@ -# ------------------------------------------------------------------- -# Derived sources for TestWebKitAPI -# -# See 'Tools/qmake/README' for an overview of the build system -# ------------------------------------------------------------------- - -TEMPLATE = derived - -# Make sure forwarded headers needed by this project are present -fwheader_generator.commands = perl $${ROOT_WEBKIT_DIR}/Source/WebKit2/Scripts/generate-forwarding-headers.pl $${ROOT_WEBKIT_DIR}/Tools/TestWebKitAPI $${ROOT_BUILD_DIR}/Source/include qt -fwheader_generator.depends = $${ROOT_WEBKIT_DIR}/Source/WebKit2/Scripts/generate-forwarding-headers.pl -GENERATORS += fwheader_generator diff --git a/Tools/TestWebKitAPI/GNUmakefile.am b/Tools/TestWebKitAPI/GNUmakefile.am deleted file mode 100644 index a3b3f9857..000000000 --- a/Tools/TestWebKitAPI/GNUmakefile.am +++ /dev/null @@ -1,375 +0,0 @@ -noinst_LTLIBRARIES += \ - Libraries/libTestWebKitAPIMain.la - -Libraries_libTestWebKitAPIMain_la_SOURCES = \ - Tools/TestWebKitAPI/Test.h \ - Tools/TestWebKitAPI/TestsController.cpp \ - Tools/TestWebKitAPI/TestsController.h \ - Tools/TestWebKitAPI/gtk/main.cpp - -# Use -isystem gcc flag so that gcc considers gtest headers as system headers. -# We need this to avoid a lot of compile warnings due to -Wundef. -# See http://code.google.com/p/googletest/issues/detail?id=258 -Libraries_libTestWebKitAPIMain_la_CPPFLAGS = \ - -isystem $(srcdir)/Source/ThirdParty/gtest/include \ - -I$(srcdir)/Tools/TestWebKitAPI \ - -I$(srcdir)/Source/ThirdParty/gtest/include \ - -I$(top_builddir)/DerivedSources/WebCore/include \ - -I$(top_builddir)/DerivedSources/WebKit2/include \ - $(global_cppflags) \ - $(javascriptcore_cppflags) \ - $(GTK_CFLAGS) - -noinst_PROGRAMS += \ - Programs/TestWebKitAPI/TestWTF \ - Programs/TestWebKitAPI/TestJavaScriptCore \ - Programs/TestWebKitAPI/TestWebCore \ - Programs/TestWebKitAPI/TestGtk - -if ENABLE_WEBKIT2 -noinst_PROGRAMS += \ - Programs/TestWebKitAPI/TestWebKit2 -endif # ENABLE_WEBKIT2 - -Programs_TestWebKitAPI_TestWTF_CPPFLAGS = \ - $(Libraries_libTestWebKitAPIMain_la_CPPFLAGS) \ - $(GLIB_LIBS) \ - $(CAIRO_CFLAGS) - -Programs_TestWebKitAPI_TestWTF_CXXFLAGS = \ - -DGTEST_HAS_RTTI=0 \ - $(global_cxxflags) - -Programs_TestWebKitAPI_TestWTF_LDADD = \ - Libraries/libTestWebKitAPIMain.la \ - Libraries/libgtest.la \ - libWTF.la \ - $(GTK_LIBS) \ - $(GLIB_LIBS) - -Programs_TestWebKitAPI_TestWTF_LDFLAGS = \ - -no-install \ - -no-fast-install - -Programs_TestWebKitAPI_TestWTF_SOURCES = \ - Tools/TestWebKitAPI/Tests/WTF/AtomicString.cpp \ - Tools/TestWebKitAPI/Tests/WTF/CString.cpp \ - Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp \ - Tools/TestWebKitAPI/Tests/WTF/Functional.cpp \ - Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp \ - Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp \ - Tools/TestWebKitAPI/Tests/WTF/IntegerToStringConversion.cpp \ - Tools/TestWebKitAPI/Tests/WTF/ListHashSet.cpp \ - Tools/TestWebKitAPI/Tests/WTF/MD5.cpp \ - Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp \ - Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp \ - Tools/TestWebKitAPI/Tests/WTF/MetaAllocator.cpp \ - Tools/TestWebKitAPI/Tests/WTF/RedBlackTree.cpp \ - Tools/TestWebKitAPI/Tests/WTF/SHA1.cpp \ - Tools/TestWebKitAPI/Tests/WTF/SaturatedArithmeticOperations.cpp \ - Tools/TestWebKitAPI/Tests/WTF/StringBuilder.cpp \ - Tools/TestWebKitAPI/Tests/WTF/StringHasher.cpp \ - Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp \ - Tools/TestWebKitAPI/Tests/WTF/StringOperators.cpp \ - Tools/TestWebKitAPI/Tests/WTF/TemporaryChange.cpp \ - Tools/TestWebKitAPI/Tests/WTF/Vector.cpp \ - Tools/TestWebKitAPI/Tests/WTF/VectorBasic.cpp \ - Tools/TestWebKitAPI/Tests/WTF/VectorReverse.cpp \ - Tools/TestWebKitAPI/WTFStringUtilities.h - -Programs_TestWebKitAPI_TestJavaScriptCore_CPPFLAGS = \ - $(Libraries_libTestWebKitAPIMain_la_CPPFLAGS) - -Programs_TestWebKitAPI_TestJavaScriptCore_CXXFLAGS = \ - -DGTEST_HAS_RTTI=0 \ - $(global_cxxflags) - -Programs_TestWebKitAPI_TestJavaScriptCore_LDADD = \ - Libraries/libTestWebKitAPIMain.la \ - Libraries/libgtest.la \ - libWTF.la \ - $(GTK_LIBS) - -Programs_TestWebKitAPI_TestJavaScriptCore_LDFLAGS = \ - -no-install \ - -no-fast-install - -Programs_TestWebKitAPI_TestJavaScriptCore_SOURCES = \ - Tools/TestWebKitAPI/Tests/JavaScriptCore/VMInspector.cpp - -webcore_layer_deps = \ - libPlatform.la \ - libPlatformGtk.la \ - libWebCorePlatform.la \ - libWebCoreGtk.la \ - libWebCore.la \ - libWebCoreModules.la -if ENABLE_SVG -webcore_layer_deps += \ - libWebCoreSVG.la -endif -if ENABLE_INDEXED_DATABASE -webcore_layer_deps += \ - libLevelDB.la -endif -if USE_OPENGL -webcore_layer_deps += \ - libANGLE.la -endif - -webcore_layer_archives = $(foreach lib, $(webcore_layer_deps), $(shell echo $(lib) | sed "s/\(.*\)\.la/.libs\/\1.a/")) - -WebCoreLayer.a: $(webcore_layer_deps) - $(AM_V_GEN) - $(AM_V_at)$(shell rm -f $@) - $(AM_V_at)$(foreach archive, $(webcore_layer_archives), $(shell ar t $(archive) | xargs -n50 ar cruT $@)) - -DISTCLEANFILES += \ - $(top_builddir)/WebCoreLayer.a - -Programs_TestWebKitAPI_TestWebCore_CPPFLAGS = \ - $(Libraries_libTestWebKitAPIMain_la_CPPFLAGS) \ - -I$(top_builddir)/DerivedSources/WebCore/include - -Programs_TestWebKitAPI_TestWebCore_CXXFLAGS = \ - -DGTEST_HAS_RTTI=0 \ - $(global_cxxflags) - -Programs_TestWebKitAPI_TestWebCore_LDADD = \ - Libraries/libTestWebKitAPIMain.la \ - Libraries/libgtest.la \ - libjavascriptcoregtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \ - libWTF.la \ - WebCoreLayer.a \ - $(CAIRO_LIBS) \ - $(CLUTTER_LIBS) \ - $(FREETYPE_LIBS) \ - $(GAMEPAD_LIBS) \ - $(GEOCLUE_LIBS) \ - $(GAIL_LIBS) \ - $(GLIB_LIBS) \ - $(GSTREAMER_LIBS) \ - $(GTK_LIBS) \ - $(JPEG_LIBS) \ - $(LIBSECRET_LIBS) \ - $(LIBSOUP_LIBS) \ - $(LIBXML_LIBS) \ - $(LIBXSLT_LIBS) \ - $(OPENGL_LIBS) \ - $(PANGO_LIBS) \ - $(PNG_LIBS) \ - $(SQLITE3_LIBS) \ - $(UNICODE_LIBS) \ - $(WEBP_LIBS) \ - $(XRENDER_LIBS) \ - $(XT_LIBS) \ - $(ZLIB_LIBS) - -Programs_TestWebKitAPI_TestWebCore_LDFLAGS = \ - -no-install \ - -no-fast-install - -Programs_TestWebKitAPI_TestWebCore_SOURCES = \ - Tools/TestWebKitAPI/Tests/WebCore/KURL.cpp \ - Tools/TestWebKitAPI/Tests/WebCore/LayoutUnit.cpp - -Programs_TestWebKitAPI_TestGtk_CPPFLAGS = \ - $(Programs_TestWebKitAPI_TestWTF_CPPFLAGS) \ - $(platform_cppflags) \ - $(platformgtk_cppflags) \ - $(webcore_cppflags) \ - $(webcoregtk_cppflags) \ - $(FREETYPE_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(GTK_CFLAGS) \ - $(LIBSOUP_CFLAGS) - -Programs_TestWebKitAPI_TestGtk_CXXFLAGS = \ - -DGTEST_HAS_RTTI=0 \ - $(global_cxxflags) - -Programs_TestWebKitAPI_TestGtk_LDADD = \ - Libraries/libTestWebKitAPIMain.la \ - Libraries/libgtest.la \ - libjavascriptcoregtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \ - libPlatformGtk.la \ - libWebCore.la \ - libWebCoreGtk.la \ - $(FREETYPE_LIBS) \ - $(GLIB_LIBS) \ - $(GTK_LIBS) \ - $(LIBSOUP_LIBS) - -Programs_TestWebKitAPI_TestGtk_LDFLAGS = \ - $(Programs_TestWebKitAPI_TestWTF_LDFLAGS) - -Programs_TestWebKitAPI_TestGtk_SOURCES = \ - Source/WebCore/platform/graphics/IntRect.cpp \ - Source/WebCore/platform/graphics/cairo/IntRectCairo.cpp \ - Source/WebCore/platform/graphics/gtk/IntRectGtk.cpp \ - Source/WebCore/platform/gtk/GtkInputMethodFilter.cpp \ - Tools/TestWebKitAPI/config.h \ - Tools/TestWebKitAPI/Tests/gtk/InputMethodFilter.cpp - -Programs_TestWebKitAPI_TestWebKit2_CPPFLAGS = \ - $(Programs_TestWebKitAPI_TestWTF_CPPFLAGS) \ - -I$(top_builddir)/DerivedSources/WebKit2/include \ - $(FREETYPE_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(GTK_CFLAGS) \ - $(LIBSOUP_CFLAGS) - -Programs_TestWebKitAPI_TestWebKit2_CXXFLAGS = \ - -DGTEST_HAS_RTTI=0 \ - $(global_cxxflags) - -Programs_TestWebKitAPI_TestWebKit2_LDADD = \ - Libraries/libTestWebKitAPIMain.la \ - Libraries/libgtest.la \ - libjavascriptcoregtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \ - libwebkit2gtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \ - $(FREETYPE_LIBS) \ - $(GLIB_LIBS) \ - $(GTK_LIBS) \ - $(LIBSOUP_LIBS) - -Programs_TestWebKitAPI_TestWebKit2_LDFLAGS = \ - $(Programs_TestWebKitAPI_TestWTF_LDFLAGS) - -Programs_TestWebKitAPI_TestWebKit2_SOURCES = \ - Tools/TestWebKitAPI/config.h \ - Tools/TestWebKitAPI/gtk/PlatformUtilitiesGtk.cpp \ - Tools/TestWebKitAPI/gtk/PlatformWebViewGtk.cpp \ - Tools/TestWebKitAPI/JavaScriptTest.cpp \ - Tools/TestWebKitAPI/JavaScriptTest.h \ - Tools/TestWebKitAPI/PlatformUtilities.cpp \ - Tools/TestWebKitAPI/PlatformUtilities.h \ - Tools/TestWebKitAPI/PlatformWebView.h \ - Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/CookieManager.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/DownloadDecideDestinationCrash.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/EvaluateJavaScript.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/Find.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/ForceRepaint.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypeHTML.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypePNG.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/LoadAlternateHTMLStringWithNonDirectoryURL.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/LoadPageOnCrash.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/ReloadPageAfterCrash.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/ResizeWindowAfterCrash.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/PageLoadDidChangeLocationWithinPageForFrame.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/PreventEmptyUserAgent.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/PrivateBrowsingPushStateNoHistoryCallback.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/RestoreSessionStateContainingFormData.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/TerminateTwice.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/UserMessage.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/WKConnection.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/WKPageGetScaleFactorNotZero.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/WKPreferences.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/WKString.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/WKStringJSString.cpp - -if ENABLE_WEBKIT2 -noinst_LTLIBRARIES += \ - Libraries/libTestWebKitAPIInjectedBundle.la -endif # ENABLE_WEBKIT2 - -Libraries_libTestWebKitAPIInjectedBundle_la_SOURCES = \ - Tools/TestWebKitAPI/InjectedBundleController.cpp \ - Tools/TestWebKitAPI/InjectedBundleController.h \ - Tools/TestWebKitAPI/InjectedBundleMain.cpp \ - Tools/TestWebKitAPI/InjectedBundleTest.h \ - Tools/TestWebKitAPI/PlatformUtilities.cpp \ - Tools/TestWebKitAPI/PlatformUtilities.h \ - Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/UserMessage_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent_Bundle.cpp \ - Tools/TestWebKitAPI/Tests/WebKit2/WKConnection_Bundle.cpp \ - Tools/TestWebKitAPI/gtk/InjectedBundleControllerGtk.cpp \ - Tools/TestWebKitAPI/gtk/PlatformUtilitiesGtk.cpp - -Libraries_libTestWebKitAPIInjectedBundle_la_LDFLAGS = \ - -rpath ${shell pwd}/$(top_builddir)/Libraries/.libs \ - $(no_undefined) \ - -avoid-version \ - -module - -Libraries_libTestWebKitAPIInjectedBundle_la_CPPFLAGS = \ - $(Libraries_libTestWebKitAPIMain_la_CPPFLAGS) \ - -I$(top_builddir)/DerivedSources/InjectedBundle \ - $(GTK_CFLAGS) - -Libraries_libTestWebKitAPIInjectedBundle_la_CXXFLAGS = \ - -DGTEST_HAS_RTTI=0 \ - $(global_cxxflags) - -Libraries_libTestWebKitAPIInjectedBundle_la_CFLAGS = \ - $(global_cflags) - - -stamp-testwebkitapi-webcore-forwarding-headers: $(WebKit2)/Scripts/generate-forwarding-headers.pl $(Programs_TestWebKitAPI_TestWebCore_SOURCES) - $(AM_V_GEN)$(PERL) $< $(srcdir)/Tools/TestWebKitAPI/Tests/WebCore $(GENSOURCES_WEBCORE)/include gtk \ - && echo timestamp > $(@F) - -stamp-testwebkitapi-webkit2-forwarding-headers: $(WebKit2)/Scripts/generate-forwarding-headers.pl $(Programs_TestWebKitAPI_TestWebKit2_SOURCES) $(Libraries_libTestWebKitAPIInjectedBundle_la_SOURCES) - $(AM_V_GEN)$(PERL) $< $(srcdir)/Tools/TestWebKitAPI $(GENSOURCES_WEBKIT2)/include gtk \ - && echo timestamp > $(@F) - -BUILT_SOURCES += $(top_builddir)/stamp-testwebkitapi-webcore-forwarding-headers -if ENABLE_WEBKIT2 -BUILT_SOURCES += $(top_builddir)/stamp-testwebkitapi-webkit2-forwarding-headers -endif # ENABLE_WEBKIT2 - - -EXTRA_DIST += \ - Tools/TestWebKitAPI/Tests/WebKit2/18-characters.html \ - Tools/TestWebKitAPI/Tests/WebKit2/file-with-anchor.html \ - Tools/TestWebKitAPI/Tests/WebKit2/find.html \ - Tools/TestWebKitAPI/Tests/WebKit2/icon.png \ - Tools/TestWebKitAPI/Tests/WebKit2/lots-of-iframes.html \ - Tools/TestWebKitAPI/Tests/WebKit2/lots-of-images.html \ - Tools/TestWebKitAPI/Tests/WebKit2/lots-of-text.html \ - Tools/TestWebKitAPI/Tests/WebKit2/mouse-move-listener.html \ - Tools/TestWebKitAPI/Tests/WebKit2/push-state.html \ - Tools/TestWebKitAPI/Tests/WebKit2/simple-accelerated-compositing.html \ - Tools/TestWebKitAPI/Tests/WebKit2/simple-form.html \ - Tools/TestWebKitAPI/Tests/WebKit2/simple.html \ - Tools/TestWebKitAPI/Tests/WebKit2/simple-iframe.html \ - Tools/TestWebKitAPI/Tests/WebKit2/simple-tall.html \ - Tools/TestWebKitAPI/Tests/WebKit2/spacebar-scrolling.html diff --git a/Tools/TestWebKitAPI/InjectedBundle-Info.plist b/Tools/TestWebKitAPI/InjectedBundle-Info.plist deleted file mode 100644 index c285a472c..000000000 --- a/Tools/TestWebKitAPI/InjectedBundle-Info.plist +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundlePackageType</key> - <string>BNDL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1</string> -</dict> -</plist> diff --git a/Tools/TestWebKitAPI/InjectedBundle.pri b/Tools/TestWebKitAPI/InjectedBundle.pri deleted file mode 100644 index 171a200f0..000000000 --- a/Tools/TestWebKitAPI/InjectedBundle.pri +++ /dev/null @@ -1,56 +0,0 @@ -# ------------------------------------------------------------------- -# Project file for TestWebKitAPI's InjectedBundle -# -# See 'Tools/qmake/README' for an overview of the build system -# ------------------------------------------------------------------- - -TEMPLATE = lib -TARGET = TestWebKitAPIInjectedBundle - -INCLUDEPATH += $$PWD -INCLUDEPATH += $${ROOT_WEBKIT_DIR}/Source/ThirdParty/gtest/include - -SOURCES += \ - $$PWD/InjectedBundleController.cpp \ - $$PWD/InjectedBundleController.h \ - $$PWD/InjectedBundleMain.cpp \ - $$PWD/InjectedBundleTest.h \ - $$PWD/PlatformUtilities.cpp \ - $$PWD/PlatformUtilities.h \ - $$PWD/qt/InjectedBundleControllerQt.cpp \ - $$PWD/qt/PlatformUtilitiesQt.cpp \ - $$PWD/Tests/WebKit2/CanHandleRequest_Bundle.cpp \ - $$PWD/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp \ - $$PWD/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp \ - $$PWD/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp \ - $$PWD/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback_Bundle.cpp \ - $$PWD/Tests/WebKit2/HitTestResultNodeHandle_Bundle.cpp \ - $$PWD/Tests/WebKit2/InjectedBundleBasic_Bundle.cpp \ - $$PWD/Tests/WebKit2/InjectedBundleFrameHitTest_Bundle.cpp \ - $$PWD/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp \ - $$PWD/Tests/WebKit2/LoadCanceledNoServerRedirectCallback_Bundle.cpp \ - $$PWD/Tests/WebKit2/MouseMoveAfterCrash_Bundle.cpp \ - $$PWD/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout_Bundle.cpp \ - $$PWD/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp \ - $$PWD/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp \ - $$PWD/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp \ - $$PWD/Tests/WebKit2/ParentFrame_Bundle.cpp \ - $$PWD/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly_Bundle.cpp \ - $$PWD/Tests/WebKit2/ShouldGoToBackForwardListItem_Bundle.cpp \ - $$PWD/Tests/WebKit2/UserMessage_Bundle.cpp \ - $$PWD/Tests/WebKit2/WillSendSubmitEvent_Bundle.cpp \ - $$PWD/Tests/WebKit2/WKConnection_Bundle.cpp - - -DESTDIR = $${ROOT_BUILD_DIR}/lib - -QT += core webkit - -WEBKIT += wtf javascriptcore webcore webkit2 - -CONFIG += plugin rpath compiling_thirdparty_code - -LIBS += -L$${ROOT_BUILD_DIR}/Source/ThirdParty/gtest/$$targetSubDir() -lgtest - -DEFINES += APITEST_SOURCE_DIR=\\\"$$PWD\\\" \ - ROOT_BUILD_DIR=\\\"$${ROOT_BUILD_DIR}\\\" diff --git a/Tools/TestWebKitAPI/InjectedBundleController.cpp b/Tools/TestWebKitAPI/InjectedBundleController.cpp index fb78013ee..53f39a874 100644 --- a/Tools/TestWebKitAPI/InjectedBundleController.cpp +++ b/Tools/TestWebKitAPI/InjectedBundleController.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleController.h" #include "InjectedBundleTest.h" @@ -33,7 +36,7 @@ namespace TestWebKitAPI { -InjectedBundleController& InjectedBundleController::shared() +InjectedBundleController& InjectedBundleController::singleton() { static InjectedBundleController& shared = *new InjectedBundleController; return shared; @@ -54,16 +57,15 @@ void InjectedBundleController::initialize(WKBundleRef bundle, WKTypeRef initiali if (!initializationUserData) return; - WKBundleClient client = { - 0, - this, + WKBundleClientV1 client = { + { 0, this }, didCreatePage, willDestroyPage, didInitializePageGroup, didReceiveMessage, didReceiveMessageToPage }; - WKBundleSetClient(m_bundle, &client); + WKBundleSetClient(m_bundle, &client.base); // Initialize the test from the "initializationUserData". @@ -139,3 +141,5 @@ void InjectedBundleController::registerCreateInjectedBundleTestFunction(const st } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/InjectedBundleController.h b/Tools/TestWebKitAPI/InjectedBundleController.h index 0ca112584..eaa7f0d17 100644 --- a/Tools/TestWebKitAPI/InjectedBundleController.h +++ b/Tools/TestWebKitAPI/InjectedBundleController.h @@ -26,7 +26,7 @@ #ifndef InjectedBundleController_h #define InjectedBundleController_h -#include <WebKit2/WKBundle.h> +#include <WebKit/WKBundle.h> #include <map> #include <string> @@ -36,7 +36,7 @@ class InjectedBundleTest; class InjectedBundleController { public: - static InjectedBundleController& shared(); + static InjectedBundleController& singleton(); void initialize(WKBundleRef, WKTypeRef); diff --git a/Tools/TestWebKitAPI/InjectedBundleMain.cpp b/Tools/TestWebKitAPI/InjectedBundleMain.cpp index 8ad6c2bad..b2537f737 100644 --- a/Tools/TestWebKitAPI/InjectedBundleMain.cpp +++ b/Tools/TestWebKitAPI/InjectedBundleMain.cpp @@ -24,8 +24,11 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleController.h" -#include <WebKit2/WKBundleInitialize.h> +#include <WebKit/WKBundleInitialize.h> #if defined(WIN32) || defined(_WIN32) extern "C" __declspec(dllexport) @@ -34,5 +37,7 @@ extern "C" #endif void WKBundleInitialize(WKBundleRef bundle, WKTypeRef initializationUserData) { - TestWebKitAPI::InjectedBundleController::shared().initialize(bundle, initializationUserData); + TestWebKitAPI::InjectedBundleController::singleton().initialize(bundle, initializationUserData); } + +#endif diff --git a/Tools/TestWebKitAPI/InjectedBundleTest.h b/Tools/TestWebKitAPI/InjectedBundleTest.h index d0f996aff..ad2cb9581 100644 --- a/Tools/TestWebKitAPI/InjectedBundleTest.h +++ b/Tools/TestWebKitAPI/InjectedBundleTest.h @@ -48,7 +48,7 @@ public: public: Register(const std::string& test) { - InjectedBundleController::shared().registerCreateInjectedBundleTestFunction(test, Register::create); + InjectedBundleController::singleton().registerCreateInjectedBundleTestFunction(test, Register::create); } private: diff --git a/Tools/TestWebKitAPI/JavaScriptTest.cpp b/Tools/TestWebKitAPI/JavaScriptTest.cpp index 85be89252..133d99eee 100644 --- a/Tools/TestWebKitAPI/JavaScriptTest.cpp +++ b/Tools/TestWebKitAPI/JavaScriptTest.cpp @@ -24,15 +24,18 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "JavaScriptTest.h" #include "PlatformUtilities.h" #include "Test.h" #include <JavaScriptCore/JSContextRef.h> #include <JavaScriptCore/JSRetainPtr.h> -#include <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKSerializedScriptValue.h> -#include <wtf/OwnArrayPtr.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKSerializedScriptValue.h> +#include <wtf/StdLibExtras.h> namespace TestWebKitAPI { @@ -72,7 +75,7 @@ static void javaScriptCallback(WKSerializedScriptValueRef resultSerializedScript Util::run(&context.didFinish); size_t bufferSize = JSStringGetMaximumUTF8CStringSize(context.actualString.get()); - OwnArrayPtr<char> buffer = adoptArrayPtr(new char[bufferSize]); + auto buffer = std::make_unique<char[]>(bufferSize); JSStringGetUTF8CString(context.actualString.get(), buffer.get(), bufferSize); return compareJSResult(script, buffer.get(), expectedResult); @@ -90,3 +93,5 @@ static void javaScriptCallback(WKSerializedScriptValueRef resultSerializedScript } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/JavaScriptTest.h b/Tools/TestWebKitAPI/JavaScriptTest.h index c6e79c3b6..c0494b2ca 100644 --- a/Tools/TestWebKitAPI/JavaScriptTest.h +++ b/Tools/TestWebKitAPI/JavaScriptTest.h @@ -23,14 +23,9 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if PLATFORM(MAC) -#ifdef __OBJC__ -@class WKView; -@class WebView; -#else -class WKView; -class WebView; -#endif +#if PLATFORM(COCOA) +OBJC_CLASS WKView; +OBJC_CLASS WebView; #endif namespace TestWebKitAPI { @@ -44,7 +39,7 @@ namespace TestWebKitAPI { ::testing::AssertionResult runJSTest(const char* pageExpr, const char* scriptExpr, const char* expectedResultExpr, WKPageRef, const char* script, const char* expectedResult); ::testing::AssertionResult compareJSResult(const char* script, const char* actualResult, const char* expectedResult); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) ::testing::AssertionResult runJSTest(const char* webViewExpr, const char* scriptExpr, const char* expectedResultExpr, WebView *, const char* script, const char* expectedResult); ::testing::AssertionResult runJSTest(const char* viewExpr, const char* scriptExpr, const char* expectedResultExpr, WKView *, const char* script, const char* expectedResult); #endif diff --git a/Tools/TestWebKitAPI/Makefile b/Tools/TestWebKitAPI/Makefile deleted file mode 100644 index ed01cce4c..000000000 --- a/Tools/TestWebKitAPI/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Build TestWebKitAPI only on Snow Leopard and later. - -OSX_VERSION ?= $(shell sw_vers -productVersion | cut -d. -f 2) -BUILD_TESTWEBKITAPI = $(shell (( $(OSX_VERSION) >= 6 )) && echo "YES" ) - -ifeq "$(BUILD_TESTWEBKITAPI)" "YES" - -SCRIPTS_PATH = ../Scripts -include ../../Makefile.shared - -else - -all: ; - -debug d development dev develop: ; - -release r deployment dep deploy: ; - -clean: ; - -endif diff --git a/Tools/TestWebKitAPI/PlatformEfl.cmake b/Tools/TestWebKitAPI/PlatformEfl.cmake deleted file mode 100644 index 28eaf77f5..000000000 --- a/Tools/TestWebKitAPI/PlatformEfl.cmake +++ /dev/null @@ -1,130 +0,0 @@ -add_custom_target(forwarding-headersEflForTestWebKitAPI - COMMAND ${PERL_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-forwarding-headers.pl ${WEBKIT2_DIR} ${DERIVED_SOURCES_WEBKIT2_DIR}/include efl - COMMAND ${PERL_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-forwarding-headers.pl ${WEBKIT2_DIR} ${DERIVED_SOURCES_WEBKIT2_DIR}/include CoordinatedGraphics - COMMAND ${PERL_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-forwarding-headers.pl ${TESTWEBKITAPI_DIR} ${DERIVED_SOURCES_WEBKIT2_DIR}/include efl -) -set(ForwardingHeadersForTestWebKitAPI_NAME forwarding-headersEflForTestWebKitAPI) - -add_custom_target(forwarding-headersSoupForTestWebKitAPI - COMMAND ${PERL_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-forwarding-headers.pl ${WEBKIT2_DIR} ${DERIVED_SOURCES_WEBKIT2_DIR}/include soup - COMMAND ${PERL_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-forwarding-headers.pl ${TESTWEBKITAPI_DIR} ${DERIVED_SOURCES_WEBKIT2_DIR}/include soup -) -set(ForwardingNetworkHeadersForTestWebKitAPI_NAME forwarding-headersSoupForTestWebKitAPI) - -include_directories( - ${WEBKIT2_DIR}/UIProcess/API/C/CoordinatedGraphics - ${WEBKIT2_DIR}/UIProcess/API/C/soup - ${WEBKIT2_DIR}/UIProcess/API/C/efl - ${WEBKIT2_DIR}/UIProcess/API/efl - ${ECORE_EVAS_INCLUDE_DIRS} - ${ECORE_INCLUDE_DIRS} - ${EINA_INCLUDE_DIRS} - ${EO_INCLUDE_DIRS} - ${EVAS_INCLUDE_DIRS} - ${GLIB_INCLUDE_DIRS} - ${LIBSOUP_INCLUDE_DIRS} -) - -set(test_main_SOURCES - ${TESTWEBKITAPI_DIR}/efl/main.cpp -) - -set(bundle_harness_SOURCES - ${TESTWEBKITAPI_DIR}/efl/InjectedBundleController.cpp - ${TESTWEBKITAPI_DIR}/efl/PlatformUtilities.cpp -) - -set(webkit2_api_harness_SOURCES - ${TESTWEBKITAPI_DIR}/efl/PlatformUtilities.cpp - ${TESTWEBKITAPI_DIR}/efl/PlatformWebView.cpp -) - -# The list below works like a test expectation. Tests in the -# test_{webkit2_api|webcore}_BINARIES list are added to the test runner and -# tried on the bots on every build. Tests in test_{webkit2_api|webcore}_BINARIES -# are compiled and suffixed with fail and skipped from the test runner. -# -# Make sure that the tests are passing on both Debug and -# Release builds before adding it to test_{webkit2_api|webcore}_BINARIES. - -set(test_webcore_BINARIES - LayoutUnit - KURL -) - -# In here we list the bundles that are used by our specific WK2 API Tests -list(APPEND bundle_harness_SOURCES - ${TESTWEBKITAPI_DIR}/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks_Bundle.cpp -) - -set(test_webkit2_api_BINARIES - AboutBlankLoad - CloseThenTerminate - CookieManager - DidAssociateFormControls - DOMWindowExtensionNoCache - DocumentStartUserScriptAlertCrash - EvaluateJavaScript - FailedLoad - Find - ForceRepaint - FrameMIMETypeHTML - FrameMIMETypePNG - GetInjectedBundleInitializationUserDataCallback - HitTestResultNodeHandle - InjectedBundleBasic - InjectedBundleFrameHitTest - InjectedBundleInitializationUserDataCallbackWins - LoadAlternateHTMLStringWithNonDirectoryURL - LoadCanceledNoServerRedirectCallback - LoadPageOnCrash - MouseMoveAfterCrash - NewFirstVisuallyNonEmptyLayout - NewFirstVisuallyNonEmptyLayoutFails - NewFirstVisuallyNonEmptyLayoutForImages - PageLoadBasic - PageLoadDidChangeLocationWithinPageForFrame - PageVisibilityState - ParentFrame - PreventEmptyUserAgent - PrivateBrowsingPushStateNoHistoryCallback - ReloadPageAfterCrash - ResizeWindowAfterCrash - ResponsivenessTimerDoesntFireEarly - TerminateTwice - UserMessage - WKConnection - WKPreferences - WKString - WKStringJSString - WKURL - WillLoad - WillSendSubmitEvent - CoordinatedGraphics/WKViewUserViewportToContents - efl/WKViewClientWebProcessCallbacks -) - -# Seccomp filters is an internal API and its symbols -# are not (and should not) be exposed by default. We -# can only test it when building shared core. -if (ENABLE_SECCOMP_FILTERS AND SHARED_CORE) - list(APPEND test_webkit2_api_BINARIES - SeccompFilters - ) -endif () - -set(test_webkit2_api_fail_BINARIES - CanHandleRequest - DOMWindowExtensionBasic - DownloadDecideDestinationCrash - NewFirstVisuallyNonEmptyLayoutFrames - ResizeReversePaginatedWebView - RestoreSessionStateContainingFormData - ScrollPinningBehaviors - ShouldGoToBackForwardListItem - WKPageGetScaleFactorNotZero -) - -# Tests disabled because of missing features on the test harness: -# -# SpacebarScrolling diff --git a/Tools/TestWebKitAPI/PlatformQt.cmake b/Tools/TestWebKitAPI/PlatformQt.cmake new file mode 100644 index 000000000..fe3808685 --- /dev/null +++ b/Tools/TestWebKitAPI/PlatformQt.cmake @@ -0,0 +1,54 @@ +set(TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/TestWebKitAPI") +set(TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY_WTF "${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY}/WTF") + +include_directories( + ${DERIVED_SOURCES_DIR}/ForwardingHeaders + ${DERIVED_SOURCES_DIR}/ForwardingHeaders/JavaScriptCore + ${TESTWEBKITAPI_DIR} +) + +include_directories(SYSTEM + ${ICU_INCLUDE_DIRS} + ${Qt5Gui_INCLUDE_DIRS} +) + +add_definitions( + -DROOT_BUILD_DIR="${CMAKE_BINARY_DIR}" + -DQT_NO_CAST_FROM_ASCII +) + +if (WIN32) + add_definitions(-DUSE_CONSOLE_ENTRY_POINT) + add_definitions(-DWEBCORE_EXPORT=) + add_definitions(-DSTATICALLY_LINKED_WITH_WTF) +endif () + +set(test_main_SOURCES + ${TESTWEBKITAPI_DIR}/qt/main.cpp +) + +list(APPEND test_wtf_LIBRARIES + ${Qt5Gui_LIBRARIES} +) + +set(test_webcore_LIBRARIES + WebCore + gtest + ${Qt5Gui_LIBRARIES} + ${DEPEND_STATIC_LIBS} +) + +add_executable(TestWebCore + ${test_main_SOURCES} + ${TESTWEBKITAPI_DIR}/TestsController.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebCore/LayoutUnit.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebCore/URL.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebCore/SharedBuffer.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebCore/FileSystem.cpp + ${TESTWEBKITAPI_DIR}/Tests/WebCore/PublicSuffix.cpp +) + +target_link_libraries(TestWebCore ${test_webcore_LIBRARIES}) +add_test(TestWebCore ${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY}/WebCore/TestWebCore) +set_tests_properties(TestWebCore PROPERTIES TIMEOUT 60) +set_target_properties(TestWebCore PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${TESTWEBKITAPI_RUNTIME_OUTPUT_DIRECTORY}/WebCore) diff --git a/Tools/TestWebKitAPI/PlatformUtilities.cpp b/Tools/TestWebKitAPI/PlatformUtilities.cpp index 1ded2a94c..216c70ac2 100644 --- a/Tools/TestWebKitAPI/PlatformUtilities.cpp +++ b/Tools/TestWebKitAPI/PlatformUtilities.cpp @@ -24,14 +24,16 @@ */ #include "config.h" + #include "PlatformUtilities.h" -#include <wtf/OwnArrayPtr.h> -#include <wtf/PassOwnArrayPtr.h> +#include <wtf/StdLibExtras.h> namespace TestWebKitAPI { namespace Util { +#if WK_HAVE_C_SPI + WKContextRef createContextWithInjectedBundle() { WKRetainPtr<WKStringRef> injectedBundlePath(AdoptWK, createInjectedBundlePath()); @@ -46,10 +48,10 @@ WKDictionaryRef createInitializationDictionaryForInjectedBundleTest(const std::s WKRetainPtr<WKStringRef> testNameKey(AdoptWK, WKStringCreateWithUTF8CString("TestName")); WKRetainPtr<WKStringRef> testNameString(AdoptWK, WKStringCreateWithUTF8CString(testName.c_str())); - WKDictionaryAddItem(initializationDictionary, testNameKey.get(), testNameString.get()); + WKDictionarySetItem(initializationDictionary, testNameKey.get(), testNameString.get()); WKRetainPtr<WKStringRef> userDataKey(AdoptWK, WKStringCreateWithUTF8CString("UserData")); - WKDictionaryAddItem(initializationDictionary, userDataKey.get(), userData); + WKDictionarySetItem(initializationDictionary, userDataKey.get(), userData); return initializationDictionary; } @@ -67,7 +69,7 @@ WKContextRef createContextForInjectedBundleTest(const std::string& testName, WKT std::string toSTD(WKStringRef string) { size_t bufferSize = WKStringGetMaximumUTF8CStringSize(string); - OwnArrayPtr<char> buffer = adoptArrayPtr(new char[bufferSize]); + auto buffer = std::make_unique<char[]>(bufferSize); size_t stringLength = WKStringGetUTF8CString(string, buffer.get(), bufferSize); return std::string(buffer.get(), stringLength - 1); } @@ -77,14 +79,16 @@ std::string toSTD(WKRetainPtr<WKStringRef> string) return toSTD(string.get()); } -std::string toSTD(const char* string) +WKRetainPtr<WKStringRef> toWK(const char* utf8String) { - return std::string(string); + return WKRetainPtr<WKStringRef>(AdoptWK, WKStringCreateWithUTF8CString(utf8String)); } -WKRetainPtr<WKStringRef> toWK(const char* utf8String) +#endif // WK_HAVE_C_SPI + +std::string toSTD(const char* string) { - return WKRetainPtr<WKStringRef>(AdoptWK, WKStringCreateWithUTF8CString(utf8String)); + return std::string(string); } } // namespace Util diff --git a/Tools/TestWebKitAPI/PlatformUtilities.h b/Tools/TestWebKitAPI/PlatformUtilities.h index 10da84d33..7583e4ee0 100644 --- a/Tools/TestWebKitAPI/PlatformUtilities.h +++ b/Tools/TestWebKitAPI/PlatformUtilities.h @@ -26,15 +26,12 @@ #ifndef PlatformUtilities_h #define PlatformUtilities_h -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKNativeEvent.h> +#include <WebKit/WKRetainPtr.h> #include <string> -#if PLATFORM(MAC) -#if __OBJC__ -@class NSString; -#else -class NSString; -#endif +#if USE(FOUNDATION) +OBJC_CLASS NSString; #endif namespace TestWebKitAPI { @@ -42,12 +39,14 @@ namespace Util { // Runs a platform runloop until the 'done' is true. void run(bool* done); +void sleep(double seconds); -#if PLATFORM(WIN) -bool shouldTranslateMessage(const MSG&); +std::string toSTD(const char*); +#if USE(FOUNDATION) +std::string toSTD(NSString *); #endif -void sleep(double seconds); +#if WK_HAVE_C_SPI WKContextRef createContextWithInjectedBundle(); WKContextRef createContextForInjectedBundleTest(const std::string&, WKTypeRef userData = 0); @@ -62,13 +61,11 @@ bool isKeyDown(WKNativeEventPtr); std::string toSTD(WKStringRef); std::string toSTD(WKRetainPtr<WKStringRef>); -std::string toSTD(const char*); -#if PLATFORM(MAC) -std::string toSTD(NSString *); -#endif WKRetainPtr<WKStringRef> toWK(const char* utf8String); +#endif // WK_HAVE_C_SPI + template<typename T, typename U> static inline ::testing::AssertionResult assertWKStringEqual(const char* expected_expression, const char* actual_expression, T expected, U actual) { @@ -78,6 +75,10 @@ static inline ::testing::AssertionResult assertWKStringEqual(const char* expecte #define EXPECT_WK_STREQ(expected, actual) \ EXPECT_PRED_FORMAT2(TestWebKitAPI::Util::assertWKStringEqual, expected, actual) +#if WK_API_ENABLED +extern NSString * const TestPlugInClassNameParameter; +#endif + } // namespace Util } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/PlatformWebView.h b/Tools/TestWebKitAPI/PlatformWebView.h index 3eb791a19..f6819cd5e 100644 --- a/Tools/TestWebKitAPI/PlatformWebView.h +++ b/Tools/TestWebKitAPI/PlatformWebView.h @@ -30,7 +30,11 @@ #include <CoreGraphics/CGGeometry.h> #endif -#ifdef __APPLE__ +#if PLATFORM(MAC) +#include <objc/objc.h> +#endif + +#if defined(__APPLE__) && !PLATFORM(GTK) #ifdef __OBJC__ @class WKView; @class NSWindow; @@ -40,19 +44,10 @@ class NSWindow; #endif typedef WKView *PlatformWKView; typedef NSWindow *PlatformWindow; -#elif defined(WIN32) || defined(_WIN32) -typedef WKViewRef PlatformWKView; -typedef HWND PlatformWindow; #elif PLATFORM(GTK) typedef WKViewRef PlatformWKView; typedef GtkWidget *PlatformWindow; #elif PLATFORM(EFL) -typedef struct _Ecore_Evas Ecore_Evas; -#if USE(EO) -typedef struct _Eo Evas_Object; -#else -typedef struct _Evas_Object Evas_Object; -#endif typedef Evas_Object* PlatformWKView; typedef Ecore_Evas* PlatformWindow; #elif PLATFORM(QT) @@ -66,13 +61,14 @@ typedef QQuickView* PlatformWindow; namespace TestWebKitAPI { -#if PLATFORM(WIN) -class WindowMessageObserver; -#endif - class PlatformWebView { public: - PlatformWebView(WKContextRef, WKPageGroupRef = 0); + explicit PlatformWebView(WKPageConfigurationRef); + explicit PlatformWebView(WKContextRef, WKPageGroupRef = 0); + explicit PlatformWebView(WKPageRef relatedPage); +#if PLATFORM(MAC) + explicit PlatformWebView(WKContextRef, WKPageGroupRef, Class wkViewSubclass); +#endif ~PlatformWebView(); WKPageRef page() const; @@ -84,24 +80,19 @@ public: void simulateAltKeyPress(); void simulateRightClick(unsigned x, unsigned y); void simulateMouseMove(unsigned x, unsigned y); - -#if PLATFORM(WIN) - void simulateAKeyDown(); - void setParentWindowMessageObserver(WindowMessageObserver* observer) { m_parentWindowMessageObserver = observer; } +#if PLATFORM(MAC) + void simulateButtonClick(WKEventMouseButton, unsigned x, unsigned y, WKEventModifiers); #endif private: -#if PLATFORM(WIN) - static void registerWindowClass(); - static LRESULT CALLBACK wndProc(HWND, UINT message, WPARAM, LPARAM); +#if PLATFORM(MAC) + void initialize(WKPageConfigurationRef, Class wkViewSubclass); +#elif PLATFORM(GTK) + void initialize(WKPageConfigurationRef); #endif PlatformWKView m_view; PlatformWindow m_window; - -#if PLATFORM(WIN) - WindowMessageObserver* m_parentWindowMessageObserver; -#endif }; } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Test.h b/Tools/TestWebKitAPI/Test.h index ca43924a2..cf44045fb 100644 --- a/Tools/TestWebKitAPI/Test.h +++ b/Tools/TestWebKitAPI/Test.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,6 +26,8 @@ #ifndef Test_h #define Test_h +#include <type_traits> + namespace TestWebKitAPI { #define EXPECT_NOT_NULL(expression) \ @@ -40,6 +42,18 @@ namespace TestWebKitAPI { #define ASSERT_NULL(expression) \ ASSERT_TRUE(!(expression)) +template<typename T> +static inline ::testing::AssertionResult assertStrongEnum(const char* expected_expression, const char* actual_expression, T expected, T actual) +{ + static_assert(std::is_enum<T>::value, "T is not an enum type"); + typedef typename std::underlying_type<T>::type UnderlyingStorageType; + return ::testing::internal::CmpHelperEQ(expected_expression, actual_expression, static_cast<UnderlyingStorageType>(expected), static_cast<UnderlyingStorageType>(actual)); +} + +#define EXPECT_STRONG_ENUM_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(TestWebKitAPI::assertStrongEnum, expected, actual) + + } // namespace TestWebKitAPI #endif // Test_h diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.pri b/Tools/TestWebKitAPI/TestWebKitAPI.pri deleted file mode 100644 index ddc9934f4..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.pri +++ /dev/null @@ -1,22 +0,0 @@ - -INCLUDEPATH += $$PWD $${ROOT_WEBKIT_DIR}/Source/ThirdParty/gtest/include -WEBKIT += wtf javascriptcore webkit2 - -DEFINES += QT_NO_CAST_FROM_ASCII - -QT += core core-private gui gui-private webkit quick quick-private - -CONFIG += compiling_thirdparty_code - -SOURCES += \ - $$PWD/JavaScriptTest.cpp \ - $$PWD/PlatformUtilities.cpp \ - $$PWD/TestsController.cpp \ - $$PWD/qt/main.cpp \ - $$PWD/qt/PlatformUtilitiesQt.cpp \ - $$PWD/qt/PlatformWebViewQt.cpp - -LIBS += -L$${ROOT_BUILD_DIR}/Source/ThirdParty/gtest/$$targetSubDir() -lgtest - -DEFINES += ROOT_BUILD_DIR=\\\"$${ROOT_BUILD_DIR}\\\" - diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.pro b/Tools/TestWebKitAPI/TestWebKitAPI.pro deleted file mode 100644 index b9d0cd5b6..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.pro +++ /dev/null @@ -1,11 +0,0 @@ -TEMPLATE = subdirs -CONFIG += ordered - -derived_sources.file = DerivedSources.pri -injected_bundle.file = InjectedBundle.pri -tests.file = Tests.pri - -SUBDIRS += derived_sources injected_bundle tests - -addStrictSubdirOrderBetween(derived_sources, injected_bundle) -addStrictSubdirOrderBetween(derived_sources, tests) diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.sln b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.sln deleted file mode 100644 index 38b2fd6b3..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.sln +++ /dev/null @@ -1,29 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestWebKitAPI", "TestWebKitAPI.vcxproj", "{AF94D13A-36C1-45FF-9B0B-EB5D3FF6F43D}" - ProjectSection(ProjectDependencies) = postProject - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-md", "..\..\..\Source\ThirdParty\gtest\msvc\gtest-md.vcxproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {AF94D13A-36C1-45FF-9B0B-EB5D3FF6F43D}.Debug|Win32.ActiveCfg = Debug|Win32 - {AF94D13A-36C1-45FF-9B0B-EB5D3FF6F43D}.Debug|Win32.Build.0 = Debug|Win32 - {AF94D13A-36C1-45FF-9B0B-EB5D3FF6F43D}.Release|Win32.ActiveCfg = Release|Win32 - {AF94D13A-36C1-45FF-9B0B-EB5D3FF6F43D}.Release|Win32.Build.0 = Release|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug|Win32.ActiveCfg = Debug|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug|Win32.Build.0 = Debug|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release|Win32.ActiveCfg = Release|Win32 - {C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj deleted file mode 100644 index d6db8309a..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj +++ /dev/null @@ -1,314 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="DebugSuffix|Win32"> - <Configuration>DebugSuffix</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="DebugSuffix|x64"> - <Configuration>DebugSuffix</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug_WinCairo|Win32"> - <Configuration>Debug_WinCairo</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug_WinCairo|x64"> - <Configuration>Debug_WinCairo</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Production|Win32"> - <Configuration>Production</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Production|x64"> - <Configuration>Production</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release_WinCairo|Win32"> - <Configuration>Release_WinCairo</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release_WinCairo|x64"> - <Configuration>Release_WinCairo</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{AF94D13A-36C1-45FF-9B0B-EB5D3FF6F43D}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>TestWebKitAPI</RootNamespace> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIDebug.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIDebug.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIDebugWinCairo.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIDebugWinCairo.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIDebug.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIDebug.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIRelease.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIRelease.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIReleaseWinCairo.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIReleaseWinCairo.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIProduction.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="TestWebKitAPIProduction.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" /> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - <Link /> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\config.h" /> - <ClInclude Include="..\Test.h" /> - <ClInclude Include="..\TestsController.h" /> - <ClInclude Include="..\win\HostWindow.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\TestsController.cpp" /> - <ClCompile Include="..\Tests\WebCore\LayoutUnit.cpp" /> - <ClCompile Include="..\Tests\WebCore\win\BitmapImage.cpp"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - </ClCompile> - <ClCompile Include="..\Tests\WebKit\win\WebViewDestruction.cpp" /> - <ClCompile Include="..\Tests\WTF\cf\RetainPtr.cpp" /> - <ClCompile Include="..\Tests\WTF\cf\RetainPtrHashing.cpp" /> - <ClCompile Include="..\Tests\WTF\CheckedArithmeticOperations.cpp" /> - <ClCompile Include="..\Tests\WTF\Functional.cpp" /> - <ClCompile Include="..\Tests\WTF\HashMap.cpp" /> - <ClCompile Include="..\Tests\WTF\MD5.cpp" /> - <ClCompile Include="..\Tests\WTF\MathExtras.cpp" /> - <ClCompile Include="..\Tests\WTF\MediaTime.cpp" /> - <ClCompile Include="..\Tests\WTF\SHA1.cpp" /> - <ClCompile Include="..\Tests\WTF\SaturatedArithmeticOperations.cpp" /> - <ClCompile Include="..\Tests\WTF\StringHasher.cpp" /> - <ClCompile Include="..\Tests\WTF\StringOperators.cpp" /> - <ClCompile Include="..\Tests\WTF\Vector.cpp" /> - <ClCompile Include="..\Tests\WTF\VectorBasic.cpp" /> - <ClCompile Include="..\Tests\WTF\VectorReverse.cpp" /> - <ClCompile Include="..\win\HostWindow.cpp" /> - <ClCompile Include="..\win\main.cpp" /> - </ItemGroup> - <ItemGroup> - <None Include="TestWebKitAPIPostBuild.cmd" /> - <None Include="TestWebKitAPIPreBuild.cmd" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters deleted file mode 100644 index 27cf75cb4..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters +++ /dev/null @@ -1,98 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Tests"> - <UniqueIdentifier>{80b7e5c5-5c50-4363-ae7b-a0956e6a688d}</UniqueIdentifier> - </Filter> - <Filter Include="win"> - <UniqueIdentifier>{e0b41579-994a-4d5e-9c2a-2ec14cd0c606}</UniqueIdentifier> - </Filter> - <Filter Include="Tests\WTF"> - <UniqueIdentifier>{87f2c8f6-8710-4785-a918-2aec42c9f1d3}</UniqueIdentifier> - </Filter> - <Filter Include="Tests\WebCore"> - <UniqueIdentifier>{77db1e64-3c2d-4de3-adc1-860d4ea1c3c2}</UniqueIdentifier> - </Filter> - <Filter Include="Tests\WebKit"> - <UniqueIdentifier>{f8236406-78aa-4c83-b393-b060b09405a3}</UniqueIdentifier> - </Filter> - <Filter Include="Tests\WTF\cf"> - <UniqueIdentifier>{909ce22a-2223-4afa-af44-2d0153f13cc6}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\config.h" /> - <ClInclude Include="..\Test.h" /> - <ClInclude Include="..\TestsController.h" /> - <ClInclude Include="..\win\HostWindow.h"> - <Filter>win</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\TestsController.cpp" /> - <ClCompile Include="..\win\HostWindow.cpp"> - <Filter>win</Filter> - </ClCompile> - <ClCompile Include="..\win\main.cpp"> - <Filter>win</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WebCore\win\BitmapImage.cpp"> - <Filter>Tests\WebCore</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WebCore\LayoutUnit.cpp"> - <Filter>Tests\WebCore</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WebKit\win\WebViewDestruction.cpp"> - <Filter>Tests\WebKit</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\CheckedArithmeticOperations.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\Functional.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\HashMap.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\MD5.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\MathExtras.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\MediaTime.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\SHA1.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\SaturatedArithmeticOperations.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\StringHasher.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\StringOperators.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\Vector.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\VectorBasic.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\VectorReverse.cpp"> - <Filter>Tests\WTF</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\cf\RetainPtr.cpp"> - <Filter>Tests\WTF\cf</Filter> - </ClCompile> - <ClCompile Include="..\Tests\WTF\cf\RetainPtrHashing.cpp"> - <Filter>Tests\WTF\cf</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="TestWebKitAPIPostBuild.cmd" /> - <None Include="TestWebKitAPIPreBuild.cmd" /> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPICommon.props b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPICommon.props deleted file mode 100644 index 07bdf91db..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPICommon.props +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup /> - <ItemDefinitionGroup> - <Link> - <SubSystem>Console</SubSystem> - <AdditionalDependencies>CFNetwork$(DebugSuffix).lib;CoreFoundation$(DebugSuffix).lib;WebKit$(DebugSuffix).lib;WTF$(DebugSuffix).lib;JavaScriptCore$(DebugSuffix).lib;gtest$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - <ClCompile> - <AdditionalIncludeDirectories>$(ProjectDir)..;$(ProjectDir)..\win;$(ConfigurationBuildDir)\Include;$(ConfigurationBuildDir)\Include\private\JavaScriptCore;$(ConfigurationBuildDir)\Include\WebCore\ForwardingHeaders;$(ConfigurationBuildDir)\Include\private;..\..\..\Source\ThirdParty\gtest\include;$(WebKit_Libraries)\include;$(WebKit_Libraries)\Include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup /> -</Project>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPICommonWinCairo.props b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPICommonWinCairo.props deleted file mode 100644 index 5b75cd8ba..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPICommonWinCairo.props +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup /> - <ItemDefinitionGroup> - <Link> - <SubSystem>Console</SubSystem> - <AdditionalDependencies>CFLite.lib;WebKit.lib;JavaScriptCore.lib;gtest.lib;WTF.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - <ClCompile> - <AdditionalIncludeDirectories>$(ProjectDir)..;$(ProjectDir)..\win;$(ConfigurationBuildDir)\Include;$(ConfigurationBuildDir)\Include\private\JavaScriptCore;$(ConfigurationBuildDir)\Include\WebCore\ForwardingHeaders;$(ConfigurationBuildDir)\Include\private;..\..\..\Source\ThirdParty\gtest\include;$(WebKit_Libraries)\include;$(WebKit_Libraries)\Include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup /> -</Project> diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIDebug.props b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIDebug.props deleted file mode 100644 index 76cef1409..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIDebug.props +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets"> - <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" /> - <Import Project="TestWebKitAPICommon.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup /> - <ItemDefinitionGroup /> - <ItemGroup /> -</Project>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIDebugWinCairo.props b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIDebugWinCairo.props deleted file mode 100644 index ce507e69c..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIDebugWinCairo.props +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets"> - <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefinesCairo.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\WinCairo.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\cURL.props" /> - <Import Project="TestWebKitAPICommonWinCairo.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup /> - <ItemDefinitionGroup /> - <ItemGroup /> -</Project> diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIPostBuild.cmd b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIPostBuild.cmd deleted file mode 100644 index 26707cac6..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIPostBuild.cmd +++ /dev/null @@ -1 +0,0 @@ -if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed" diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIPreBuild.cmd b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIPreBuild.cmd deleted file mode 100644 index a77077674..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIPreBuild.cmd +++ /dev/null @@ -1,6 +0,0 @@ -%SystemDrive%\cygwin\bin\which.exe bash -if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH% -cmd /c -if exist "%CONFIGURATIONBUILDDIR%\buildfailed" grep XX%PROJECTNAME%XX "%CONFIGURATIONBUILDDIR%\buildfailed" -if errorlevel 1 exit 1 -echo XX%PROJECTNAME%XX > "%CONFIGURATIONBUILDDIR%\buildfailed" diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIProduction.props b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIProduction.props deleted file mode 100644 index bac3a5bf2..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIProduction.props +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets"> - <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" /> - <Import Project="TestWebKitAPICommon.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup /> - <ItemDefinitionGroup /> - <ItemGroup /> -</Project>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIRelease.props b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIRelease.props deleted file mode 100644 index a25ac6c9b..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIRelease.props +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets"> - <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" /> - <Import Project="TestWebKitAPICommon.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup /> - <ItemDefinitionGroup /> - <ItemGroup /> -</Project>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIReleaseWinCairo.props b/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIReleaseWinCairo.props deleted file mode 100644 index 759c7fc3c..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPIReleaseWinCairo.props +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets"> - <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefinesCairo.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\WinCairo.props" /> - <Import Project="$(WebKit_Libraries)\tools\vsprops\cURL.props" /> - <Import Project="TestWebKitAPICommonWinCairo.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup /> - <ItemDefinitionGroup /> - <ItemGroup /> -</Project> diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj deleted file mode 100644 index c484361c0..000000000 --- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1359 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 45; - objects = { - -/* Begin PBXBuildFile section */ - 00BC16871680FE810065F1E5 /* PublicSuffix.mm in Sources */ = {isa = PBXBuildFile; fileRef = 00BC16851680FE810065F1E5 /* PublicSuffix.mm */; }; - 00CD9F6315BE312C002DA2CE /* BackForwardList.mm in Sources */ = {isa = PBXBuildFile; fileRef = 00CD9F6215BE312C002DA2CE /* BackForwardList.mm */; }; - 0BCD833514857CE400EA2003 /* HashMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BCD833414857CE400EA2003 /* HashMap.cpp */; }; - 0BCD856A1485C98B00EA2003 /* TemporaryChange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BCD85691485C98B00EA2003 /* TemporaryChange.cpp */; }; - 0F17BBD615AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F17BBD415AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp */; }; - 0FC6C4CC141027E0005B7F0C /* RedBlackTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */; }; - 0FC6C4CF141034AD005B7F0C /* MetaAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC6C4CE141034AD005B7F0C /* MetaAllocator.cpp */; }; - 14464013167A8305000BD218 /* LayoutUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14464012167A8305000BD218 /* LayoutUnit.cpp */; }; - 14F3B11315E45EAB00210069 /* SaturatedArithmeticOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F3B11215E45EAB00210069 /* SaturatedArithmeticOperations.cpp */; }; - 1A02C84F125D4A8400E3F4BD /* Find.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A02C84E125D4A8400E3F4BD /* Find.cpp */; }; - 1A02C870125D4CFD00E3F4BD /* find.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1A02C84B125D4A5E00E3F4BD /* find.html */; }; - 1A5FEFDD1270E2A3000E2921 /* EvaluateJavaScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5FEFDC1270E2A3000E2921 /* EvaluateJavaScript.cpp */; }; - 1A7BFC0C171A0BDB00BC5F64 /* WillSendSubmitEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A7BFC0A171A0BDB00BC5F64 /* WillSendSubmitEvent.mm */; }; - 1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C045F9461385C2F800C0F3CD /* 18-characters.html */; }; - 1AA9E55914980A9900001A8A /* Functional.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AA9E55714980A9900001A8A /* Functional.cpp */; }; - 1ADBEFAE130C689C00D61D19 /* ForceRepaint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADBEFAD130C689C00D61D19 /* ForceRepaint.cpp */; }; - 1ADBEFE3130C6AA100D61D19 /* simple-accelerated-compositing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */; }; - 1AE72F48173EB214006362F0 /* TerminateTwice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE72F47173EB214006362F0 /* TerminateTwice.cpp */; }; - 1AEDE22613E5E7E700E62FE8 /* InjectedBundleControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */; }; - 1AEF994917A09F5400998EF0 /* GetPIDAfterAbortedProcessLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AEF994817A09F5300998EF0 /* GetPIDAfterAbortedProcessLaunch.cpp */; }; - 261516D615B0E60500A2C201 /* SetAndUpdateCacheModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */; }; - 26300B1816755CD90066886D /* ListHashSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26300B1716755CD90066886D /* ListHashSet.cpp */; }; - 265AF55015D1E48A00B0CB4A /* WTFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265AF54F15D1E48A00B0CB4A /* WTFString.cpp */; }; - 266FAFD315E5775200F61D5B /* IntegerToStringConversion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266FAFD215E5775200F61D5B /* IntegerToStringConversion.cpp */; }; - 26A2C72F15E2E73C005B1A14 /* CString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A2C72E15E2E73C005B1A14 /* CString.cpp */; }; - 26B2DFF915BDE599004F691D /* HashSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26B2DFF815BDE599004F691D /* HashSet.cpp */; }; - 26DF5A5E15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */; }; - 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 */; }; - 290A9BB71735DE8A00D71BBC /* CloseNewWindowInNavigationPolicyDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 290A9BB51735DE8A00D71BBC /* CloseNewWindowInNavigationPolicyDelegate.mm */; }; - 290A9BB91735F63800D71BBC /* OpenNewWindow.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 290A9BB81735F42300D71BBC /* OpenNewWindow.html */; }; - 290F4275172A221C00939FF0 /* custom-protocol-sync-xhr.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 290F4274172A1FDE00939FF0 /* custom-protocol-sync-xhr.html */; }; - 290F4278172A232C00939FF0 /* CustomProtocolsSyncXHRTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 290F4276172A232C00939FF0 /* CustomProtocolsSyncXHRTest.mm */; }; - 290F427B172A23A500939FF0 /* TestProtocol.mm in Sources */ = {isa = PBXBuildFile; fileRef = 290F4279172A23A500939FF0 /* TestProtocol.mm */; }; - 291861FF17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm in Sources */ = {isa = PBXBuildFile; fileRef = 291861FD17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm */; }; - 2943BE86161DFEB800999E3D /* UserContentTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2943BE84161DFEB800999E3D /* UserContentTest.mm */; }; - 297234B4173AD04800983601 /* CustomProtocolsInvalidScheme.mm in Sources */ = {isa = PBXBuildFile; fileRef = 297234B2173AD04800983601 /* CustomProtocolsInvalidScheme.mm */; }; - 297234B7173AFAC700983601 /* CustomProtocolsInvalidScheme_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 297234B5173AFAC700983601 /* CustomProtocolsInvalidScheme_Bundle.cpp */; }; - 29AB8AA1164C735800D49BEC /* CustomProtocolsTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29AB8A9F164C735800D49BEC /* CustomProtocolsTest.mm */; }; - 29AB8AA4164C7A9300D49BEC /* TestBrowsingContextLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29AB8AA2164C7A9300D49BEC /* TestBrowsingContextLoadDelegate.mm */; }; - 2D640B5517875DFF00BFAF99 /* ScrollPinningBehaviors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D640B5417875DFF00BFAF99 /* ScrollPinningBehaviors.cpp */; }; - 2DD7D3AA178205D00026E1E3 /* ResizeReversePaginatedWebView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2DD7D3A9178205D00026E1E3 /* ResizeReversePaginatedWebView.cpp */; }; - 2DD7D3AF178227B30026E1E3 /* lots-of-text-vertical-lr.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */; }; - 2E7765CD16C4D80A00BA2BB1 /* mainIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */; }; - 2E7765CF16C4D81100BA2BB1 /* mainMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E7765CE16C4D81100BA2BB1 /* mainMac.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 */; }; - 33DC8911141953A300747EF7 /* LoadCanceledNoServerRedirectCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33DC8910141953A300747EF7 /* LoadCanceledNoServerRedirectCallback.cpp */; }; - 33DC8912141955FE00747EF7 /* simple-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 33DC890E1419539300747EF7 /* simple-iframe.html */; }; - 33DC89141419579F00747EF7 /* LoadCanceledNoServerRedirectCallback_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33DC89131419579F00747EF7 /* LoadCanceledNoServerRedirectCallback_Bundle.cpp */; }; - 33E79E06137B5FD900E32D99 /* mouse-move-listener.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 33E79E05137B5FCE00E32D99 /* mouse-move-listener.html */; }; - 37200B9213A16230007A4FAD /* VectorReverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37200B9113A16230007A4FAD /* VectorReverse.cpp */; }; - 3722C8691461E03E00C45D00 /* RenderedImageFromDOMRange.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */; }; - 3751AF7C169518F800764319 /* DOMNodeFromJSObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3751AF7A169518F800764319 /* DOMNodeFromJSObject.mm */; }; - 3776BC63150946BC0043A66D /* DeviceScaleFactorInDashboardRegions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3776BC62150946BC0043A66D /* DeviceScaleFactorInDashboardRegions.mm */; }; - 378E64731632646D00B6C676 /* InjectedBundleFrameHitTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 378E64711632646D00B6C676 /* InjectedBundleFrameHitTest.cpp */; }; - 378E64771632655E00B6C676 /* InjectedBundleFrameHitTest_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 378E64751632655D00B6C676 /* InjectedBundleFrameHitTest_Bundle.cpp */; }; - 378E64791632707400B6C676 /* link-with-title.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 378E647816326FDF00B6C676 /* link-with-title.html */; }; - 379028B614FABD92007E6B43 /* AcceptsFirstMouse.mm in Sources */ = {isa = PBXBuildFile; fileRef = 379028B514FABD92007E6B43 /* AcceptsFirstMouse.mm */; }; - 379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 379028B814FABE49007E6B43 /* acceptsFirstMouse.html */; }; - 3799AD3A14120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */; }; - 37A6895F148A9B50005100FA /* SubresourceErrorCrash.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A6895D148A9B50005100FA /* SubresourceErrorCrash.mm */; }; - 37DC678D140D7C5000ABCCDB /* DOMRangeOfString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */; }; - 37DC6791140D7D7600ABCCDB /* DOMRangeOfString.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */; }; - 37E1064C1697681800B78BD0 /* DOMHTMLTableCellElementCellAbove.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 37E1064B169767F700B78BD0 /* DOMHTMLTableCellElementCellAbove.html */; }; - 37E1064D16976C8500B78BD0 /* DOMHTMLTableCellCellAbove.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E1064A1697676400B78BD0 /* DOMHTMLTableCellCellAbove.mm */; }; - 37E38C34169B7D010084C28C /* WebViewDidRemoveFrameFromHierarchy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E38C33169B7D010084C28C /* WebViewDidRemoveFrameFromHierarchy.mm */; }; - 440A1D3914A0103A008A66F2 /* KURL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 440A1D3814A0103A008A66F2 /* KURL.cpp */; }; - 4BB4160216815B2600824238 /* JSWrapperForNodeInWebFrame.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4160116815B2600824238 /* JSWrapperForNodeInWebFrame.mm */; }; - 4BB4160416815F9100824238 /* ElementAtPointInWebFrame.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4160316815F9100824238 /* ElementAtPointInWebFrame.mm */; }; - 4BFDFFA71314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDFFA61314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp */; }; - 4BFDFFA9131477770061F24B /* HitTestResultNodeHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDFFA8131477770061F24B /* HitTestResultNodeHandle.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 */; }; - 5142B2731517C8C800C32B19 /* ContextMenuCanCopyURL.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5142B2721517C89100C32B19 /* ContextMenuCanCopyURL.html */; }; - 517E7DFC15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 517E7DFB15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm */; }; - 517E7E04151119C100D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 517E7E031511187500D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html */; }; - 51E93017156B13E1004C99DF /* WKPageGetScaleFactorNotZero.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51E93016156B13E1004C99DF /* WKPageGetScaleFactorNotZero.cpp */; }; - 51FBBB4D1513D4E900822738 /* WebViewCanPasteURL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51FBBB4C1513D4E900822738 /* WebViewCanPasteURL.mm */; }; - 51FCF79A1534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51FCF7981534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp */; }; - 51FCF7A11534B2A000104491 /* ShouldGoToBackForwardListItem_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51FCF7971534AC6D00104491 /* ShouldGoToBackForwardListItem_Bundle.cpp */; }; - 520BCF4C141EB09E00937EA8 /* WebArchive_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 520BCF4A141EB09E00937EA8 /* WebArchive_Bundle.cpp */; }; - 520BCF4D141EB09E00937EA8 /* WebArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 520BCF4B141EB09E00937EA8 /* WebArchive.cpp */; }; - 52B8CF9615868CF000281053 /* SetDocumentURI.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52B8CF9515868CF000281053 /* SetDocumentURI.mm */; }; - 52B8CF9815868D9100281053 /* SetDocumentURI.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 52B8CF9415868CF000281053 /* SetDocumentURI.html */; }; - 52CB47411448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52CB47401448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp */; }; - 52E5CE4614D21E9D003B2BD8 /* ParentFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E5CE4514D21E9D003B2BD8 /* ParentFrame.cpp */; }; - 52E5CE4914D21EAB003B2BD8 /* ParentFrame_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E5CE4814D21EAB003B2BD8 /* ParentFrame_Bundle.cpp */; }; - 76E182DA1547550100F1FADD /* WillSendSubmitEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76E182D91547550100F1FADD /* WillSendSubmitEvent.cpp */; }; - 76E182DD1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */; }; - 76E182DF154767E600F1FADD /* auto-submitting-form.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 76E182DE15475A8300F1FADD /* auto-submitting-form.html */; }; - 7C8DDAAB1735DEEE00EA5AC0 /* CloseThenTerminate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8DDAA91735DE1D00EA5AC0 /* CloseThenTerminate.cpp */; }; - 7CFBCADF1743234F00B2BFCF /* WillLoad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CFBCADD1743234F00B2BFCF /* WillLoad.cpp */; }; - 7CFBCAE51743238F00B2BFCF /* WillLoad_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CFBCAE31743238E00B2BFCF /* WillLoad_Bundle.cpp */; }; - 81B50193140F232300D9EB58 /* StringBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81B50192140F232300D9EB58 /* StringBuilder.cpp */; }; - 8A2C750E16CED9550024F352 /* ResizeWindowAfterCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A2C750D16CED9550024F352 /* ResizeWindowAfterCrash.cpp */; }; - 8A3AF93B16C9ED2700D248C1 /* ReloadPageAfterCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A3AF93A16C9ED2700D248C1 /* ReloadPageAfterCrash.cpp */; }; - 8AA28C1A16D2FA7B002FF4DB /* LoadPageOnCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8AA28C1916D2FA7B002FF4DB /* LoadPageOnCrash.cpp */; }; - 930AD402150698D00067970F /* lots-of-text.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 930AD401150698B30067970F /* lots-of-text.html */; }; - 9318778915EEC57700A9CCE3 /* NewFirstVisuallyNonEmptyLayoutForImages.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4ECA1506F035007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages.cpp */; }; - 9361002914DC95A70061379D /* lots-of-iframes.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9361002814DC957B0061379D /* lots-of-iframes.html */; }; - 939BA91714103412001A01BD /* DeviceScaleFactorOnBack.mm in Sources */ = {isa = PBXBuildFile; fileRef = 939BA91614103412001A01BD /* DeviceScaleFactorOnBack.mm */; }; - 93ABA80916DDAB91002DB2FA /* StringHasher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93ABA80816DDAB91002DB2FA /* StringHasher.cpp */; }; - 93AF4ECE1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */; }; - 93AF4ED01506F123007FD57E /* lots-of-images.html in Resources */ = {isa = PBXBuildFile; fileRef = 93AF4ECF1506F123007FD57E /* lots-of-images.html */; }; - 93AF4ED11506F130007FD57E /* lots-of-images.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93AF4ECF1506F123007FD57E /* lots-of-images.html */; }; - 93F1DB3114DA20760024C362 /* NewFirstVisuallyNonEmptyLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F1DB3014DA20760024C362 /* NewFirstVisuallyNonEmptyLayout.cpp */; }; - 93F1DB3414DA20870024C362 /* NewFirstVisuallyNonEmptyLayout_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F1DB3314DA20870024C362 /* NewFirstVisuallyNonEmptyLayout_Bundle.cpp */; }; - 93F1DB5514DB1B730024C362 /* NewFirstVisuallyNonEmptyLayoutFails.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F1DB5414DB1B730024C362 /* NewFirstVisuallyNonEmptyLayoutFails.cpp */; }; - 93F1DB5714DB1B840024C362 /* NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F1DB5614DB1B840024C362 /* NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp */; }; - 93F7E86C14DC8E4D00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F7E86B14DC8E4D00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames.cpp */; }; - 93F7E86F14DC8E5C00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */; }; - 9B26FC6C159D061000CC3765 /* HTMLFormCollectionNamedItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B26FC6B159D061000CC3765 /* HTMLFormCollectionNamedItem.mm */; }; - 9B26FCCA159D16DE00CC3765 /* HTMLFormCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */; }; - 9B4F8FA4159D52B1002D9F94 /* HTMLCollectionNamedItem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */; }; - 9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; }; - A51B650916ADF9B1007AA5D9 /* PageVisibilityState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A51B650816ADF9B1007AA5D9 /* PageVisibilityState.cpp */; }; - A57A34F016AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm in Sources */ = {isa = PBXBuildFile; fileRef = A57A34EF16AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm */; }; - A57A34F216AF6B2B00C2501F /* PageVisibilityStateWithWindowChanges.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A57A34F116AF69E200C2501F /* PageVisibilityStateWithWindowChanges.html */; }; - A5E2027315B2181900C13E14 /* WindowlessWebViewWithMedia.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */; }; - A5E2027515B21F6E00C13E14 /* WindowlessWebViewWithMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */; }; - A7A966DB140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A966DA140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp */; }; - B4039F9D15E6D8B3007255D6 /* MathExtras.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4039F9C15E6D8B3007255D6 /* MathExtras.cpp */; }; - B55AD1D2179F336C00AC1494 /* PreventImageLoadWithAutoResizing.mm in Sources */ = {isa = PBXBuildFile; fileRef = B55AD1D1179F336600AC1494 /* PreventImageLoadWithAutoResizing.mm */; }; - B55AD1D5179F3B3000AC1494 /* PreventImageLoadWithAutoResizing_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B55AD1D3179F3ABF00AC1494 /* PreventImageLoadWithAutoResizing_Bundle.cpp */; }; - B55F11A01516834F00915916 /* AttributedString.mm in Sources */ = {isa = PBXBuildFile; fileRef = B55F119F1516834F00915916 /* AttributedString.mm */; }; - B55F11B71517D03300915916 /* attributedStringCustomFont.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = B55F11B01517A2C400915916 /* attributedStringCustomFont.html */; }; - B55F11BE15191A0600915916 /* Ahem.ttf in Copy Resources */ = {isa = PBXBuildFile; fileRef = B55F11B9151916E600915916 /* Ahem.ttf */; }; - BC029B181486AD6400817DA9 /* RetainPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC029B161486AD6400817DA9 /* RetainPtr.cpp */; }; - BC029B1C1486B25900817DA9 /* RetainPtr.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC029B1B1486B25900817DA9 /* RetainPtr.mm */; }; - BC131885117114B600B69727 /* PlatformUtilitiesMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC131884117114B600B69727 /* PlatformUtilitiesMac.mm */; }; - BC131AA9117131FC00B69727 /* TestsController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC131AA8117131FC00B69727 /* TestsController.cpp */; }; - BC22D31514DC689800FFB1DD /* UserMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22D31314DC689800FFB1DD /* UserMessage.cpp */; }; - BC22D31914DC68B900FFB1DD /* UserMessage_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22D31714DC68B800FFB1DD /* UserMessage_Bundle.cpp */; }; - BC246D8E132F115A00B56D7C /* AboutBlankLoad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC246D8C132F115A00B56D7C /* AboutBlankLoad.cpp */; }; - BC246D9A132F1FE100B56D7C /* CanHandleRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC246D98132F1FE100B56D7C /* CanHandleRequest.cpp */; }; - BC246D9C132F1FF000B56D7C /* CanHandleRequest_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC246D97132F1FE100B56D7C /* CanHandleRequest_Bundle.cpp */; }; - BC2D004912A9FDFA00E732A3 /* PageLoadDidChangeLocationWithinPageForFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2D004812A9FDFA00E732A3 /* PageLoadDidChangeLocationWithinPageForFrame.cpp */; }; - BC2D006412AA04CE00E732A3 /* file-with-anchor.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = BC2D004A12A9FEB300E732A3 /* file-with-anchor.html */; }; - BC3C4C7214575B6A0025FB62 /* WKBrowsingContextLoadDelegateTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC3C4C7014575B6A0025FB62 /* WKBrowsingContextLoadDelegateTest.mm */; }; - BC3C4C7F14587AA60025FB62 /* WKBrowsingContextGroupTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC3C4C7D14587AA60025FB62 /* WKBrowsingContextGroupTest.mm */; }; - BC55F5F914AD78EE00484BE1 /* Vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC55F5F814AD78EE00484BE1 /* Vector.cpp */; }; - BC575A90126E74D3006F0F12 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCB9E9F011235BDE00A137E0 /* Cocoa.framework */; }; - BC575A91126E74D3006F0F12 /* WebKit2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCA61DB411700EFD00460D1E /* WebKit2.framework */; }; - BC575A92126E74D3006F0F12 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC90964D1255620C00083756 /* JavaScriptCore.framework */; }; - BC575A97126E74F1006F0F12 /* InjectedBundleMain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC575946126E7351006F0F12 /* InjectedBundleMain.cpp */; }; - BC575AA2126E7660006F0F12 /* InjectedBundleController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC575AA0126E7657006F0F12 /* InjectedBundleController.cpp */; }; - BC575AAD126E83B9006F0F12 /* InjectedBundleBasic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC575AAC126E83B9006F0F12 /* InjectedBundleBasic.cpp */; }; - BC575AB0126E83C8006F0F12 /* InjectedBundleBasic_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC575AAF126E83C8006F0F12 /* InjectedBundleBasic_Bundle.cpp */; }; - BC575BC0126F5752006F0F12 /* PlatformUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC575BBF126F5752006F0F12 /* PlatformUtilities.cpp */; }; - BC575BD9126F58E2006F0F12 /* PlatformUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC575BBF126F5752006F0F12 /* PlatformUtilities.cpp */; }; - BC575BE0126F590D006F0F12 /* PlatformUtilitiesMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC131884117114B600B69727 /* PlatformUtilitiesMac.mm */; }; - BC7B61AA129A038700D174A4 /* WKPreferences.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7B619A1299FE9E00D174A4 /* WKPreferences.cpp */; }; - BC901E241492ADCE0074A667 /* WKConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC901E221492ADCE0074A667 /* WKConnection.cpp */; }; - BC901E331492AF390074A667 /* WKConnection_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC901E311492AF390074A667 /* WKConnection_Bundle.cpp */; }; - BC90955D125548AA00083756 /* PlatformWebViewMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC90955C125548AA00083756 /* PlatformWebViewMac.mm */; }; - BC90964C125561BF00083756 /* VectorBasic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC90964B125561BF00083756 /* VectorBasic.cpp */; }; - BC90977A125571AB00083756 /* PageLoadBasic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC909779125571AB00083756 /* PageLoadBasic.cpp */; }; - BC909784125571CF00083756 /* simple.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = BC909778125571AB00083756 /* simple.html */; }; - BC90995E12567BC100083756 /* WKString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC90995D12567BC100083756 /* WKString.cpp */; }; - BC9099941256ACF100083756 /* WKStringJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC9099931256ACF100083756 /* WKStringJSString.cpp */; }; - BCAA485614A0444C0088FAC4 /* simple-tall.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = BCAA485514A021640088FAC4 /* simple-tall.html */; }; - BCAA485814A044D40088FAC4 /* EditorCommands.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCAA485714A044D40088FAC4 /* EditorCommands.mm */; }; - BCB68040126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB6803F126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp */; }; - BCB68042126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCB68041126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp */; }; - BCBD3710125AA2EB00D2C29F /* FrameMIMETypeHTML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCBD370F125AA2EB00D2C29F /* FrameMIMETypeHTML.cpp */; }; - BCBD3737125ABBEB00D2C29F /* icon.png in Copy Resources */ = {isa = PBXBuildFile; fileRef = BCBD372E125ABBE600D2C29F /* icon.png */; }; - BCBD3761125ABCFE00D2C29F /* FrameMIMETypePNG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCBD3760125ABCFE00D2C29F /* FrameMIMETypePNG.cpp */; }; - BCC8B95B12611F4700DE46A4 /* FailedLoad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC8B95A12611F4700DE46A4 /* FailedLoad.cpp */; }; - C01363C813C3997300EF3964 /* StringOperators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C01363C713C3997300EF3964 /* StringOperators.cpp */; }; - C01A23F21266156700C9ED55 /* spacebar-scrolling.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C02B7882126615410026BF0F /* spacebar-scrolling.html */; }; - C02B77F2126612140026BF0F /* SpacebarScrolling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C02B77F1126612140026BF0F /* SpacebarScrolling.cpp */; }; - C045F9451385C2EA00C0F3CD /* DownloadDecideDestinationCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C045F9441385C2E900C0F3CD /* DownloadDecideDestinationCrash.cpp */; }; - C07E6CAF13FD67650038B22B /* DynamicDeviceScaleFactor.mm in Sources */ = {isa = PBXBuildFile; fileRef = C07E6CAE13FD67650038B22B /* DynamicDeviceScaleFactor.mm */; }; - C07E6CB213FD73930038B22B /* devicePixelRatio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C07E6CB113FD738A0038B22B /* devicePixelRatio.html */; }; - C081224213FC172400DC39AE /* JavaScriptTestMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = C081224013FC172400DC39AE /* JavaScriptTestMac.mm */; }; - C081224513FC19EC00DC39AE /* SyntheticBackingScaleFactorWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = C081224413FC19EC00DC39AE /* SyntheticBackingScaleFactorWindow.m */; }; - C08587BF13FE956C001EF4E5 /* WebKitAgnosticTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = C08587BD13FE956C001EF4E5 /* WebKitAgnosticTest.mm */; }; - C08587FC13FEC39B001EF4E5 /* InstanceMethodSwizzler.mm in Sources */ = {isa = PBXBuildFile; fileRef = C08587FB13FEC39B001EF4E5 /* InstanceMethodSwizzler.mm */; }; - C085880013FEC3A6001EF4E5 /* InstanceMethodSwizzler.mm in Sources */ = {isa = PBXBuildFile; fileRef = C08587FF13FEC3A6001EF4E5 /* InstanceMethodSwizzler.mm */; }; - C0991C51143C7D68007998F2 /* RetainPtrHashing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0991C50143C7D68007998F2 /* RetainPtrHashing.cpp */; }; - C0ADBE7C12FCA4D000D2C129 /* JavaScriptTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0ADBE7A12FCA4D000D2C129 /* JavaScriptTest.cpp */; }; - C0ADBE8312FCA6AA00D2C129 /* RestoreSessionStateContainingFormData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0ADBE8212FCA6AA00D2C129 /* RestoreSessionStateContainingFormData.cpp */; }; - C0ADBE9612FCA79B00D2C129 /* simple-form.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C0ADBE8412FCA6B600D2C129 /* simple-form.html */; }; - C0BD669D131D3CF700E18F2A /* ResponsivenessTimerDoesntFireEarly.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0BD669C131D3CF700E18F2A /* ResponsivenessTimerDoesntFireEarly.cpp */; }; - C0BD669F131D3CFF00E18F2A /* ResponsivenessTimerDoesntFireEarly_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0BD669E131D3CFF00E18F2A /* ResponsivenessTimerDoesntFireEarly_Bundle.cpp */; }; - C0C5D3BE14598B6F00A802A6 /* GetBackingScaleFactor.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0C5D3BC14598B6F00A802A6 /* GetBackingScaleFactor.mm */; }; - C0C5D3C61459912900A802A6 /* GetBackingScaleFactor_Bundle.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0C5D3BD14598B6F00A802A6 /* GetBackingScaleFactor_Bundle.mm */; }; - C2CF975A16CEC7140054E99D /* JSContextBackForwardCache2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C2CF975916CEC69E0054E99D /* JSContextBackForwardCache2.html */; }; - C2CF975B16CEC71B0054E99D /* JSContextBackForwardCache1.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C2CF975816CEC69E0054E99D /* JSContextBackForwardCache1.html */; }; - C2EB2DD316CAC7AC009B52EE /* WebViewDidCreateJavaScriptContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2EB2DD116CAC7AC009B52EE /* WebViewDidCreateJavaScriptContext.mm */; }; - C507E8A714C6545B005D6B3B /* InspectorBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = C507E8A614C6545B005D6B3B /* InspectorBar.mm */; }; - C5101C4F176B8D9200EE9B15 /* findRanges.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C5101C4E176B8BB900EE9B15 /* findRanges.html */; }; - C51AFB99169F49FF009CCF66 /* FindMatches.mm in Sources */ = {isa = PBXBuildFile; fileRef = C51AFB98169F49FF009CCF66 /* FindMatches.mm */; }; - C540F776152E4DA000A40C8C /* SimplifyMarkup.mm in Sources */ = {isa = PBXBuildFile; fileRef = C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */; }; - C540F784152E5A9A00A40C8C /* verboseMarkup.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C540F783152E5A7800A40C8C /* verboseMarkup.html */; }; - C54237F016B8955800E638FC /* PasteboardNotifications.mm in Sources */ = {isa = PBXBuildFile; fileRef = C54237EE16B8955800E638FC /* PasteboardNotifications.mm */; }; - C54237F116B8957D00E638FC /* PasteboardNotifications_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C54237ED16B8955800E638FC /* PasteboardNotifications_Bundle.cpp */; }; - C5E1AFFE16B221F1006CC1F2 /* execCopy.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C5E1AFFD16B22179006CC1F2 /* execCopy.html */; }; - CD5393C81757BA9700C07123 /* MD5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5393C71757BA9700C07123 /* MD5.cpp */; }; - CD5393CA1757BAC400C07123 /* SHA1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5393C91757BAC400C07123 /* SHA1.cpp */; }; - CD5497B415857F0C00B5BC30 /* MediaTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5497B315857F0C00B5BC30 /* MediaTime.cpp */; }; - E1220DA0155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */; }; - E1220DCA155B28AA0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */; }; - E194E1BB177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm in Sources */ = {isa = PBXBuildFile; fileRef = E194E1BA177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm */; }; - E194E1BD177E53C7009C4D4E /* StopLoadingFromDidReceiveResponse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */; }; - E490296814E2E3A4002BEDD1 /* TypingStyleCrash.mm in Sources */ = {isa = PBXBuildFile; fileRef = E490296714E2E3A4002BEDD1 /* TypingStyleCrash.mm */; }; - E4A757D4178AF1B100B5D7A4 /* Deque.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A757D3178AEA5B00B5D7A4 /* Deque.cpp */; }; - F660AA0D15A5F061003A1243 /* GetInjectedBundleInitializationUserDataCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F660AA0C15A5F061003A1243 /* GetInjectedBundleInitializationUserDataCallback.cpp */; }; - F660AA1115A5F631003A1243 /* GetInjectedBundleInitializationUserDataCallback_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F660AA0F15A5F624003A1243 /* GetInjectedBundleInitializationUserDataCallback_Bundle.cpp */; }; - F660AA1315A619C9003A1243 /* InjectedBundleInitializationUserDataCallbackWins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F660AA1215A619C8003A1243 /* InjectedBundleInitializationUserDataCallbackWins.cpp */; }; - F660AA1515A61ABF003A1243 /* InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F660AA1415A61ABF003A1243 /* InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp */; }; - F6B7BE9417469209008A3445 /* DidAssociateFormControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6B7BE93174691EF008A3445 /* DidAssociateFormControls.cpp */; }; - F6B7BE9517469212008A3445 /* DidAssociateFormControls_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6B7BE92174691EF008A3445 /* DidAssociateFormControls_Bundle.cpp */; }; - F6B7BE9717469B96008A3445 /* associate-form-controls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F6B7BE9617469B7E008A3445 /* associate-form-controls.html */; }; - F6F3F29113342FEB00A6BF19 /* CookieManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6F3F29013342FEB00A6BF19 /* CookieManager.cpp */; }; - F6F49C6915545C8E0007F39D /* DOMWindowExtensionNoCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6F49C6715545C8D0007F39D /* DOMWindowExtensionNoCache.cpp */; }; - F6F49C6B15545CA70007F39D /* DOMWindowExtensionNoCache_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6F49C6615545C8D0007F39D /* DOMWindowExtensionNoCache_Bundle.cpp */; }; - F6FDDDD314241AD4004F1729 /* PrivateBrowsingPushStateNoHistoryCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6FDDDD214241AD4004F1729 /* PrivateBrowsingPushStateNoHistoryCallback.cpp */; }; - F6FDDDD614241C6F004F1729 /* push-state.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F6FDDDD514241C48004F1729 /* push-state.html */; }; - FE217ECD1640A54A0052988B /* VMInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE217ECC1640A54A0052988B /* VMInspector.cpp */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - BC575A95126E74E7006F0F12 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = BC57597F126E74AF006F0F12; - remoteInfo = InjectedBundle; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 8DD76F9E0486AA7600D96B5E /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; - BCB9F4FB112384C000A137E0 /* Copy Resources */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = TestWebKitAPI.resources; - dstSubfolderSpec = 7; - files = ( - 290A9BB91735F63800D71BBC /* OpenNewWindow.html in Copy Resources */, - 290F4275172A221C00939FF0 /* custom-protocol-sync-xhr.html in Copy Resources */, - C2CF975B16CEC71B0054E99D /* JSContextBackForwardCache1.html in Copy Resources */, - C2CF975A16CEC7140054E99D /* JSContextBackForwardCache2.html in Copy Resources */, - 1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */, - F6B7BE9717469B96008A3445 /* associate-form-controls.html in Copy Resources */, - 379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */, - B55F11BE15191A0600915916 /* Ahem.ttf in Copy Resources */, - B55F11B71517D03300915916 /* attributedStringCustomFont.html in Copy Resources */, - 76E182DF154767E600F1FADD /* auto-submitting-form.html in Copy Resources */, - 26DF5A6315A2A27E003689C2 /* CancelLoadFromResourceLoadDelegate.html in Copy Resources */, - 5142B2731517C8C800C32B19 /* ContextMenuCanCopyURL.html in Copy Resources */, - C07E6CB213FD73930038B22B /* devicePixelRatio.html in Copy Resources */, - 37E1064C1697681800B78BD0 /* DOMHTMLTableCellElementCellAbove.html in Copy Resources */, - 37DC6791140D7D7600ABCCDB /* DOMRangeOfString.html in Copy Resources */, - C5E1AFFE16B221F1006CC1F2 /* execCopy.html in Copy Resources */, - BC2D006412AA04CE00E732A3 /* file-with-anchor.html in Copy Resources */, - C5101C4F176B8D9200EE9B15 /* findRanges.html in Copy Resources */, - 1A02C870125D4CFD00E3F4BD /* find.html in Copy Resources */, - 9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */, - 9B26FCCA159D16DE00CC3765 /* HTMLFormCollectionNamedItem.html in Copy Resources */, - BCBD3737125ABBEB00D2C29F /* icon.png in Copy Resources */, - 378E64791632707400B6C676 /* link-with-title.html in Copy Resources */, - 9361002914DC95A70061379D /* lots-of-iframes.html in Copy Resources */, - 93AF4ED11506F130007FD57E /* lots-of-images.html in Copy Resources */, - 930AD402150698D00067970F /* lots-of-text.html in Copy Resources */, - 2DD7D3AF178227B30026E1E3 /* lots-of-text-vertical-lr.html in Copy Resources */, - E1220DCA155B28AA0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html in Copy Resources */, - 517E7E04151119C100D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html in Copy Resources */, - 33E79E06137B5FD900E32D99 /* mouse-move-listener.html in Copy Resources */, - A57A34F216AF6B2B00C2501F /* PageVisibilityStateWithWindowChanges.html in Copy Resources */, - F6FDDDD614241C6F004F1729 /* push-state.html in Copy Resources */, - 52B8CF9815868D9100281053 /* SetDocumentURI.html in Copy Resources */, - 1ADBEFE3130C6AA100D61D19 /* simple-accelerated-compositing.html in Copy Resources */, - C0ADBE9612FCA79B00D2C129 /* simple-form.html in Copy Resources */, - 33DC8912141955FE00747EF7 /* simple-iframe.html in Copy Resources */, - BCAA485614A0444C0088FAC4 /* simple-tall.html in Copy Resources */, - BC909784125571CF00083756 /* simple.html in Copy Resources */, - C01A23F21266156700C9ED55 /* spacebar-scrolling.html in Copy Resources */, - E194E1BD177E53C7009C4D4E /* StopLoadingFromDidReceiveResponse.html in Copy Resources */, - C540F784152E5A9A00A40C8C /* verboseMarkup.html in Copy Resources */, - A5E2027515B21F6E00C13E14 /* WindowlessWebViewWithMedia.html in Copy Resources */, - ); - name = "Copy Resources"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 00BC16851680FE810065F1E5 /* PublicSuffix.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PublicSuffix.mm; sourceTree = "<group>"; }; - 00CD9F6215BE312C002DA2CE /* BackForwardList.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BackForwardList.mm; sourceTree = "<group>"; }; - 0BCD833414857CE400EA2003 /* HashMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HashMap.cpp; path = WTF/HashMap.cpp; sourceTree = "<group>"; }; - 0BCD85691485C98B00EA2003 /* TemporaryChange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TemporaryChange.cpp; path = WTF/TemporaryChange.cpp; sourceTree = "<group>"; }; - 0F17BBD415AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCoreStatisticsWithNoWebProcess.cpp; sourceTree = "<group>"; }; - 0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RedBlackTree.cpp; path = WTF/RedBlackTree.cpp; sourceTree = "<group>"; }; - 0FC6C4CE141034AD005B7F0C /* MetaAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MetaAllocator.cpp; path = WTF/MetaAllocator.cpp; sourceTree = "<group>"; }; - 14464012167A8305000BD218 /* LayoutUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutUnit.cpp; sourceTree = "<group>"; }; - 14F3B11215E45EAB00210069 /* SaturatedArithmeticOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SaturatedArithmeticOperations.cpp; path = WTF/SaturatedArithmeticOperations.cpp; sourceTree = "<group>"; }; - 1A02C84B125D4A5E00E3F4BD /* find.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = find.html; sourceTree = "<group>"; }; - 1A02C84E125D4A8400E3F4BD /* Find.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Find.cpp; sourceTree = "<group>"; }; - 1A5FEFDC1270E2A3000E2921 /* EvaluateJavaScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EvaluateJavaScript.cpp; sourceTree = "<group>"; }; - 1A7BFC0A171A0BDB00BC5F64 /* WillSendSubmitEvent.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WillSendSubmitEvent.mm; sourceTree = "<group>"; }; - 1AA9E55714980A9900001A8A /* Functional.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Functional.cpp; path = WTF/Functional.cpp; sourceTree = "<group>"; }; - 1ADBEFAD130C689C00D61D19 /* ForceRepaint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ForceRepaint.cpp; sourceTree = "<group>"; }; - 1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-accelerated-compositing.html"; sourceTree = "<group>"; }; - 1AE72F47173EB214006362F0 /* TerminateTwice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TerminateTwice.cpp; sourceTree = "<group>"; }; - 1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundleControllerMac.mm; sourceTree = "<group>"; }; - 1AEF994817A09F5300998EF0 /* GetPIDAfterAbortedProcessLaunch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetPIDAfterAbortedProcessLaunch.cpp; sourceTree = "<group>"; }; - 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SetAndUpdateCacheModel.mm; sourceTree = "<group>"; }; - 26300B1716755CD90066886D /* ListHashSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ListHashSet.cpp; path = WTF/ListHashSet.cpp; sourceTree = "<group>"; }; - 265AF54F15D1E48A00B0CB4A /* WTFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WTFString.cpp; path = WTF/WTFString.cpp; sourceTree = "<group>"; }; - 266FAFD215E5775200F61D5B /* IntegerToStringConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IntegerToStringConversion.cpp; path = WTF/IntegerToStringConversion.cpp; sourceTree = "<group>"; }; - 26A2C72E15E2E73C005B1A14 /* CString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CString.cpp; path = WTF/CString.cpp; sourceTree = "<group>"; }; - 26B2DFF815BDE599004F691D /* HashSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HashSet.cpp; path = WTF/HashSet.cpp; sourceTree = "<group>"; }; - 26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CancelLoadFromResourceLoadDelegate.mm; sourceTree = "<group>"; }; - 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>"; }; - 290A9BB51735DE8A00D71BBC /* CloseNewWindowInNavigationPolicyDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CloseNewWindowInNavigationPolicyDelegate.mm; sourceTree = "<group>"; }; - 290A9BB81735F42300D71BBC /* OpenNewWindow.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = OpenNewWindow.html; sourceTree = "<group>"; }; - 290F4274172A1FDE00939FF0 /* custom-protocol-sync-xhr.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "custom-protocol-sync-xhr.html"; sourceTree = "<group>"; }; - 290F4276172A232C00939FF0 /* CustomProtocolsSyncXHRTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CustomProtocolsSyncXHRTest.mm; sourceTree = "<group>"; }; - 290F4279172A23A500939FF0 /* TestProtocol.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestProtocol.mm; sourceTree = "<group>"; }; - 290F427A172A23A500939FF0 /* TestProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestProtocol.h; sourceTree = "<group>"; }; - 291861FD17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StopLoadingFromDidFinishLoading.mm; sourceTree = "<group>"; }; - 2943BE84161DFEB800999E3D /* UserContentTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = UserContentTest.mm; path = WebKit2ObjC/UserContentTest.mm; sourceTree = "<group>"; }; - 297234B2173AD04800983601 /* CustomProtocolsInvalidScheme.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CustomProtocolsInvalidScheme.mm; path = WebKit2ObjC/CustomProtocolsInvalidScheme.mm; sourceTree = "<group>"; }; - 297234B5173AFAC700983601 /* CustomProtocolsInvalidScheme_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CustomProtocolsInvalidScheme_Bundle.cpp; path = WebKit2ObjC/CustomProtocolsInvalidScheme_Bundle.cpp; sourceTree = "<group>"; }; - 29AB8A9F164C735800D49BEC /* CustomProtocolsTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CustomProtocolsTest.mm; path = WebKit2ObjC/CustomProtocolsTest.mm; sourceTree = "<group>"; }; - 29AB8AA2164C7A9300D49BEC /* TestBrowsingContextLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestBrowsingContextLoadDelegate.mm; sourceTree = "<group>"; }; - 29AB8AA3164C7A9300D49BEC /* TestBrowsingContextLoadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestBrowsingContextLoadDelegate.h; sourceTree = "<group>"; }; - 2D640B5417875DFF00BFAF99 /* ScrollPinningBehaviors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollPinningBehaviors.cpp; sourceTree = "<group>"; }; - 2DD7D3A9178205D00026E1E3 /* ResizeReversePaginatedWebView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResizeReversePaginatedWebView.cpp; sourceTree = "<group>"; }; - 2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "lots-of-text-vertical-lr.html"; sourceTree = "<group>"; }; - 2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = mainIOS.mm; sourceTree = "<group>"; }; - 2E7765CE16C4D81100BA2BB1 /* mainMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = mainMac.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>"; }; - 33DC890E1419539300747EF7 /* simple-iframe.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-iframe.html"; sourceTree = "<group>"; }; - 33DC8910141953A300747EF7 /* LoadCanceledNoServerRedirectCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadCanceledNoServerRedirectCallback.cpp; sourceTree = "<group>"; }; - 33DC89131419579F00747EF7 /* LoadCanceledNoServerRedirectCallback_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadCanceledNoServerRedirectCallback_Bundle.cpp; sourceTree = "<group>"; }; - 33E79E05137B5FCE00E32D99 /* mouse-move-listener.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "mouse-move-listener.html"; sourceTree = "<group>"; }; - 37200B9113A16230007A4FAD /* VectorReverse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VectorReverse.cpp; path = WTF/VectorReverse.cpp; sourceTree = "<group>"; }; - 3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderedImageFromDOMRange.mm; sourceTree = "<group>"; }; - 3751AF7A169518F800764319 /* DOMNodeFromJSObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMNodeFromJSObject.mm; sourceTree = "<group>"; }; - 3776BC62150946BC0043A66D /* DeviceScaleFactorInDashboardRegions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DeviceScaleFactorInDashboardRegions.mm; sourceTree = "<group>"; }; - 378E64711632646D00B6C676 /* InjectedBundleFrameHitTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleFrameHitTest.cpp; sourceTree = "<group>"; }; - 378E64751632655D00B6C676 /* InjectedBundleFrameHitTest_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleFrameHitTest_Bundle.cpp; sourceTree = "<group>"; }; - 378E647816326FDF00B6C676 /* link-with-title.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "link-with-title.html"; sourceTree = "<group>"; }; - 379028B514FABD92007E6B43 /* AcceptsFirstMouse.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AcceptsFirstMouse.mm; sourceTree = "<group>"; }; - 379028B814FABE49007E6B43 /* acceptsFirstMouse.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = acceptsFirstMouse.html; sourceTree = "<group>"; }; - 3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringByEvaluatingJavaScriptFromString.mm; sourceTree = "<group>"; }; - 37A6895D148A9B50005100FA /* SubresourceErrorCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SubresourceErrorCrash.mm; sourceTree = "<group>"; }; - 37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMRangeOfString.mm; sourceTree = "<group>"; }; - 37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DOMRangeOfString.html; sourceTree = "<group>"; }; - 37E1064A1697676400B78BD0 /* DOMHTMLTableCellCellAbove.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMHTMLTableCellCellAbove.mm; sourceTree = "<group>"; }; - 37E1064B169767F700B78BD0 /* DOMHTMLTableCellElementCellAbove.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DOMHTMLTableCellElementCellAbove.html; sourceTree = "<group>"; }; - 37E38C33169B7D010084C28C /* WebViewDidRemoveFrameFromHierarchy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewDidRemoveFrameFromHierarchy.mm; sourceTree = "<group>"; }; - 440A1D3814A0103A008A66F2 /* KURL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KURL.cpp; sourceTree = "<group>"; }; - 44A622C114A0E2B60048515B /* WTFStringUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFStringUtilities.h; sourceTree = "<group>"; }; - 4BB4160116815B2600824238 /* JSWrapperForNodeInWebFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSWrapperForNodeInWebFrame.mm; sourceTree = "<group>"; }; - 4BB4160316815F9100824238 /* ElementAtPointInWebFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ElementAtPointInWebFrame.mm; 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>"; }; - 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>"; }; - 5142B2721517C89100C32B19 /* ContextMenuCanCopyURL.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ContextMenuCanCopyURL.html; sourceTree = "<group>"; }; - 517E7DFB15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCachePruneWithinResourceLoadDelegate.mm; sourceTree = "<group>"; }; - 517E7E031511187500D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = MemoryCachePruneWithinResourceLoadDelegate.html; sourceTree = "<group>"; }; - 51E93016156B13E1004C99DF /* WKPageGetScaleFactorNotZero.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKPageGetScaleFactorNotZero.cpp; sourceTree = "<group>"; }; - 51FBBB4C1513D4E900822738 /* WebViewCanPasteURL.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewCanPasteURL.mm; sourceTree = "<group>"; }; - 51FCF7971534AC6D00104491 /* ShouldGoToBackForwardListItem_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShouldGoToBackForwardListItem_Bundle.cpp; sourceTree = "<group>"; }; - 51FCF7981534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShouldGoToBackForwardListItem.cpp; sourceTree = "<group>"; }; - 520BCF4A141EB09E00937EA8 /* WebArchive_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebArchive_Bundle.cpp; sourceTree = "<group>"; }; - 520BCF4B141EB09E00937EA8 /* WebArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebArchive.cpp; sourceTree = "<group>"; }; - 52B8CF9415868CF000281053 /* SetDocumentURI.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = SetDocumentURI.html; sourceTree = "<group>"; }; - 52B8CF9515868CF000281053 /* SetDocumentURI.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SetDocumentURI.mm; sourceTree = "<group>"; }; - 52CB47401448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadAlternateHTMLStringWithNonDirectoryURL.cpp; sourceTree = "<group>"; }; - 52E5CE4514D21E9D003B2BD8 /* ParentFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentFrame.cpp; sourceTree = "<group>"; }; - 52E5CE4814D21EAB003B2BD8 /* ParentFrame_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentFrame_Bundle.cpp; sourceTree = "<group>"; }; - 76E182D91547550100F1FADD /* WillSendSubmitEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillSendSubmitEvent.cpp; sourceTree = "<group>"; }; - 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillSendSubmitEvent_Bundle.cpp; sourceTree = "<group>"; }; - 76E182DE15475A8300F1FADD /* auto-submitting-form.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "auto-submitting-form.html"; sourceTree = "<group>"; }; - 7C8DDAA91735DE1D00EA5AC0 /* CloseThenTerminate.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CloseThenTerminate.cpp; sourceTree = "<group>"; }; - 7CFBCADD1743234F00B2BFCF /* WillLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillLoad.cpp; sourceTree = "<group>"; }; - 7CFBCAE31743238E00B2BFCF /* WillLoad_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillLoad_Bundle.cpp; sourceTree = "<group>"; }; - 81B50192140F232300D9EB58 /* StringBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringBuilder.cpp; path = WTF/StringBuilder.cpp; sourceTree = "<group>"; }; - 8A2C750D16CED9550024F352 /* ResizeWindowAfterCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResizeWindowAfterCrash.cpp; sourceTree = "<group>"; }; - 8A3AF93A16C9ED2700D248C1 /* ReloadPageAfterCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReloadPageAfterCrash.cpp; sourceTree = "<group>"; }; - 8AA28C1916D2FA7B002FF4DB /* LoadPageOnCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadPageOnCrash.cpp; sourceTree = "<group>"; }; - 8DD76FA10486AA7600D96B5E /* TestWebKitAPI */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TestWebKitAPI; sourceTree = BUILT_PRODUCTS_DIR; }; - 930AD401150698B30067970F /* lots-of-text.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "lots-of-text.html"; sourceTree = "<group>"; }; - 9361002814DC957B0061379D /* lots-of-iframes.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "lots-of-iframes.html"; sourceTree = "<group>"; }; - 939BA91614103412001A01BD /* DeviceScaleFactorOnBack.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DeviceScaleFactorOnBack.mm; sourceTree = "<group>"; }; - 93ABA80816DDAB91002DB2FA /* StringHasher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringHasher.cpp; path = WTF/StringHasher.cpp; sourceTree = "<group>"; }; - 93AF4ECA1506F035007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutForImages.cpp; sourceTree = "<group>"; }; - 93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp; sourceTree = "<group>"; }; - 93AF4ECF1506F123007FD57E /* lots-of-images.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "lots-of-images.html"; sourceTree = "<group>"; }; - 93F1DB3014DA20760024C362 /* NewFirstVisuallyNonEmptyLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayout.cpp; sourceTree = "<group>"; }; - 93F1DB3314DA20870024C362 /* NewFirstVisuallyNonEmptyLayout_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayout_Bundle.cpp; sourceTree = "<group>"; }; - 93F1DB5414DB1B730024C362 /* NewFirstVisuallyNonEmptyLayoutFails.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFails.cpp; sourceTree = "<group>"; }; - 93F1DB5614DB1B840024C362 /* NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp; sourceTree = "<group>"; }; - 93F7E86B14DC8E4D00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames.cpp; sourceTree = "<group>"; }; - 93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp; sourceTree = "<group>"; }; - 9B26FC6B159D061000CC3765 /* HTMLFormCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLFormCollectionNamedItem.mm; sourceTree = "<group>"; }; - 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLFormCollectionNamedItem.html; sourceTree = "<group>"; }; - 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HTMLCollectionNamedItem.mm; sourceTree = "<group>"; }; - 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLCollectionNamedItem.html; sourceTree = "<group>"; }; - A51B650816ADF9B1007AA5D9 /* PageVisibilityState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageVisibilityState.cpp; sourceTree = "<group>"; }; - A57A34EF16AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PageVisibilityStateWithWindowChanges.mm; sourceTree = "<group>"; }; - A57A34F116AF69E200C2501F /* PageVisibilityStateWithWindowChanges.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = PageVisibilityStateWithWindowChanges.html; sourceTree = "<group>"; }; - A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = WindowlessWebViewWithMedia.html; sourceTree = "<group>"; }; - A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowlessWebViewWithMedia.mm; sourceTree = "<group>"; }; - A7A966DA140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CheckedArithmeticOperations.cpp; path = WTF/CheckedArithmeticOperations.cpp; sourceTree = "<group>"; }; - B4039F9C15E6D8B3007255D6 /* MathExtras.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MathExtras.cpp; path = WTF/MathExtras.cpp; sourceTree = "<group>"; }; - B55AD1D1179F336600AC1494 /* PreventImageLoadWithAutoResizing.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = PreventImageLoadWithAutoResizing.mm; path = WebKit2ObjC/PreventImageLoadWithAutoResizing.mm; sourceTree = "<group>"; }; - B55AD1D3179F3ABF00AC1494 /* PreventImageLoadWithAutoResizing_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PreventImageLoadWithAutoResizing_Bundle.cpp; path = WebKit2ObjC/PreventImageLoadWithAutoResizing_Bundle.cpp; sourceTree = "<group>"; }; - B55F119F1516834F00915916 /* AttributedString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AttributedString.mm; sourceTree = "<group>"; }; - B55F11B01517A2C400915916 /* attributedStringCustomFont.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = attributedStringCustomFont.html; sourceTree = "<group>"; }; - B55F11B9151916E600915916 /* Ahem.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Ahem.ttf; sourceTree = "<group>"; }; - BC029B161486AD6400817DA9 /* RetainPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RetainPtr.cpp; sourceTree = "<group>"; }; - BC029B1B1486B25900817DA9 /* RetainPtr.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RetainPtr.mm; path = WTF/ns/RetainPtr.mm; sourceTree = "<group>"; }; - BC131883117114A800B69727 /* PlatformUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformUtilities.h; sourceTree = "<group>"; }; - BC131884117114B600B69727 /* PlatformUtilitiesMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformUtilitiesMac.mm; sourceTree = "<group>"; }; - BC131A9E1171317C00B69727 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; }; - BC131AA8117131FC00B69727 /* TestsController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = TestsController.cpp; sourceTree = "<group>"; }; - BC22D31314DC689800FFB1DD /* UserMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMessage.cpp; sourceTree = "<group>"; }; - BC22D31714DC68B800FFB1DD /* UserMessage_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMessage_Bundle.cpp; sourceTree = "<group>"; }; - BC246D8C132F115A00B56D7C /* AboutBlankLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AboutBlankLoad.cpp; sourceTree = "<group>"; }; - BC246D97132F1FE100B56D7C /* CanHandleRequest_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanHandleRequest_Bundle.cpp; sourceTree = "<group>"; }; - BC246D98132F1FE100B56D7C /* CanHandleRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanHandleRequest.cpp; sourceTree = "<group>"; }; - BC2D004812A9FDFA00E732A3 /* PageLoadDidChangeLocationWithinPageForFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageLoadDidChangeLocationWithinPageForFrame.cpp; sourceTree = "<group>"; }; - BC2D004A12A9FEB300E732A3 /* file-with-anchor.html */ = {isa = PBXFileReference; explicitFileType = text.html; fileEncoding = 4; path = "file-with-anchor.html"; sourceTree = "<group>"; }; - BC3C4C7014575B6A0025FB62 /* WKBrowsingContextLoadDelegateTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKBrowsingContextLoadDelegateTest.mm; path = WebKit2ObjC/WKBrowsingContextLoadDelegateTest.mm; sourceTree = "<group>"; }; - BC3C4C7D14587AA60025FB62 /* WKBrowsingContextGroupTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKBrowsingContextGroupTest.mm; path = WebKit2ObjC/WKBrowsingContextGroupTest.mm; sourceTree = "<group>"; }; - BC55F5F814AD78EE00484BE1 /* Vector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vector.cpp; path = WTF/Vector.cpp; sourceTree = "<group>"; }; - BC575946126E7351006F0F12 /* InjectedBundleMain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleMain.cpp; sourceTree = "<group>"; }; - BC575980126E74AF006F0F12 /* InjectedBundleTestWebKitAPI.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InjectedBundleTestWebKitAPI.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - BC575981126E74AF006F0F12 /* InjectedBundle-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "InjectedBundle-Info.plist"; sourceTree = "<group>"; }; - BC575A9E126E75FB006F0F12 /* InjectedBundleTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundleTest.h; sourceTree = "<group>"; }; - BC575A9F126E7657006F0F12 /* InjectedBundleController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundleController.h; sourceTree = "<group>"; }; - BC575AA0126E7657006F0F12 /* InjectedBundleController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleController.cpp; sourceTree = "<group>"; }; - BC575AAC126E83B9006F0F12 /* InjectedBundleBasic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleBasic.cpp; sourceTree = "<group>"; }; - BC575AAF126E83C8006F0F12 /* InjectedBundleBasic_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleBasic_Bundle.cpp; sourceTree = "<group>"; }; - BC575AE2126E88B1006F0F12 /* InjectedBundle.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = InjectedBundle.xcconfig; sourceTree = "<group>"; }; - BC575BBF126F5752006F0F12 /* PlatformUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformUtilities.cpp; sourceTree = "<group>"; }; - BC7B619A1299FE9E00D174A4 /* WKPreferences.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKPreferences.cpp; sourceTree = "<group>"; }; - BC901E221492ADCE0074A667 /* WKConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKConnection.cpp; sourceTree = "<group>"; }; - BC901E311492AF390074A667 /* WKConnection_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKConnection_Bundle.cpp; sourceTree = "<group>"; }; - BC90951B125533D700083756 /* PlatformWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformWebView.h; sourceTree = "<group>"; }; - BC90955C125548AA00083756 /* PlatformWebViewMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformWebViewMac.mm; sourceTree = "<group>"; }; - BC90957E12554CF900083756 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; }; - BC90957F12554CF900083756 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; }; - BC90958012554CF900083756 /* TestWebKitAPI.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = TestWebKitAPI.xcconfig; sourceTree = "<group>"; }; - BC90964B125561BF00083756 /* VectorBasic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VectorBasic.cpp; path = WTF/VectorBasic.cpp; sourceTree = "<group>"; }; - BC90964D1255620C00083756 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = JavaScriptCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - BC909778125571AB00083756 /* simple.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = simple.html; sourceTree = "<group>"; }; - BC909779125571AB00083756 /* PageLoadBasic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageLoadBasic.cpp; sourceTree = "<group>"; }; - BC90995D12567BC100083756 /* WKString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKString.cpp; sourceTree = "<group>"; }; - BC9099931256ACF100083756 /* WKStringJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKStringJSString.cpp; sourceTree = "<group>"; }; - BCA61DB411700EFD00460D1E /* WebKit2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit2.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - BCAA485514A021640088FAC4 /* simple-tall.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-tall.html"; sourceTree = "<group>"; }; - BCAA485714A044D40088FAC4 /* EditorCommands.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EditorCommands.mm; sourceTree = "<group>"; }; - BCB6803F126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentStartUserScriptAlertCrash.cpp; sourceTree = "<group>"; }; - BCB68041126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentStartUserScriptAlertCrash_Bundle.cpp; sourceTree = "<group>"; }; - BCB9E7C711234E3A00A137E0 /* TestsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestsController.h; sourceTree = "<group>"; }; - BCB9E7FA112359A300A137E0 /* Test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Test.h; sourceTree = "<group>"; }; - BCB9E9F011235BDE00A137E0 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - BCBD370F125AA2EB00D2C29F /* FrameMIMETypeHTML.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrameMIMETypeHTML.cpp; sourceTree = "<group>"; }; - BCBD372E125ABBE600D2C29F /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; }; - BCBD3760125ABCFE00D2C29F /* FrameMIMETypePNG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrameMIMETypePNG.cpp; sourceTree = "<group>"; }; - BCC8B95A12611F4700DE46A4 /* FailedLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FailedLoad.cpp; sourceTree = "<group>"; }; - C01363C713C3997300EF3964 /* StringOperators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringOperators.cpp; path = WTF/StringOperators.cpp; sourceTree = "<group>"; }; - C02B77F1126612140026BF0F /* SpacebarScrolling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpacebarScrolling.cpp; sourceTree = "<group>"; }; - C02B7853126613AE0026BF0F /* Carbon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = Carbon.framework; sourceTree = SDKROOT; }; - C02B7882126615410026BF0F /* spacebar-scrolling.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "spacebar-scrolling.html"; sourceTree = "<group>"; }; - C045F9441385C2E900C0F3CD /* DownloadDecideDestinationCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DownloadDecideDestinationCrash.cpp; sourceTree = "<group>"; }; - C045F9461385C2F800C0F3CD /* 18-characters.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "18-characters.html"; sourceTree = "<group>"; }; - C07E6CAE13FD67650038B22B /* DynamicDeviceScaleFactor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DynamicDeviceScaleFactor.mm; sourceTree = "<group>"; }; - C07E6CB113FD738A0038B22B /* devicePixelRatio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = devicePixelRatio.html; sourceTree = "<group>"; }; - C081224013FC172400DC39AE /* JavaScriptTestMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JavaScriptTestMac.mm; sourceTree = "<group>"; }; - C081224313FC19EC00DC39AE /* SyntheticBackingScaleFactorWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SyntheticBackingScaleFactorWindow.h; sourceTree = "<group>"; }; - C081224413FC19EC00DC39AE /* SyntheticBackingScaleFactorWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyntheticBackingScaleFactorWindow.m; sourceTree = "<group>"; }; - C081224813FC1B0300DC39AE /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C08587BD13FE956C001EF4E5 /* WebKitAgnosticTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebKitAgnosticTest.mm; sourceTree = "<group>"; }; - C08587BE13FE956C001EF4E5 /* WebKitAgnosticTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitAgnosticTest.h; sourceTree = "<group>"; }; - C08587FB13FEC39B001EF4E5 /* InstanceMethodSwizzler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InstanceMethodSwizzler.mm; sourceTree = "<group>"; }; - C08587FE13FEC3A6001EF4E5 /* InstanceMethodSwizzler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InstanceMethodSwizzler.h; sourceTree = "<group>"; }; - C08587FF13FEC3A6001EF4E5 /* InstanceMethodSwizzler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InstanceMethodSwizzler.mm; sourceTree = "<group>"; }; - C0991C50143C7D68007998F2 /* RetainPtrHashing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RetainPtrHashing.cpp; sourceTree = "<group>"; }; - C0ADBE7A12FCA4D000D2C129 /* JavaScriptTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JavaScriptTest.cpp; sourceTree = "<group>"; }; - C0ADBE7B12FCA4D000D2C129 /* JavaScriptTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptTest.h; sourceTree = "<group>"; }; - C0ADBE8212FCA6AA00D2C129 /* RestoreSessionStateContainingFormData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RestoreSessionStateContainingFormData.cpp; sourceTree = "<group>"; }; - C0ADBE8412FCA6B600D2C129 /* simple-form.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-form.html"; sourceTree = "<group>"; }; - C0BD669C131D3CF700E18F2A /* ResponsivenessTimerDoesntFireEarly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResponsivenessTimerDoesntFireEarly.cpp; sourceTree = "<group>"; }; - C0BD669E131D3CFF00E18F2A /* ResponsivenessTimerDoesntFireEarly_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResponsivenessTimerDoesntFireEarly_Bundle.cpp; sourceTree = "<group>"; }; - C0C5D3BC14598B6F00A802A6 /* GetBackingScaleFactor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetBackingScaleFactor.mm; sourceTree = "<group>"; }; - C0C5D3BD14598B6F00A802A6 /* GetBackingScaleFactor_Bundle.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetBackingScaleFactor_Bundle.mm; sourceTree = "<group>"; }; - C2CF975816CEC69E0054E99D /* JSContextBackForwardCache1.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = JSContextBackForwardCache1.html; sourceTree = "<group>"; }; - C2CF975916CEC69E0054E99D /* JSContextBackForwardCache2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = JSContextBackForwardCache2.html; sourceTree = "<group>"; }; - C2EB2DD116CAC7AC009B52EE /* WebViewDidCreateJavaScriptContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewDidCreateJavaScriptContext.mm; sourceTree = "<group>"; }; - C507E8A614C6545B005D6B3B /* InspectorBar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InspectorBar.mm; sourceTree = "<group>"; }; - C5101C4E176B8BB900EE9B15 /* findRanges.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = findRanges.html; sourceTree = "<group>"; }; - C51AFB98169F49FF009CCF66 /* FindMatches.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FindMatches.mm; sourceTree = "<group>"; }; - C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SimplifyMarkup.mm; sourceTree = "<group>"; }; - C540F783152E5A7800A40C8C /* verboseMarkup.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = verboseMarkup.html; sourceTree = "<group>"; }; - C54237ED16B8955800E638FC /* PasteboardNotifications_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PasteboardNotifications_Bundle.cpp; sourceTree = "<group>"; }; - C54237EE16B8955800E638FC /* PasteboardNotifications.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteboardNotifications.mm; sourceTree = "<group>"; }; - C5E1AFFD16B22179006CC1F2 /* execCopy.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = execCopy.html; sourceTree = "<group>"; }; - CD5393C71757BA9700C07123 /* MD5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MD5.cpp; path = WTF/MD5.cpp; sourceTree = "<group>"; }; - CD5393C91757BAC400C07123 /* SHA1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SHA1.cpp; path = WTF/SHA1.cpp; sourceTree = "<group>"; }; - CD5497B315857F0C00B5BC30 /* MediaTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MediaTime.cpp; path = WTF/MediaTime.cpp; sourceTree = "<group>"; }; - E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCacheDisableWithinResourceLoadDelegate.mm; sourceTree = "<group>"; }; - E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = MemoryCacheDisableWithinResourceLoadDelegate.html; sourceTree = "<group>"; }; - E194E1BA177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StopLoadingFromDidReceiveResponse.mm; sourceTree = "<group>"; }; - E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = StopLoadingFromDidReceiveResponse.html; sourceTree = "<group>"; }; - E490296714E2E3A4002BEDD1 /* TypingStyleCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TypingStyleCrash.mm; sourceTree = "<group>"; }; - E4A757D3178AEA5B00B5D7A4 /* Deque.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Deque.cpp; path = WTF/Deque.cpp; sourceTree = "<group>"; }; - F3FC3EE213678B7300126A65 /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; - F660AA0C15A5F061003A1243 /* GetInjectedBundleInitializationUserDataCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetInjectedBundleInitializationUserDataCallback.cpp; sourceTree = "<group>"; }; - F660AA0F15A5F624003A1243 /* GetInjectedBundleInitializationUserDataCallback_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetInjectedBundleInitializationUserDataCallback_Bundle.cpp; sourceTree = "<group>"; }; - F660AA1215A619C8003A1243 /* InjectedBundleInitializationUserDataCallbackWins.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleInitializationUserDataCallbackWins.cpp; sourceTree = "<group>"; }; - F660AA1415A61ABF003A1243 /* InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp; sourceTree = "<group>"; }; - F6B7BE92174691EF008A3445 /* DidAssociateFormControls_Bundle.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DidAssociateFormControls_Bundle.cpp; sourceTree = "<group>"; }; - F6B7BE93174691EF008A3445 /* DidAssociateFormControls.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DidAssociateFormControls.cpp; sourceTree = "<group>"; }; - F6B7BE9617469B7E008A3445 /* associate-form-controls.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "associate-form-controls.html"; sourceTree = "<group>"; }; - F6F3F29013342FEB00A6BF19 /* CookieManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CookieManager.cpp; sourceTree = "<group>"; }; - F6F49C6615545C8D0007F39D /* DOMWindowExtensionNoCache_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMWindowExtensionNoCache_Bundle.cpp; sourceTree = "<group>"; }; - F6F49C6715545C8D0007F39D /* DOMWindowExtensionNoCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMWindowExtensionNoCache.cpp; sourceTree = "<group>"; }; - F6FDDDD214241AD4004F1729 /* PrivateBrowsingPushStateNoHistoryCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateBrowsingPushStateNoHistoryCallback.cpp; sourceTree = "<group>"; }; - F6FDDDD514241C48004F1729 /* push-state.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "push-state.html"; sourceTree = "<group>"; }; - FE217ECC1640A54A0052988B /* VMInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInspector.cpp; sourceTree = "<group>"; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8DD76F9B0486AA7600D96B5E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BC57597E126E74AF006F0F12 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - BC575A90126E74D3006F0F12 /* Cocoa.framework in Frameworks */, - BC575A92126E74D3006F0F12 /* JavaScriptCore.framework in Frameworks */, - BC575A91126E74D3006F0F12 /* WebKit2.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 08FB7794FE84155DC02AAC07 /* TestWebKitAPI */ = { - isa = PBXGroup; - children = ( - 08FB7795FE84155DC02AAC07 /* Source */, - BCB9EB66112366D800A137E0 /* Tests */, - BC90957D12554CEA00083756 /* Configurations */, - 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */, - 1AB674ADFE9D54B511CA2CBB /* Products */, - ); - name = TestWebKitAPI; - sourceTree = "<group>"; - }; - 08FB7795FE84155DC02AAC07 /* Source */ = { - isa = PBXGroup; - children = ( - BC575944126E733C006F0F12 /* InjectedBundle */, - 2E9660DC16C07D7B00371B42 /* ios */, - BCA61C3A11700B9400460D1E /* mac */, - BC131A9E1171317C00B69727 /* config.h */, - C0ADBE7A12FCA4D000D2C129 /* JavaScriptTest.cpp */, - C0ADBE7B12FCA4D000D2C129 /* JavaScriptTest.h */, - BC575BBF126F5752006F0F12 /* PlatformUtilities.cpp */, - BC131883117114A800B69727 /* PlatformUtilities.h */, - BC90951B125533D700083756 /* PlatformWebView.h */, - BCB9E7FA112359A300A137E0 /* Test.h */, - BC131AA8117131FC00B69727 /* TestsController.cpp */, - BCB9E7C711234E3A00A137E0 /* TestsController.h */, - 44A622C114A0E2B60048515B /* WTFStringUtilities.h */, - ); - name = Source; - sourceTree = "<group>"; - }; - 08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = { - isa = PBXGroup; - children = ( - C02B7853126613AE0026BF0F /* Carbon.framework */, - BCB9E9F011235BDE00A137E0 /* Cocoa.framework */, - BC90964D1255620C00083756 /* JavaScriptCore.framework */, - F3FC3EE213678B7300126A65 /* libgtest.a */, - C081224813FC1B0300DC39AE /* WebKit.framework */, - BCA61DB411700EFD00460D1E /* WebKit2.framework */, - ); - name = "External Frameworks and Libraries"; - sourceTree = "<group>"; - }; - 1AB674ADFE9D54B511CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8DD76FA10486AA7600D96B5E /* TestWebKitAPI */, - BC575980126E74AF006F0F12 /* InjectedBundleTestWebKitAPI.bundle */, - ); - name = Products; - sourceTree = "<group>"; - }; - 2E9660DC16C07D7B00371B42 /* ios */ = { - isa = PBXGroup; - children = ( - 2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */, - ); - path = ios; - sourceTree = "<group>"; - }; - 440A1D3614A01000008A66F2 /* WebCore */ = { - isa = PBXGroup; - children = ( - 440A1D3814A0103A008A66F2 /* KURL.cpp */, - 14464012167A8305000BD218 /* LayoutUnit.cpp */, - ); - path = WebCore; - sourceTree = "<group>"; - }; - BC029B1A1486B23800817DA9 /* ns */ = { - isa = PBXGroup; - children = ( - BC029B1B1486B25900817DA9 /* RetainPtr.mm */, - ); - name = ns; - sourceTree = "<group>"; - }; - BC3C4C6F14575B1D0025FB62 /* WebKit2 Objective-C */ = { - isa = PBXGroup; - children = ( - B55AD1D3179F3ABF00AC1494 /* PreventImageLoadWithAutoResizing_Bundle.cpp */, - B55AD1D1179F336600AC1494 /* PreventImageLoadWithAutoResizing.mm */, - 297234B2173AD04800983601 /* CustomProtocolsInvalidScheme.mm */, - 297234B5173AFAC700983601 /* CustomProtocolsInvalidScheme_Bundle.cpp */, - 29AB8A9F164C735800D49BEC /* CustomProtocolsTest.mm */, - 290F4276172A232C00939FF0 /* CustomProtocolsSyncXHRTest.mm */, - 2943BE84161DFEB800999E3D /* UserContentTest.mm */, - BC3C4C7D14587AA60025FB62 /* WKBrowsingContextGroupTest.mm */, - BC3C4C7014575B6A0025FB62 /* WKBrowsingContextLoadDelegateTest.mm */, - ); - name = "WebKit2 Objective-C"; - sourceTree = "<group>"; - }; - BC575944126E733C006F0F12 /* InjectedBundle */ = { - isa = PBXGroup; - children = ( - BC575981126E74AF006F0F12 /* InjectedBundle-Info.plist */, - BC575AA0126E7657006F0F12 /* InjectedBundleController.cpp */, - BC575A9F126E7657006F0F12 /* InjectedBundleController.h */, - BC575946126E7351006F0F12 /* InjectedBundleMain.cpp */, - BC575A9E126E75FB006F0F12 /* InjectedBundleTest.h */, - ); - name = InjectedBundle; - sourceTree = "<group>"; - }; - BC90957D12554CEA00083756 /* Configurations */ = { - isa = PBXGroup; - children = ( - BC90957E12554CF900083756 /* Base.xcconfig */, - BC90957F12554CF900083756 /* DebugRelease.xcconfig */, - BC575AE2126E88B1006F0F12 /* InjectedBundle.xcconfig */, - BC90958012554CF900083756 /* TestWebKitAPI.xcconfig */, - ); - path = Configurations; - sourceTree = "<group>"; - }; - BC9096411255616000083756 /* WebKit2 */ = { - isa = PBXGroup; - children = ( - C0C5D3BB14598B6F00A802A6 /* mac */, - BC90977B125571AE00083756 /* Resources */, - BC246D8C132F115A00B56D7C /* AboutBlankLoad.cpp */, - 7C8DDAA91735DE1D00EA5AC0 /* CloseThenTerminate.cpp */, - BC246D98132F1FE100B56D7C /* CanHandleRequest.cpp */, - BC246D97132F1FE100B56D7C /* CanHandleRequest_Bundle.cpp */, - F6F3F29013342FEB00A6BF19 /* CookieManager.cpp */, - F6B7BE93174691EF008A3445 /* DidAssociateFormControls.cpp */, - F6B7BE92174691EF008A3445 /* DidAssociateFormControls_Bundle.cpp */, - BCB6803F126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp */, - BCB68041126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp */, - 51393E1E1523944A005F39C5 /* DOMWindowExtensionBasic.cpp */, - 51393E1D1523944A005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp */, - F6F49C6715545C8D0007F39D /* DOMWindowExtensionNoCache.cpp */, - F6F49C6615545C8D0007F39D /* DOMWindowExtensionNoCache_Bundle.cpp */, - C045F9441385C2E900C0F3CD /* DownloadDecideDestinationCrash.cpp */, - 1A5FEFDC1270E2A3000E2921 /* EvaluateJavaScript.cpp */, - BCC8B95A12611F4700DE46A4 /* FailedLoad.cpp */, - 1A02C84E125D4A8400E3F4BD /* Find.cpp */, - C51AFB98169F49FF009CCF66 /* FindMatches.mm */, - 1ADBEFAD130C689C00D61D19 /* ForceRepaint.cpp */, - BCBD370F125AA2EB00D2C29F /* FrameMIMETypeHTML.cpp */, - BCBD3760125ABCFE00D2C29F /* FrameMIMETypePNG.cpp */, - F660AA0C15A5F061003A1243 /* GetInjectedBundleInitializationUserDataCallback.cpp */, - F660AA0F15A5F624003A1243 /* GetInjectedBundleInitializationUserDataCallback_Bundle.cpp */, - 4BFDFFA8131477770061F24B /* HitTestResultNodeHandle.cpp */, - 4BFDFFA61314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp */, - BC575AAC126E83B9006F0F12 /* InjectedBundleBasic.cpp */, - BC575AAF126E83C8006F0F12 /* InjectedBundleBasic_Bundle.cpp */, - 378E64711632646D00B6C676 /* InjectedBundleFrameHitTest.cpp */, - 378E64751632655D00B6C676 /* InjectedBundleFrameHitTest_Bundle.cpp */, - F660AA1215A619C8003A1243 /* InjectedBundleInitializationUserDataCallbackWins.cpp */, - F660AA1415A61ABF003A1243 /* InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp */, - 52CB47401448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp */, - 33DC8910141953A300747EF7 /* LoadCanceledNoServerRedirectCallback.cpp */, - 33DC89131419579F00747EF7 /* LoadCanceledNoServerRedirectCallback_Bundle.cpp */, - 8AA28C1916D2FA7B002FF4DB /* LoadPageOnCrash.cpp */, - 33BE5AF4137B5A6C00705813 /* MouseMoveAfterCrash.cpp */, - 33BE5AF8137B5AAE00705813 /* MouseMoveAfterCrash_Bundle.cpp */, - 93F1DB3014DA20760024C362 /* NewFirstVisuallyNonEmptyLayout.cpp */, - 93F1DB3314DA20870024C362 /* NewFirstVisuallyNonEmptyLayout_Bundle.cpp */, - 93F1DB5414DB1B730024C362 /* NewFirstVisuallyNonEmptyLayoutFails.cpp */, - 93F1DB5614DB1B840024C362 /* NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp */, - 93AF4ECA1506F035007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages.cpp */, - 93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */, - 93F7E86B14DC8E4D00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames.cpp */, - 93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */, - BC909779125571AB00083756 /* PageLoadBasic.cpp */, - BC2D004812A9FDFA00E732A3 /* PageLoadDidChangeLocationWithinPageForFrame.cpp */, - A51B650816ADF9B1007AA5D9 /* PageVisibilityState.cpp */, - 52E5CE4514D21E9D003B2BD8 /* ParentFrame.cpp */, - 52E5CE4814D21EAB003B2BD8 /* ParentFrame_Bundle.cpp */, - C54237EE16B8955800E638FC /* PasteboardNotifications.mm */, - C54237ED16B8955800E638FC /* PasteboardNotifications_Bundle.cpp */, - 333B9CE11277F23100FEFCE3 /* PreventEmptyUserAgent.cpp */, - F6FDDDD214241AD4004F1729 /* PrivateBrowsingPushStateNoHistoryCallback.cpp */, - 8A3AF93A16C9ED2700D248C1 /* ReloadPageAfterCrash.cpp */, - 2DD7D3A9178205D00026E1E3 /* ResizeReversePaginatedWebView.cpp */, - 8A2C750D16CED9550024F352 /* ResizeWindowAfterCrash.cpp */, - C0BD669C131D3CF700E18F2A /* ResponsivenessTimerDoesntFireEarly.cpp */, - C0BD669E131D3CFF00E18F2A /* ResponsivenessTimerDoesntFireEarly_Bundle.cpp */, - C0ADBE8212FCA6AA00D2C129 /* RestoreSessionStateContainingFormData.cpp */, - 2D640B5417875DFF00BFAF99 /* ScrollPinningBehaviors.cpp */, - 51FCF7981534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp */, - 51FCF7971534AC6D00104491 /* ShouldGoToBackForwardListItem_Bundle.cpp */, - C02B77F1126612140026BF0F /* SpacebarScrolling.cpp */, - 1AE72F47173EB214006362F0 /* TerminateTwice.cpp */, - BC22D31314DC689800FFB1DD /* UserMessage.cpp */, - BC22D31714DC68B800FFB1DD /* UserMessage_Bundle.cpp */, - 520BCF4B141EB09E00937EA8 /* WebArchive.cpp */, - 520BCF4A141EB09E00937EA8 /* WebArchive_Bundle.cpp */, - 0F17BBD415AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp */, - 7CFBCADD1743234F00B2BFCF /* WillLoad.cpp */, - 7CFBCAE31743238E00B2BFCF /* WillLoad_Bundle.cpp */, - 76E182D91547550100F1FADD /* WillSendSubmitEvent.cpp */, - 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */, - BC901E221492ADCE0074A667 /* WKConnection.cpp */, - BC901E311492AF390074A667 /* WKConnection_Bundle.cpp */, - 51E93016156B13E1004C99DF /* WKPageGetScaleFactorNotZero.cpp */, - BC7B619A1299FE9E00D174A4 /* WKPreferences.cpp */, - BC90995D12567BC100083756 /* WKString.cpp */, - BC9099931256ACF100083756 /* WKStringJSString.cpp */, - ); - path = WebKit2; - sourceTree = "<group>"; - }; - BC9096461255618900083756 /* WTF */ = { - isa = PBXGroup; - children = ( - C0991C4F143C7D68007998F2 /* cf */, - BC029B1A1486B23800817DA9 /* ns */, - 26F1B44215CA434F00D1E4BF /* AtomicString.cpp */, - A7A966DA140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp */, - 26A2C72E15E2E73C005B1A14 /* CString.cpp */, - E4A757D3178AEA5B00B5D7A4 /* Deque.cpp */, - 1AA9E55714980A9900001A8A /* Functional.cpp */, - 0BCD833414857CE400EA2003 /* HashMap.cpp */, - 26B2DFF815BDE599004F691D /* HashSet.cpp */, - 266FAFD215E5775200F61D5B /* IntegerToStringConversion.cpp */, - 26300B1716755CD90066886D /* ListHashSet.cpp */, - CD5393C71757BA9700C07123 /* MD5.cpp */, - B4039F9C15E6D8B3007255D6 /* MathExtras.cpp */, - CD5497B315857F0C00B5BC30 /* MediaTime.cpp */, - 0FC6C4CE141034AD005B7F0C /* MetaAllocator.cpp */, - 0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */, - CD5393C91757BAC400C07123 /* SHA1.cpp */, - 14F3B11215E45EAB00210069 /* SaturatedArithmeticOperations.cpp */, - 81B50192140F232300D9EB58 /* StringBuilder.cpp */, - 93ABA80816DDAB91002DB2FA /* StringHasher.cpp */, - 26F1B44315CA434F00D1E4BF /* StringImpl.cpp */, - C01363C713C3997300EF3964 /* StringOperators.cpp */, - 0BCD85691485C98B00EA2003 /* TemporaryChange.cpp */, - BC55F5F814AD78EE00484BE1 /* Vector.cpp */, - BC90964B125561BF00083756 /* VectorBasic.cpp */, - 37200B9113A16230007A4FAD /* VectorReverse.cpp */, - 265AF54F15D1E48A00B0CB4A /* WTFString.cpp */, - ); - name = WTF; - sourceTree = "<group>"; - }; - BC90977B125571AE00083756 /* Resources */ = { - isa = PBXGroup; - children = ( - C045F9461385C2F800C0F3CD /* 18-characters.html */, - F6B7BE9617469B7E008A3445 /* associate-form-controls.html */, - 76E182DE15475A8300F1FADD /* auto-submitting-form.html */, - 290F4274172A1FDE00939FF0 /* custom-protocol-sync-xhr.html */, - C5E1AFFD16B22179006CC1F2 /* execCopy.html */, - BC2D004A12A9FEB300E732A3 /* file-with-anchor.html */, - 1A02C84B125D4A5E00E3F4BD /* find.html */, - C5101C4E176B8BB900EE9B15 /* findRanges.html */, - BCBD372E125ABBE600D2C29F /* icon.png */, - 378E647816326FDF00B6C676 /* link-with-title.html */, - 9361002814DC957B0061379D /* lots-of-iframes.html */, - 93AF4ECF1506F123007FD57E /* lots-of-images.html */, - 930AD401150698B30067970F /* lots-of-text.html */, - 2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */, - 33E79E05137B5FCE00E32D99 /* mouse-move-listener.html */, - F6FDDDD514241C48004F1729 /* push-state.html */, - 1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */, - C0ADBE8412FCA6B600D2C129 /* simple-form.html */, - 33DC890E1419539300747EF7 /* simple-iframe.html */, - BCAA485514A021640088FAC4 /* simple-tall.html */, - BC909778125571AB00083756 /* simple.html */, - C02B7882126615410026BF0F /* spacebar-scrolling.html */, - ); - name = Resources; - sourceTree = "<group>"; - }; - BCA61C3A11700B9400460D1E /* mac */ = { - isa = PBXGroup; - children = ( - 1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */, - C08587FE13FEC3A6001EF4E5 /* InstanceMethodSwizzler.h */, - C08587FF13FEC3A6001EF4E5 /* InstanceMethodSwizzler.mm */, - C081224013FC172400DC39AE /* JavaScriptTestMac.mm */, - 2E7765CE16C4D81100BA2BB1 /* mainMac.mm */, - BC131884117114B600B69727 /* PlatformUtilitiesMac.mm */, - BC90955C125548AA00083756 /* PlatformWebViewMac.mm */, - C081224313FC19EC00DC39AE /* SyntheticBackingScaleFactorWindow.h */, - C081224413FC19EC00DC39AE /* SyntheticBackingScaleFactorWindow.m */, - 29AB8AA3164C7A9300D49BEC /* TestBrowsingContextLoadDelegate.h */, - 29AB8AA2164C7A9300D49BEC /* TestBrowsingContextLoadDelegate.mm */, - 290F427A172A23A500939FF0 /* TestProtocol.h */, - 290F4279172A23A500939FF0 /* TestProtocol.mm */, - C08587BE13FE956C001EF4E5 /* WebKitAgnosticTest.h */, - C08587BD13FE956C001EF4E5 /* WebKitAgnosticTest.mm */, - ); - path = mac; - sourceTree = "<group>"; - }; - BCB9EB66112366D800A137E0 /* Tests */ = { - isa = PBXGroup; - children = ( - FE217ECB1640A54A0052988B /* JavaScriptCore */, - C07E6CAD13FD67650038B22B /* mac */, - C08587F913FEC39B001EF4E5 /* TestWebKitAPI */, - 440A1D3614A01000008A66F2 /* WebCore */, - BC9096411255616000083756 /* WebKit2 */, - BC3C4C6F14575B1D0025FB62 /* WebKit2 Objective-C */, - BC9096461255618900083756 /* WTF */, - ); - path = Tests; - sourceTree = "<group>"; - }; - C07E6CAD13FD67650038B22B /* mac */ = { - isa = PBXGroup; - children = ( - C07E6CB013FD737C0038B22B /* Resources */, - 379028B514FABD92007E6B43 /* AcceptsFirstMouse.mm */, - B55F119F1516834F00915916 /* AttributedString.mm */, - 00CD9F6215BE312C002DA2CE /* BackForwardList.mm */, - 26DF5A5D15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm */, - 290A9BB51735DE8A00D71BBC /* CloseNewWindowInNavigationPolicyDelegate.mm */, - 5142B2701517C88B00C32B19 /* ContextMenuCanCopyURL.mm */, - 3776BC62150946BC0043A66D /* DeviceScaleFactorInDashboardRegions.mm */, - 939BA91614103412001A01BD /* DeviceScaleFactorOnBack.mm */, - 37E1064A1697676400B78BD0 /* DOMHTMLTableCellCellAbove.mm */, - 3751AF7A169518F800764319 /* DOMNodeFromJSObject.mm */, - 37DC678B140D7C5000ABCCDB /* DOMRangeOfString.mm */, - C07E6CAE13FD67650038B22B /* DynamicDeviceScaleFactor.mm */, - 4BB4160316815F9100824238 /* ElementAtPointInWebFrame.mm */, - 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */, - 9B26FC6B159D061000CC3765 /* HTMLFormCollectionNamedItem.mm */, - C507E8A614C6545B005D6B3B /* InspectorBar.mm */, - 4BB4160116815B2600824238 /* JSWrapperForNodeInWebFrame.mm */, - E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */, - 517E7DFB15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm */, - A57A34EF16AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm */, - 00BC16851680FE810065F1E5 /* PublicSuffix.mm */, - 3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */, - 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */, - 52B8CF9515868CF000281053 /* SetDocumentURI.mm */, - C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */, - 291861FD17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm */, - E194E1BA177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm */, - 3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */, - 37A6895D148A9B50005100FA /* SubresourceErrorCrash.mm */, - E490296714E2E3A4002BEDD1 /* TypingStyleCrash.mm */, - 51FBBB4C1513D4E900822738 /* WebViewCanPasteURL.mm */, - C2EB2DD116CAC7AC009B52EE /* WebViewDidCreateJavaScriptContext.mm */, - 37E38C33169B7D010084C28C /* WebViewDidRemoveFrameFromHierarchy.mm */, - 1A7BFC0A171A0BDB00BC5F64 /* WillSendSubmitEvent.mm */, - A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */, - ); - path = mac; - sourceTree = "<group>"; - }; - C07E6CB013FD737C0038B22B /* Resources */ = { - isa = PBXGroup; - children = ( - C2CF975816CEC69E0054E99D /* JSContextBackForwardCache1.html */, - C2CF975916CEC69E0054E99D /* JSContextBackForwardCache2.html */, - 379028B814FABE49007E6B43 /* acceptsFirstMouse.html */, - B55F11B9151916E600915916 /* Ahem.ttf */, - B55F11B01517A2C400915916 /* attributedStringCustomFont.html */, - 26DF5A6115A2A22B003689C2 /* CancelLoadFromResourceLoadDelegate.html */, - 5142B2721517C89100C32B19 /* ContextMenuCanCopyURL.html */, - C07E6CB113FD738A0038B22B /* devicePixelRatio.html */, - 37E1064B169767F700B78BD0 /* DOMHTMLTableCellElementCellAbove.html */, - 37DC678F140D7D3A00ABCCDB /* DOMRangeOfString.html */, - 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */, - 9B26FCB4159D15E700CC3765 /* HTMLFormCollectionNamedItem.html */, - E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */, - 517E7E031511187500D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.html */, - 290A9BB81735F42300D71BBC /* OpenNewWindow.html */, - A57A34F116AF69E200C2501F /* PageVisibilityStateWithWindowChanges.html */, - 52B8CF9415868CF000281053 /* SetDocumentURI.html */, - E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */, - C540F783152E5A7800A40C8C /* verboseMarkup.html */, - A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */, - ); - name = Resources; - sourceTree = "<group>"; - }; - C08587F913FEC39B001EF4E5 /* TestWebKitAPI */ = { - isa = PBXGroup; - children = ( - C08587FA13FEC39B001EF4E5 /* mac */, - ); - path = TestWebKitAPI; - sourceTree = "<group>"; - }; - C08587FA13FEC39B001EF4E5 /* mac */ = { - isa = PBXGroup; - children = ( - C08587FB13FEC39B001EF4E5 /* InstanceMethodSwizzler.mm */, - ); - path = mac; - sourceTree = "<group>"; - }; - C0991C4F143C7D68007998F2 /* cf */ = { - isa = PBXGroup; - children = ( - BC029B161486AD6400817DA9 /* RetainPtr.cpp */, - C0991C50143C7D68007998F2 /* RetainPtrHashing.cpp */, - ); - name = cf; - path = WTF/cf; - sourceTree = "<group>"; - }; - C0C5D3BB14598B6F00A802A6 /* mac */ = { - isa = PBXGroup; - children = ( - BCAA485714A044D40088FAC4 /* EditorCommands.mm */, - C0C5D3BC14598B6F00A802A6 /* GetBackingScaleFactor.mm */, - C0C5D3BD14598B6F00A802A6 /* GetBackingScaleFactor_Bundle.mm */, - 1AEF994817A09F5300998EF0 /* GetPIDAfterAbortedProcessLaunch.cpp */, - ); - path = mac; - sourceTree = "<group>"; - }; - FE217ECB1640A54A0052988B /* JavaScriptCore */ = { - isa = PBXGroup; - children = ( - FE217ECC1640A54A0052988B /* VMInspector.cpp */, - ); - path = JavaScriptCore; - sourceTree = "<group>"; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 8DD76F960486AA7600D96B5E /* TestWebKitAPI */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "TestWebKitAPI" */; - buildPhases = ( - 8DD76F990486AA7600D96B5E /* Sources */, - 8DD76F9B0486AA7600D96B5E /* Frameworks */, - 8DD76F9E0486AA7600D96B5E /* CopyFiles */, - BCB9F4FB112384C000A137E0 /* Copy Resources */, - ); - buildRules = ( - ); - dependencies = ( - BC575A96126E74E7006F0F12 /* PBXTargetDependency */, - ); - name = TestWebKitAPI; - productInstallPath = "$(HOME)/bin"; - productName = TestWebKitAPI; - productReference = 8DD76FA10486AA7600D96B5E /* TestWebKitAPI */; - productType = "com.apple.product-type.tool"; - }; - BC57597F126E74AF006F0F12 /* InjectedBundleTestWebKitAPI */ = { - isa = PBXNativeTarget; - buildConfigurationList = BC575986126E74AF006F0F12 /* Build configuration list for PBXNativeTarget "InjectedBundleTestWebKitAPI" */; - buildPhases = ( - BC57597C126E74AF006F0F12 /* Resources */, - BC57597D126E74AF006F0F12 /* Sources */, - BC57597E126E74AF006F0F12 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = InjectedBundleTestWebKitAPI; - productName = InjectedBundle; - productReference = BC575980126E74AF006F0F12 /* InjectedBundleTestWebKitAPI.bundle */; - productType = "com.apple.product-type.bundle"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - attributes = { - }; - buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "TestWebKitAPI" */; - compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 08FB7794FE84155DC02AAC07 /* TestWebKitAPI */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8DD76F960486AA7600D96B5E /* TestWebKitAPI */, - BC57597F126E74AF006F0F12 /* InjectedBundleTestWebKitAPI */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - BC57597C126E74AF006F0F12 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 93AF4ED01506F123007FD57E /* lots-of-images.html in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8DD76F990486AA7600D96B5E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - BC246D8E132F115A00B56D7C /* AboutBlankLoad.cpp in Sources */, - 297234B4173AD04800983601 /* CustomProtocolsInvalidScheme.mm in Sources */, - 379028B614FABD92007E6B43 /* AcceptsFirstMouse.mm in Sources */, - 291861FF17BD4DC700D4E41E /* StopLoadingFromDidFinishLoading.mm in Sources */, - 26F1B44415CA434F00D1E4BF /* AtomicString.cpp in Sources */, - B55F11A01516834F00915916 /* AttributedString.mm in Sources */, - 00CD9F6315BE312C002DA2CE /* BackForwardList.mm in Sources */, - 1AE72F48173EB214006362F0 /* TerminateTwice.cpp in Sources */, - 26DF5A5E15A29BAA003689C2 /* CancelLoadFromResourceLoadDelegate.mm in Sources */, - BC246D9A132F1FE100B56D7C /* CanHandleRequest.cpp in Sources */, - A7A966DB140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp in Sources */, - 5142B2711517C88B00C32B19 /* ContextMenuCanCopyURL.mm in Sources */, - F6F3F29113342FEB00A6BF19 /* CookieManager.cpp in Sources */, - 26A2C72F15E2E73C005B1A14 /* CString.cpp in Sources */, - 29AB8AA1164C735800D49BEC /* CustomProtocolsTest.mm in Sources */, - 3776BC63150946BC0043A66D /* DeviceScaleFactorInDashboardRegions.mm in Sources */, - 939BA91714103412001A01BD /* DeviceScaleFactorOnBack.mm in Sources */, - BCB68040126FBFE100642A61 /* DocumentStartUserScriptAlertCrash.cpp in Sources */, - 37E1064D16976C8500B78BD0 /* DOMHTMLTableCellCellAbove.mm in Sources */, - 3751AF7C169518F800764319 /* DOMNodeFromJSObject.mm in Sources */, - 37DC678D140D7C5000ABCCDB /* DOMRangeOfString.mm in Sources */, - 51393E201523944A005F39C5 /* DOMWindowExtensionBasic.cpp in Sources */, - F6F49C6915545C8E0007F39D /* DOMWindowExtensionNoCache.cpp in Sources */, - C045F9451385C2EA00C0F3CD /* DownloadDecideDestinationCrash.cpp in Sources */, - C07E6CAF13FD67650038B22B /* DynamicDeviceScaleFactor.mm in Sources */, - BCAA485814A044D40088FAC4 /* EditorCommands.mm in Sources */, - 4BB4160416815F9100824238 /* ElementAtPointInWebFrame.mm in Sources */, - 1A5FEFDD1270E2A3000E2921 /* EvaluateJavaScript.cpp in Sources */, - BCC8B95B12611F4700DE46A4 /* FailedLoad.cpp in Sources */, - 1A02C84F125D4A8400E3F4BD /* Find.cpp in Sources */, - C51AFB99169F49FF009CCF66 /* FindMatches.mm in Sources */, - 1ADBEFAE130C689C00D61D19 /* ForceRepaint.cpp in Sources */, - BCBD3710125AA2EB00D2C29F /* FrameMIMETypeHTML.cpp in Sources */, - BCBD3761125ABCFE00D2C29F /* FrameMIMETypePNG.cpp in Sources */, - 290F427B172A23A500939FF0 /* TestProtocol.mm in Sources */, - 1AA9E55914980A9900001A8A /* Functional.cpp in Sources */, - C0C5D3BE14598B6F00A802A6 /* GetBackingScaleFactor.mm in Sources */, - F660AA0D15A5F061003A1243 /* GetInjectedBundleInitializationUserDataCallback.cpp in Sources */, - 0BCD833514857CE400EA2003 /* HashMap.cpp in Sources */, - 2DD7D3AA178205D00026E1E3 /* ResizeReversePaginatedWebView.cpp in Sources */, - 26B2DFF915BDE599004F691D /* HashSet.cpp in Sources */, - 4BFDFFA9131477770061F24B /* HitTestResultNodeHandle.cpp in Sources */, - 9B4F8FA4159D52B1002D9F94 /* HTMLCollectionNamedItem.mm in Sources */, - 9B26FC6C159D061000CC3765 /* HTMLFormCollectionNamedItem.mm in Sources */, - C2EB2DD316CAC7AC009B52EE /* WebViewDidCreateJavaScriptContext.mm in Sources */, - BC575AAD126E83B9006F0F12 /* InjectedBundleBasic.cpp in Sources */, - 378E64731632646D00B6C676 /* InjectedBundleFrameHitTest.cpp in Sources */, - F660AA1315A619C9003A1243 /* InjectedBundleInitializationUserDataCallbackWins.cpp in Sources */, - C507E8A714C6545B005D6B3B /* InspectorBar.mm in Sources */, - C08587FC13FEC39B001EF4E5 /* InstanceMethodSwizzler.mm in Sources */, - C085880013FEC3A6001EF4E5 /* InstanceMethodSwizzler.mm in Sources */, - 266FAFD315E5775200F61D5B /* IntegerToStringConversion.cpp in Sources */, - C0ADBE7C12FCA4D000D2C129 /* JavaScriptTest.cpp in Sources */, - C081224213FC172400DC39AE /* JavaScriptTestMac.mm in Sources */, - 4BB4160216815B2600824238 /* JSWrapperForNodeInWebFrame.mm in Sources */, - 440A1D3914A0103A008A66F2 /* KURL.cpp in Sources */, - 14464013167A8305000BD218 /* LayoutUnit.cpp in Sources */, - 2D640B5517875DFF00BFAF99 /* ScrollPinningBehaviors.cpp in Sources */, - 26300B1816755CD90066886D /* ListHashSet.cpp in Sources */, - 52CB47411448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp in Sources */, - 33DC8911141953A300747EF7 /* LoadCanceledNoServerRedirectCallback.cpp in Sources */, - 8AA28C1A16D2FA7B002FF4DB /* LoadPageOnCrash.cpp in Sources */, - CD5393C81757BA9700C07123 /* MD5.cpp in Sources */, - B4039F9D15E6D8B3007255D6 /* MathExtras.cpp in Sources */, - CD5497B415857F0C00B5BC30 /* MediaTime.cpp in Sources */, - E1220DA0155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm in Sources */, - 517E7DFC15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm in Sources */, - 0FC6C4CF141034AD005B7F0C /* MetaAllocator.cpp in Sources */, - 33BE5AF5137B5A6C00705813 /* MouseMoveAfterCrash.cpp in Sources */, - 93F1DB3114DA20760024C362 /* NewFirstVisuallyNonEmptyLayout.cpp in Sources */, - 93F1DB5514DB1B730024C362 /* NewFirstVisuallyNonEmptyLayoutFails.cpp in Sources */, - 9318778915EEC57700A9CCE3 /* NewFirstVisuallyNonEmptyLayoutForImages.cpp in Sources */, - 7CFBCADF1743234F00B2BFCF /* WillLoad.cpp in Sources */, - 93F7E86C14DC8E4D00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames.cpp in Sources */, - BC90977A125571AB00083756 /* PageLoadBasic.cpp in Sources */, - BC2D004912A9FDFA00E732A3 /* PageLoadDidChangeLocationWithinPageForFrame.cpp in Sources */, - A51B650916ADF9B1007AA5D9 /* PageVisibilityState.cpp in Sources */, - A57A34F016AF677200C2501F /* PageVisibilityStateWithWindowChanges.mm in Sources */, - 52E5CE4614D21E9D003B2BD8 /* ParentFrame.cpp in Sources */, - C54237F016B8955800E638FC /* PasteboardNotifications.mm in Sources */, - BC575BC0126F5752006F0F12 /* PlatformUtilities.cpp in Sources */, - BC131885117114B600B69727 /* PlatformUtilitiesMac.mm in Sources */, - BC90955D125548AA00083756 /* PlatformWebViewMac.mm in Sources */, - 333B9CE21277F23100FEFCE3 /* PreventEmptyUserAgent.cpp in Sources */, - B55AD1D2179F336C00AC1494 /* PreventImageLoadWithAutoResizing.mm in Sources */, - F6FDDDD314241AD4004F1729 /* PrivateBrowsingPushStateNoHistoryCallback.cpp in Sources */, - 00BC16871680FE810065F1E5 /* PublicSuffix.mm in Sources */, - 0FC6C4CC141027E0005B7F0C /* RedBlackTree.cpp in Sources */, - 8A3AF93B16C9ED2700D248C1 /* ReloadPageAfterCrash.cpp in Sources */, - 8A2C750E16CED9550024F352 /* ResizeWindowAfterCrash.cpp in Sources */, - 3722C8691461E03E00C45D00 /* RenderedImageFromDOMRange.mm in Sources */, - C0BD669D131D3CF700E18F2A /* ResponsivenessTimerDoesntFireEarly.cpp in Sources */, - C0ADBE8312FCA6AA00D2C129 /* RestoreSessionStateContainingFormData.cpp in Sources */, - 1AEF994917A09F5400998EF0 /* GetPIDAfterAbortedProcessLaunch.cpp in Sources */, - BC029B181486AD6400817DA9 /* RetainPtr.cpp in Sources */, - BC029B1C1486B25900817DA9 /* RetainPtr.mm in Sources */, - C0991C51143C7D68007998F2 /* RetainPtrHashing.cpp in Sources */, - CD5393CA1757BAC400C07123 /* SHA1.cpp in Sources */, - 14F3B11315E45EAB00210069 /* SaturatedArithmeticOperations.cpp in Sources */, - 261516D615B0E60500A2C201 /* SetAndUpdateCacheModel.mm in Sources */, - 52B8CF9615868CF000281053 /* SetDocumentURI.mm in Sources */, - 7C8DDAAB1735DEEE00EA5AC0 /* CloseThenTerminate.cpp in Sources */, - 51FCF79A1534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp in Sources */, - C540F776152E4DA000A40C8C /* SimplifyMarkup.mm in Sources */, - C02B77F2126612140026BF0F /* SpacebarScrolling.cpp in Sources */, - E194E1BB177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm in Sources */, - 81B50193140F232300D9EB58 /* StringBuilder.cpp in Sources */, - 3799AD3A14120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm in Sources */, - 93ABA80916DDAB91002DB2FA /* StringHasher.cpp in Sources */, - 26F1B44515CA434F00D1E4BF /* StringImpl.cpp in Sources */, - C01363C813C3997300EF3964 /* StringOperators.cpp in Sources */, - 37A6895F148A9B50005100FA /* SubresourceErrorCrash.mm in Sources */, - C081224513FC19EC00DC39AE /* SyntheticBackingScaleFactorWindow.m in Sources */, - 0BCD856A1485C98B00EA2003 /* TemporaryChange.cpp in Sources */, - E4A757D4178AF1B100B5D7A4 /* Deque.cpp in Sources */, - 29AB8AA4164C7A9300D49BEC /* TestBrowsingContextLoadDelegate.mm in Sources */, - BC131AA9117131FC00B69727 /* TestsController.cpp in Sources */, - E490296814E2E3A4002BEDD1 /* TypingStyleCrash.mm in Sources */, - 2943BE86161DFEB800999E3D /* UserContentTest.mm in Sources */, - 1A7BFC0C171A0BDB00BC5F64 /* WillSendSubmitEvent.mm in Sources */, - BC22D31514DC689800FFB1DD /* UserMessage.cpp in Sources */, - BC55F5F914AD78EE00484BE1 /* Vector.cpp in Sources */, - BC90964C125561BF00083756 /* VectorBasic.cpp in Sources */, - 37200B9213A16230007A4FAD /* VectorReverse.cpp in Sources */, - 290A9BB71735DE8A00D71BBC /* CloseNewWindowInNavigationPolicyDelegate.mm in Sources */, - FE217ECD1640A54A0052988B /* VMInspector.cpp in Sources */, - 520BCF4D141EB09E00937EA8 /* WebArchive.cpp in Sources */, - 0F17BBD615AF6C4D007AB753 /* WebCoreStatisticsWithNoWebProcess.cpp in Sources */, - 290F4278172A232C00939FF0 /* CustomProtocolsSyncXHRTest.mm in Sources */, - C08587BF13FE956C001EF4E5 /* WebKitAgnosticTest.mm in Sources */, - 51FBBB4D1513D4E900822738 /* WebViewCanPasteURL.mm in Sources */, - 37E38C34169B7D010084C28C /* WebViewDidRemoveFrameFromHierarchy.mm in Sources */, - 76E182DA1547550100F1FADD /* WillSendSubmitEvent.cpp in Sources */, - A5E2027315B2181900C13E14 /* WindowlessWebViewWithMedia.mm in Sources */, - F6B7BE9417469209008A3445 /* DidAssociateFormControls.cpp in Sources */, - BC3C4C7F14587AA60025FB62 /* WKBrowsingContextGroupTest.mm in Sources */, - BC3C4C7214575B6A0025FB62 /* WKBrowsingContextLoadDelegateTest.mm in Sources */, - BC901E241492ADCE0074A667 /* WKConnection.cpp in Sources */, - 51E93017156B13E1004C99DF /* WKPageGetScaleFactorNotZero.cpp in Sources */, - BC7B61AA129A038700D174A4 /* WKPreferences.cpp in Sources */, - BC90995E12567BC100083756 /* WKString.cpp in Sources */, - BC9099941256ACF100083756 /* WKStringJSString.cpp in Sources */, - 265AF55015D1E48A00B0CB4A /* WTFString.cpp in Sources */, - 2E7765CD16C4D80A00BA2BB1 /* mainIOS.mm in Sources */, - 2E7765CF16C4D81100BA2BB1 /* mainMac.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BC57597D126E74AF006F0F12 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - BC246D9C132F1FF000B56D7C /* CanHandleRequest_Bundle.cpp in Sources */, - BCB68042126FBFF100642A61 /* DocumentStartUserScriptAlertCrash_Bundle.cpp in Sources */, - 51393E221523952D005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp in Sources */, - F6F49C6B15545CA70007F39D /* DOMWindowExtensionNoCache_Bundle.cpp in Sources */, - C0C5D3C61459912900A802A6 /* GetBackingScaleFactor_Bundle.mm in Sources */, - B55AD1D5179F3B3000AC1494 /* PreventImageLoadWithAutoResizing_Bundle.cpp in Sources */, - F660AA1115A5F631003A1243 /* GetInjectedBundleInitializationUserDataCallback_Bundle.cpp in Sources */, - 4BFDFFA71314776C0061F24B /* HitTestResultNodeHandle_Bundle.cpp in Sources */, - BC575AB0126E83C8006F0F12 /* InjectedBundleBasic_Bundle.cpp in Sources */, - BC575AA2126E7660006F0F12 /* InjectedBundleController.cpp in Sources */, - 1AEDE22613E5E7E700E62FE8 /* InjectedBundleControllerMac.mm in Sources */, - 378E64771632655E00B6C676 /* InjectedBundleFrameHitTest_Bundle.cpp in Sources */, - 297234B7173AFAC700983601 /* CustomProtocolsInvalidScheme_Bundle.cpp in Sources */, - F660AA1515A61ABF003A1243 /* InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp in Sources */, - BC575A97126E74F1006F0F12 /* InjectedBundleMain.cpp in Sources */, - 33DC89141419579F00747EF7 /* LoadCanceledNoServerRedirectCallback_Bundle.cpp in Sources */, - 33BE5AF9137B5AAE00705813 /* MouseMoveAfterCrash_Bundle.cpp in Sources */, - 93F1DB3414DA20870024C362 /* NewFirstVisuallyNonEmptyLayout_Bundle.cpp in Sources */, - 93F1DB5714DB1B840024C362 /* NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp in Sources */, - 93AF4ECE1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp in Sources */, - 93F7E86F14DC8E5C00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp in Sources */, - 52E5CE4914D21EAB003B2BD8 /* ParentFrame_Bundle.cpp in Sources */, - C54237F116B8957D00E638FC /* PasteboardNotifications_Bundle.cpp in Sources */, - 7CFBCAE51743238F00B2BFCF /* WillLoad_Bundle.cpp in Sources */, - BC575BD9126F58E2006F0F12 /* PlatformUtilities.cpp in Sources */, - BC575BE0126F590D006F0F12 /* PlatformUtilitiesMac.mm in Sources */, - F6B7BE9517469212008A3445 /* DidAssociateFormControls_Bundle.cpp in Sources */, - C0BD669F131D3CFF00E18F2A /* ResponsivenessTimerDoesntFireEarly_Bundle.cpp in Sources */, - 51FCF7A11534B2A000104491 /* ShouldGoToBackForwardListItem_Bundle.cpp in Sources */, - BC22D31914DC68B900FFB1DD /* UserMessage_Bundle.cpp in Sources */, - 520BCF4C141EB09E00937EA8 /* WebArchive_Bundle.cpp in Sources */, - 76E182DD1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp in Sources */, - BC901E331492AF390074A667 /* WKConnection_Bundle.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - BC575A96126E74E7006F0F12 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = BC57597F126E74AF006F0F12 /* InjectedBundleTestWebKitAPI */; - targetProxy = BC575A95126E74E7006F0F12 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 1DEB927508733DD40010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BC90958012554CF900083756 /* TestWebKitAPI.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 1DEB927608733DD40010E9CD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BC90958012554CF900083756 /* TestWebKitAPI.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 1DEB927908733DD40010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BC90957F12554CF900083756 /* DebugRelease.xcconfig */; - buildSettings = { - DEBUG_DEFINES = "$(DEBUG_DEFINES_debug)"; - GCC_OPTIMIZATION_LEVEL = 0; - }; - name = Debug; - }; - 1DEB927A08733DD40010E9CD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BC90957F12554CF900083756 /* DebugRelease.xcconfig */; - buildSettings = { - }; - name = Release; - }; - BC575984126E74AF006F0F12 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BC575AE2126E88B1006F0F12 /* InjectedBundle.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - BC575985126E74AF006F0F12 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BC575AE2126E88B1006F0F12 /* InjectedBundle.xcconfig */; - buildSettings = { - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "TestWebKitAPI" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB927508733DD40010E9CD /* Debug */, - 1DEB927608733DD40010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "TestWebKitAPI" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB927908733DD40010E9CD /* Debug */, - 1DEB927A08733DD40010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - BC575986126E74AF006F0F12 /* Build configuration list for PBXNativeTarget "InjectedBundleTestWebKitAPI" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BC575984126E74AF006F0F12 /* Debug */, - BC575985126E74AF006F0F12 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/Tools/TestWebKitAPI/Tests.pri b/Tools/TestWebKitAPI/Tests.pri deleted file mode 100644 index 15e81c094..000000000 --- a/Tools/TestWebKitAPI/Tests.pri +++ /dev/null @@ -1,3 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += Tests/WTF Tests/JavaScriptCore Tests/WebKit2 diff --git a/Tools/TestWebKitAPI/Tests/CustomProtocolsSyncXHRTest.mm b/Tools/TestWebKitAPI/Tests/CustomProtocolsSyncXHRTest.mm deleted file mode 100644 index 461cd75bd..000000000 --- a/Tools/TestWebKitAPI/Tests/CustomProtocolsSyncXHRTest.mm +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2013 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 "JavaScriptTest.h" -#import "Test.h" - -#import "PlatformUtilities.h" -#import "TestBrowsingContextLoadDelegate.h" -#import "TestProtocol.h" -#import <WebKit2/WKBrowsingContextGroupPrivate.h> -#import <WebKit2/WKPreferencesPrivate.h> -#import <WebKit2/WKRetainPtr.h> -#import <WebKit2/WKString.h> -#import <WebKit2/WKViewPrivate.h> -#import <wtf/RetainPtr.h> - -static bool testFinished = false; - -namespace TestWebKitAPI { - -TEST(WebKit2CustomProtocolsTest, SyncXHR) -{ - [NSURLProtocol registerClass:[TestProtocol class]]; - [WKBrowsingContextController registerSchemeForCustomProtocol:[TestProtocol scheme]]; - - RetainPtr<WKProcessGroup> processGroup = adoptNS([[WKProcessGroup alloc] init]); - RetainPtr<WKBrowsingContextGroup> browsingContextGroup = adoptNS([[WKBrowsingContextGroup alloc] initWithIdentifier:@"TestIdentifier"]); - - // Allow file URLs to load non-file resources - WKRetainPtr<WKPreferencesRef> preferences(AdoptWK, WKPreferencesCreate()); - WKPreferencesSetUniversalAccessFromFileURLsAllowed(preferences.get(), true); - WKPageGroupSetPreferences(browsingContextGroup.get()._pageGroupRef, preferences.get()); - - RetainPtr<WKView> wkView = adoptNS([[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) processGroup:processGroup.get() browsingContextGroup:browsingContextGroup.get()]); - RetainPtr<TestBrowsingContextLoadDelegate> delegate = adoptNS([[TestBrowsingContextLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) { - EXPECT_JS_EQ(wkView.get().pageRef, "window._testResult", "PASS"); - testFinished = true; - }]); - wkView.get().browsingContextController.loadDelegate = delegate.get(); - - WKPageLoadURL(wkView.get().pageRef, Util::createURLForResource("custom-protocol-sync-xhr", "html")); - - TestWebKitAPI::Util::run(&testFinished); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/JavaScriptCore/JavaScriptCore.pro b/Tools/TestWebKitAPI/Tests/JavaScriptCore/JavaScriptCore.pro deleted file mode 100644 index 9d44fad0e..000000000 --- a/Tools/TestWebKitAPI/Tests/JavaScriptCore/JavaScriptCore.pro +++ /dev/null @@ -1,8 +0,0 @@ -TEMPLATE = app -TARGET = tst_jsc - -SOURCES += *.cpp - -include(../../TestWebKitAPI.pri) - -DEFINES += APITEST_SOURCE_DIR=\\\"$$PWD\\\" diff --git a/Tools/TestWebKitAPI/Tests/JavaScriptCore/VMInspector.cpp b/Tools/TestWebKitAPI/Tests/JavaScriptCore/VMInspector.cpp deleted file mode 100644 index b1c1bacf3..000000000 --- a/Tools/TestWebKitAPI/Tests/JavaScriptCore/VMInspector.cpp +++ /dev/null @@ -1,689 +0,0 @@ -/* - * 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. - */ - -#include "config.h" - -#include <interpreter/VMInspector.h> -#include <stdarg.h> -#include <stdio.h> - -using namespace JSC; - -// There's not much we can test for the VMInspector::printf() case except to -// make sure it does not crash. Unfortunately, we also don't want all the -// test strings crowding out stdout. So, we forego the printf tests. -// NOTE that the most interesting part of VMInspector::printf() is the -// formatting functionality, and it is are already being tested by the -// fprintf() and sprintf() cases. - - -// The VMInspector::fprintf() test works by printing the string to a temp file, -// and then reading the file content back into a buffer, which we, in turn, -// compare against the expected string. - -TEST(JSC, VMInspectorFprintf) -{ -#if ENABLE(VMINSPECTOR) - char actual[1024]; - char expected[1024]; - const char* format; - const char* expectedLiteral; - FILE* file; - const char* filename = "/tmp/VMInspectorFprintfTest.txt"; - size_t size; - -#define OPEN_FILE(file) \ - do { \ - file = fopen(filename, "w"); \ - } while (false) - -#define READ_AND_CLOSE_FILE(file, actual) \ - do { \ - fclose(file); \ - file = fopen(filename, "r"); \ - fseek(file, 0, SEEK_END); \ - size = ftell(file); \ - rewind(file); \ - fread(actual, 1, size, file); \ - actual[size] = '\0'; \ - fclose(file); \ - } while (false) - - // Testing standard default format specifiers: - // Note: should work just like sprintf. So, we just compare against that. - memset(actual, 'z', sizeof(actual)); - // The compiler warning flags are configured to expect a literal string for - // ::sprintf below. So, use a #define for this one case to keep the - // compiler happy. -#undef LITERAL_FORMAT -#define LITERAL_FORMAT "'%%%%' ==> '%%'\n" - - OPEN_FILE(file); - VMInspector::fprintf(file, LITERAL_FORMAT); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, LITERAL_FORMAT); - -#undef LITERAL_FORMAT - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%c', 'x' ==> '%c'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 'x'); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 'x'); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%*c', 8, 'x' ==> '%*c'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 8, 'x'); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 8, 'x'); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%s', \"hello world\" ==> '%s'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, "hello world"); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, "hello world"); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%*s', 8, \"hello world\" ==> '%*s'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 8, "hello world"); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 8, "hello world"); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%*s', 8, \"hello\" ==> '%*s'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 8, "hello"); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 8, "hello"); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%d', 987654321 ==> '%d'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 987654321); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 987654321); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%u', 4276543210u ==> '%u'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 4276543210u); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 4276543210u); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%u', 0xffffffff ==> '%u'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 0xffffffff); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 0xffffffff); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%x', 0xffffffff ==> '%x'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 0xffffffff); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 0xffffffff); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%p', (void*)0xabcdbabe ==> '%p'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, (void*)0xabcdbabe); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, (void*)0xabcdbabe); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%lu', 1234567890987654321ul ==> '%lu'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 1234567890987654321ul); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 1234567890987654321ul); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%f', 1234.567 ==> '%f'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 1234.567); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%.2f', 1234.567 ==> '%.2f'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 1234.567); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%10.2f', 1234.567 ==> '%10.2f'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 1234.567); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%010.2f', 1234.567 ==> '%010.2f'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 1234.567); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - // Bad / weird formats: - memset(actual, 'z', sizeof(actual)); - format = "'%%5.4', 987654321 ==> '%5.4'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 987654321); - READ_AND_CLOSE_FILE(file, actual); - expectedLiteral = "'%5.4', 987654321 ==> 'ERROR @ \"%5.4' \"\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%5.4' '%%d', 987654321, 4 ==> '%5.4' '%d'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 987654321, 4); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 987654321, 4); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%w' '%%d', 987654321, 6 ==> '%w' '%d'\n"; - OPEN_FILE(file); - VMInspector::fprintf(file, format, 987654321, 6); - READ_AND_CLOSE_FILE(file, actual); - ::sprintf(expected, format, 987654321, 6); - ASSERT_EQ(strcmp(actual, expected), 0); - - - // Testing the %b extension: - memset(actual, 'z', sizeof(actual)); - OPEN_FILE(file); - VMInspector::fprintf(file, "'%%b', 0 ==> '%b'\n", 0); - READ_AND_CLOSE_FILE(file, actual); - ASSERT_EQ(strcmp(actual, "'%b', 0 ==> 'FALSE'\n"), 0); - - memset(actual, 'z', sizeof(actual)); - OPEN_FILE(file); - VMInspector::fprintf(file, "'%%b', 1 ==> '%b'\n", 1); - READ_AND_CLOSE_FILE(file, actual); - ASSERT_EQ(strcmp(actual, "'%b', 1 ==> 'TRUE'\n"), 0); - - memset(actual, 'z', sizeof(actual)); - OPEN_FILE(file); - VMInspector::fprintf(file, "'%%b', -123456789 ==> '%b'\n", -123456789); - READ_AND_CLOSE_FILE(file, actual); - ASSERT_EQ(strcmp(actual, "'%b', -123456789 ==> 'TRUE'\n"), 0); - - memset(actual, 'z', sizeof(actual)); - OPEN_FILE(file); - VMInspector::fprintf(file, "'%%b', 123456789 ==> '%b'\n", 123456789); - READ_AND_CLOSE_FILE(file, actual); - ASSERT_EQ(strcmp(actual, "'%b', 123456789 ==> 'TRUE'\n"), 0); - - - // Testing the %J<x> extensions: - String str1("Test WTF String"); - String str2(""); - - memset(actual, 'z', sizeof(actual)); - OPEN_FILE(file); - VMInspector::fprintf(file, "'%%Js' is %%s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%Js' is %s\n", - &str1, str1.isEmpty() ? "EMPTY" : "NOT EMPTY"); - READ_AND_CLOSE_FILE(file, actual); - expectedLiteral = "'%Js' is %s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> 'Test WTF String' is NOT EMPTY\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); - - memset(actual, 'z', sizeof(actual)); - OPEN_FILE(file); - VMInspector::fprintf(file, "'%%Js' is %%s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%Js' is %s\n", - &str2, str2.isEmpty() ? "EMPTY" : "NOT EMPTY"); - READ_AND_CLOSE_FILE(file, actual); - expectedLiteral = "'%Js' is %s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '' is EMPTY\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); - - memset(actual, 'z', sizeof(actual)); - OPEN_FILE(file); - VMInspector::fprintf(file, "'%%J+s' is %%s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%J+s' is %s\n", - &str1, str1.isEmpty() ? "EMPTY" : "NOT EMPTY"); - READ_AND_CLOSE_FILE(file, actual); - expectedLiteral = "'%J+s' is %s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> 'WTF::String \"Test WTF String\"' is NOT EMPTY\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); - - memset(actual, 'z', sizeof(actual)); - OPEN_FILE(file); - VMInspector::fprintf(file, "'%%J+s' is %%s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%J+s' is %s\n", - &str2, str2.isEmpty() ? "EMPTY" : "NOT EMPTY"); - READ_AND_CLOSE_FILE(file, actual); - expectedLiteral = "'%J+s' is %s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> 'WTF::String \"\"' is EMPTY\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); - -#undef OPEN_FILE -#undef READ_AND_CLOSE_FILE - -#endif -} - - -TEST(JSC, VMInspectorSprintf) -{ -#if ENABLE(VMINSPECTOR) - char actual[1024]; - char expected[1024]; - const char* format; - const char* expectedLiteral; - - // Testing standard default format specifiers: - // Note: should work just like sprintf. So, we just compare against that. - memset(actual, 'z', sizeof(actual)); - // The compiler warning flags are configured to expect a literal string for - // ::sprintf below. So, use a #define for this one case to keep the - // compiler happy. -#undef LITERAL_FORMAT -#define LITERAL_FORMAT "'%%%%' ==> '%%'\n" - VMInspector::sprintf(actual, LITERAL_FORMAT); - ::sprintf(expected, LITERAL_FORMAT); -#undef LITERAL_FORMAT - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%c', 'x' ==> '%c'\n"; - VMInspector::sprintf(actual, format, 'x'); - ::sprintf(expected, format, 'x'); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%*c', 8, 'x' ==> '%*c'\n"; - VMInspector::sprintf(actual, format, 8, 'x'); - ::sprintf(expected, format, 8, 'x'); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%s', \"hello world\" ==> '%s'\n"; - VMInspector::sprintf(actual, format, "hello world"); - ::sprintf(expected, format, "hello world"); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%*s', 8, \"hello world\" ==> '%*s'\n"; - VMInspector::sprintf(actual, format, 8, "hello world"); - ::sprintf(expected, format, 8, "hello world"); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%*s', 8, \"hello\" ==> '%*s'\n"; - VMInspector::sprintf(actual, format, 8, "hello"); - ::sprintf(expected, format, 8, "hello"); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%d', 987654321 ==> '%d'\n"; - VMInspector::sprintf(actual, format, 987654321); - ::sprintf(expected, format, 987654321); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%u', 4276543210u ==> '%u'\n"; - VMInspector::sprintf(actual, format, 4276543210u); - ::sprintf(expected, format, 4276543210u); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%u', 0xffffffff ==> '%u'\n"; - VMInspector::sprintf(actual, format, 0xffffffff); - ::sprintf(expected, format, 0xffffffff); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%x', 0xffffffff ==> '%x'\n"; - VMInspector::sprintf(actual, format, 0xffffffff); - ::sprintf(expected, format, 0xffffffff); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%p', (void*)0xabcdbabe ==> '%p'\n"; - VMInspector::sprintf(actual, format, (void*)0xabcdbabe); - ::sprintf(expected, format, (void*)0xabcdbabe); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%lu', 1234567890987654321ul ==> '%lu'\n"; - VMInspector::sprintf(actual, format, 1234567890987654321ul); - ::sprintf(expected, format, 1234567890987654321ul); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%f', 1234.567 ==> '%f'\n"; - VMInspector::sprintf(actual, format, 1234.567); - ::sprintf(expected, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%.2f', 1234.567 ==> '%.2f'\n"; - VMInspector::sprintf(actual, format, 1234.567); - ::sprintf(expected, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%10.2f', 1234.567 ==> '%10.2f'\n"; - VMInspector::sprintf(actual, format, 1234.567); - ::sprintf(expected, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%010.2f', 1234.567 ==> '%010.2f'\n"; - VMInspector::sprintf(actual, format, 1234.567); - ::sprintf(expected, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - // Bad / weird formats: - memset(actual, 'z', sizeof(actual)); - format = "'%%5.4', 987654321 ==> '%5.4'\n"; - VMInspector::sprintf(actual, format, 987654321); - expectedLiteral = "'%5.4', 987654321 ==> 'ERROR @ \"%5.4' \"\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%5.4' '%%d', 987654321, 4 ==> '%5.4' '%d'\n"; - VMInspector::sprintf(actual, format, 987654321, 4); - ::sprintf(expected, format, 987654321, 4); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%w' '%%d', 987654321, 6 ==> '%w' '%d'\n"; - VMInspector::sprintf(actual, format, 987654321, 6); - ::sprintf(expected, format, 987654321, 6); - ASSERT_EQ(strcmp(actual, expected), 0); - - - // Testing the %b extension: - memset(actual, 'z', sizeof(actual)); - VMInspector::sprintf(actual, "'%%b', 0 ==> '%b'\n", 0); - ASSERT_EQ(strcmp(actual, "'%b', 0 ==> 'FALSE'\n"), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::sprintf(actual, "'%%b', 1 ==> '%b'\n", 1); - ASSERT_EQ(strcmp(actual, "'%b', 1 ==> 'TRUE'\n"), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::sprintf(actual, "'%%b', -123456789 ==> '%b'\n", -123456789); - ASSERT_EQ(strcmp(actual, "'%b', -123456789 ==> 'TRUE'\n"), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::sprintf(actual, "'%%b', 123456789 ==> '%b'\n", 123456789); - ASSERT_EQ(strcmp(actual, "'%b', 123456789 ==> 'TRUE'\n"), 0); - - - // Testing the %J<x> extensions: - String str1("Test WTF String"); - String str2(""); - - memset(actual, 'z', sizeof(actual)); - VMInspector::sprintf(actual, "'%%Js' is %%s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%Js' is %s\n", - &str1, str1.isEmpty() ? "EMPTY" : "NOT EMPTY"); - expectedLiteral = "'%Js' is %s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> 'Test WTF String' is NOT EMPTY\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::sprintf(actual, "'%%Js' is %%s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%Js' is %s\n", - &str2, str2.isEmpty() ? "EMPTY" : "NOT EMPTY"); - expectedLiteral = "'%Js' is %s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '' is EMPTY\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::sprintf(actual, "'%%J+s' is %%s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%J+s' is %s\n", - &str1, str1.isEmpty() ? "EMPTY" : "NOT EMPTY"); - expectedLiteral = "'%J+s' is %s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> 'WTF::String \"Test WTF String\"' is NOT EMPTY\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::sprintf(actual, "'%%J+s' is %%s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%J+s' is %s\n", - &str2, str2.isEmpty() ? "EMPTY" : "NOT EMPTY"); - expectedLiteral = "'%J+s' is %s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> 'WTF::String \"\"' is EMPTY\n"; - ASSERT_EQ(strcmp(actual, expectedLiteral), 0); -#endif -} - - -TEST(JSC, VMInspectorSnprintf) -{ -#if ENABLE(VMINSPECTOR) - char actual[1024]; - char expected[1024]; - const char* format; - const char* expectedLiteral; - - size_t size = 1; - while (size <= 100) { - - // Testing standard default format specifiers: - // Note: should work just like snprintf. So, we just compare against that. - memset(actual, 'z', sizeof(actual)); - // The compiler warning flags are configured to expect a literal string for - // ::snprintf below. So, use a #define for this one case to keep the - // compiler happy. -#undef LITERAL_FORMAT -#define LITERAL_FORMAT "'%%%%' ==> '%%'\n" - VMInspector::snprintf(actual, size, LITERAL_FORMAT); - ::snprintf(expected, size, LITERAL_FORMAT); -#undef LITERAL_FORMAT - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%c', 'x' ==> '%c'\n"; - VMInspector::snprintf(actual, size, format, 'x'); - ::snprintf(expected, size, format, 'x'); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%*c', 8, 'x' ==> '%*c'\n"; - VMInspector::snprintf(actual, size, format, 8, 'x'); - ::snprintf(expected, size, format, 8, 'x'); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%s', \"hello world\" ==> '%s'\n"; - VMInspector::snprintf(actual, size, format, "hello world"); - ::snprintf(expected, size, format, "hello world"); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%*s', 8, \"hello world\" ==> '%*s'\n"; - VMInspector::snprintf(actual, size, format, 8, "hello world"); - ::snprintf(expected, size, format, 8, "hello world"); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%*s', 8, \"hello\" ==> '%*s'\n"; - VMInspector::snprintf(actual, size, format, 8, "hello"); - ::snprintf(expected, size, format, 8, "hello"); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%d', 987654321 ==> '%d'\n"; - VMInspector::snprintf(actual, size, format, 987654321); - ::snprintf(expected, size, format, 987654321); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%u', 4276543210u ==> '%u'\n"; - VMInspector::snprintf(actual, size, format, 4276543210u); - ::snprintf(expected, size, format, 4276543210u); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%u', 0xffffffff ==> '%u'\n"; - VMInspector::snprintf(actual, size, format, 0xffffffff); - ::snprintf(expected, size, format, 0xffffffff); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%x', 0xffffffff ==> '%x'\n"; - VMInspector::snprintf(actual, size, format, 0xffffffff); - ::snprintf(expected, size, format, 0xffffffff); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%p', (void*)0xabcdbabe ==> '%p'\n"; - VMInspector::snprintf(actual, size, format, (void*)0xabcdbabe); - ::snprintf(expected, size, format, (void*)0xabcdbabe); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%lu', 1234567890987654321ul ==> '%lu'\n"; - VMInspector::snprintf(actual, size, format, 1234567890987654321ul); - ::snprintf(expected, size, format, 1234567890987654321ul); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%f', 1234.567 ==> '%f'\n"; - VMInspector::snprintf(actual, size, format, 1234.567); - ::snprintf(expected, size, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%.2f', 1234.567 ==> '%.2f'\n"; - VMInspector::snprintf(actual, size, format, 1234.567); - ::snprintf(expected, size, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%10.2f', 1234.567 ==> '%10.2f'\n"; - VMInspector::snprintf(actual, size, format, 1234.567); - ::snprintf(expected, size, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%010.2f', 1234.567 ==> '%010.2f'\n"; - VMInspector::snprintf(actual, size, format, 1234.567); - ::snprintf(expected, size, format, 1234.567); - ASSERT_EQ(strcmp(actual, expected), 0); - - // Bad / weird formats: - memset(actual, 'z', sizeof(actual)); - format = "'%%5.4', 987654321 ==> '%5.4'\n"; - VMInspector::snprintf(actual, size, format, 987654321); - expectedLiteral = "'%5.4', 987654321 ==> 'ERROR @ \"%5.4' \"\n"; - ::snprintf(expected, size, "%s", expectedLiteral); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%5.4' '%%d', 987654321, 4 ==> '%5.4' '%d'\n"; - VMInspector::snprintf(actual, size, format, 987654321, 4); - ::snprintf(expected, size, format, 987654321, 4); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - format = "'%%w' '%%d', 987654321, 6 ==> '%w' '%d'\n"; - VMInspector::snprintf(actual, size, format, 987654321, 6); - ::snprintf(expected, size, format, 987654321, 6); - ASSERT_EQ(strcmp(actual, expected), 0); - - - // Testing the %b extension: - memset(actual, 'z', sizeof(actual)); - VMInspector::snprintf(actual, size, "'%%b', 0 ==> '%b'\n", 0); - expectedLiteral = "'%b', 0 ==> 'FALSE'\n"; - ::snprintf(expected, size, "%s", expectedLiteral); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::snprintf(actual, size, "'%%b', 1 ==> '%b'\n", 1); - expectedLiteral = "'%b', 1 ==> 'TRUE'\n"; - ::snprintf(expected, size, "%s", expectedLiteral); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::snprintf(actual, size, "'%%b', -123456789 ==> '%b'\n", -123456789); - expectedLiteral = "'%b', -123456789 ==> 'TRUE'\n"; - ::snprintf(expected, size, "%s", expectedLiteral); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::snprintf(actual, size, "'%%b', 123456789 ==> '%b'\n", 123456789); - expectedLiteral = "'%b', 123456789 ==> 'TRUE'\n"; - ::snprintf(expected, size, "%s", expectedLiteral); - ASSERT_EQ(strcmp(actual, expected), 0); - - // Testing the %J<x> extensions: - String str1("Test WTF String"); - String str2(""); - - memset(actual, 'z', sizeof(actual)); - VMInspector::snprintf(actual, size, "'%%Js' is %%s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%Js' is %s\n", - &str1, str1.isEmpty() ? "EMPTY" : "NOT EMPTY"); - expectedLiteral = "'%Js' is %s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> 'Test WTF String' is NOT EMPTY\n"; - ::snprintf(expected, size, "%s", expectedLiteral); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::snprintf(actual, size, "'%%Js' is %%s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%Js' is %s\n", - &str2, str2.isEmpty() ? "EMPTY" : "NOT EMPTY"); - expectedLiteral = "'%Js' is %s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '' is EMPTY\n"; - ::snprintf(expected, size, "%s", expectedLiteral); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::snprintf(actual, size, "'%%J+s' is %%s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%J+s' is %s\n", - &str1, str1.isEmpty() ? "EMPTY" : "NOT EMPTY"); - expectedLiteral = "'%J+s' is %s, &str1, str1.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> 'WTF::String \"Test WTF String\"' is NOT EMPTY\n"; - ::snprintf(expected, size, "%s", expectedLiteral); - ASSERT_EQ(strcmp(actual, expected), 0); - - memset(actual, 'z', sizeof(actual)); - VMInspector::snprintf(actual, size, "'%%J+s' is %%s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> '%J+s' is %s\n", - &str2, str2.isEmpty() ? "EMPTY" : "NOT EMPTY"); - expectedLiteral = "'%J+s' is %s, &str2, str2.isEmpty()?\"EMPTY\":\"NOT EMPTY\" ==> 'WTF::String \"\"' is EMPTY\n"; - ::snprintf(expected, size, "%s", expectedLiteral); - ASSERT_EQ(strcmp(actual, expected), 0); - - // Test lower sizes more densely, and then space out to larger sizes. - // We're doing this because the lower sizes might be interesting, but - // for expediency, we don't want to test at this fine grain resolution - // for all possible sizes. Hence, we accelerate the rate once we're - // pass the interesting small sizes. - if (size <= 5) - size++; - else - size += 4; - } -#endif -} diff --git a/Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/InstanceMethodSwizzler.mm b/Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/InstanceMethodSwizzler.mm deleted file mode 100644 index 94bb7ef97..000000000 --- a/Tools/TestWebKitAPI/Tests/TestWebKitAPI/mac/InstanceMethodSwizzler.mm +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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. - */ - -#import "config.h" -#import "InstanceMethodSwizzler.h" - -#import <wtf/RetainPtr.h> - -@interface SimpleObject : NSObject -- (void)setValue:(int*)value; -@end - -@implementation SimpleObject -- (void)setValue:(int*)value -{ - *value = 1; -} -@end - -namespace TestWebKitAPI { - -static void setValue2(id self, SEL _cmd, int* value) -{ - *value = 2; -} - -static void setValue3(id self, SEL _cmd, int* value) -{ - *value = 3; -} - -TEST(TestWebKitAPI, InstanceMethodSwizzler) -{ - RetainPtr<SimpleObject> object = adoptNS([[SimpleObject alloc] init]); - - int value = 0; - - [object.get() setValue:&value]; - EXPECT_EQ(value, 1); - - { - InstanceMethodSwizzler swizzle([object.get() class], @selector(setValue:), reinterpret_cast<IMP>(setValue2)); - - [object.get() setValue:&value]; - EXPECT_EQ(value, 2); - - { - InstanceMethodSwizzler swizzle([object.get() class], @selector(setValue:), reinterpret_cast<IMP>(setValue3)); - - [object.get() setValue:&value]; - EXPECT_EQ(value, 3); - } - - [object.get() setValue:&value]; - EXPECT_EQ(value, 2); - } - - [object.get() setValue:&value]; - EXPECT_EQ(value, 1); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/AtomicString.cpp b/Tools/TestWebKitAPI/Tests/WTF/AtomicString.cpp index bddf22c23..de962ec42 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/AtomicString.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/AtomicString.cpp @@ -35,14 +35,11 @@ TEST(WTF, AtomicStringCreationFromLiteral) ASSERT_EQ(strlen("Template Literal"), stringWithTemplate.length()); ASSERT_TRUE(stringWithTemplate == "Template Literal"); ASSERT_TRUE(stringWithTemplate.string().is8Bit()); - ASSERT_TRUE(stringWithTemplate.impl()->hasTerminatingNullCharacter()); const char* programmaticStringData = "Explicit Size Literal"; AtomicString programmaticString(programmaticStringData, strlen(programmaticStringData), AtomicString::ConstructFromLiteral); ASSERT_EQ(strlen(programmaticStringData), programmaticString.length()); - ASSERT_TRUE(programmaticStringData == programmaticStringData); ASSERT_TRUE(programmaticString.string().is8Bit()); - ASSERT_TRUE(programmaticString.impl()->hasTerminatingNullCharacter()); ASSERT_EQ(programmaticStringData, reinterpret_cast<const char*>(programmaticString.string().characters8())); } @@ -56,4 +53,12 @@ TEST(WTF, AtomicStringCreationFromLiteralUniqueness) ASSERT_EQ(string1.impl(), string3.impl()); } +TEST(WTF, AtomicStringExistingHash) +{ + AtomicString string1("Template Literal", AtomicString::ConstructFromLiteral); + ASSERT_EQ(string1.existingHash(), string1.impl()->existingHash()); + AtomicString string2; + ASSERT_EQ(string2.existingHash(), 0u); +} + } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/BloomFilter.cpp b/Tools/TestWebKitAPI/Tests/WTF/BloomFilter.cpp new file mode 100644 index 000000000..802165211 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/BloomFilter.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2015 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/BloomFilter.h> +#include <wtf/RandomNumber.h> +#include <wtf/SHA1.h> + +namespace TestWebKitAPI { + +static Vector<unsigned> generateRandomHashes(size_t hashCount) +{ + Vector<unsigned> hashes; + for (unsigned i = 0; i < hashCount; ++i) + hashes.append(static_cast<unsigned>(randomNumber() * std::numeric_limits<unsigned>::max())); + return hashes; +} + +static Vector<SHA1::Digest> generateRandomDigests(size_t hashCount) +{ + Vector<SHA1::Digest> hashes; + SHA1 sha1; + for (unsigned i = 0; i < hashCount; ++i) { + double random = randomNumber(); + sha1.addBytes(reinterpret_cast<uint8_t*>(&random), sizeof(double)); + SHA1::Digest digest; + sha1.computeHash(digest); + hashes.append(digest); + } + return hashes; +} + +TEST(WTF_BloomFilter, Basic) +{ + const unsigned hashCount = 1000; + auto hashes = generateRandomHashes(hashCount); + + BloomFilter<16> filter; + for (auto hash : hashes) + filter.add(hash); + + for (auto hash : hashes) + EXPECT_TRUE(filter.mayContain(hash)); + + auto moreHashes = generateRandomHashes(hashCount); + unsigned mayContainCount = 0; + for (auto hash : moreHashes) + mayContainCount += filter.mayContain(hash) ? 1 : 0; + // False positive rate is ~0.09% so this should always be true. + EXPECT_TRUE(mayContainCount < hashCount / 10); + + for (auto hash : moreHashes) + filter.add(hash); + + for (auto hash : hashes) + EXPECT_TRUE(filter.mayContain(hash)); + for (auto hash : moreHashes) + EXPECT_TRUE(filter.mayContain(hash)); +} + +TEST(WTF_BloomFilter, BasicDigest) +{ + const unsigned hashCount = 1000; + auto hashes = generateRandomDigests(hashCount); + + BloomFilter<20> filter; + for (auto hash : hashes) + filter.add(hash); + + for (auto hash : hashes) + EXPECT_TRUE(filter.mayContain(hash)); + + auto moreHashes = generateRandomDigests(hashCount); + unsigned mayContainCount = 0; + for (auto hash : moreHashes) + mayContainCount += filter.mayContain(hash) ? 1 : 0; + // False positive rate is ~0.000004% so this should always be true. + EXPECT_TRUE(mayContainCount < hashCount / 10); + + for (auto hash : moreHashes) + filter.add(hash); + + for (auto hash : hashes) + EXPECT_TRUE(filter.mayContain(hash)); + for (auto hash : moreHashes) + EXPECT_TRUE(filter.mayContain(hash)); +} + +TEST(WTF_BloomFilter, BasicCounting) +{ + const unsigned hashCount = 1000; + auto hashes = generateRandomHashes(hashCount); + + CountingBloomFilter<16> filter; + for (auto hash : hashes) + filter.add(hash); + + for (auto hash : hashes) + EXPECT_TRUE(filter.mayContain(hash)); + + for (auto hash : hashes) + filter.add(hash); + + for (auto hash : hashes) + EXPECT_TRUE(filter.mayContain(hash)); + + for (auto hash : hashes) + filter.remove(hash); + + for (auto hash : hashes) + EXPECT_TRUE(filter.mayContain(hash)); + + auto moreHashes = generateRandomHashes(hashCount); + unsigned mayContainCount = 0; + for (auto hash : moreHashes) + mayContainCount += filter.mayContain(hash) ? 1 : 0; + // False positive rate is ~0.09% so this should always be true. + EXPECT_TRUE(mayContainCount < hashCount / 10); + + for (auto hash : moreHashes) + filter.add(hash); + for (auto hash : hashes) + filter.remove(hash); + + for (auto hash : moreHashes) + EXPECT_TRUE(filter.mayContain(hash)); + + for (auto hash : moreHashes) + filter.remove(hash); + + for (auto hash : hashes) + EXPECT_TRUE(!filter.mayContain(hash)); + for (auto hash : moreHashes) + EXPECT_TRUE(!filter.mayContain(hash)); +} + +TEST(WTF_BloomFilter, Clear) +{ + const unsigned hashCount = 1000; + auto hashes = generateRandomHashes(hashCount); + + BloomFilter<16> filter; + for (auto hash : hashes) + filter.add(hash); + + filter.clear(); + + for (auto hash : hashes) + EXPECT_TRUE(!filter.mayContain(hash)); +} + +TEST(WTF_BloomFilter, ClearCounting) +{ + const unsigned hashCount = 1000; + auto hashes = generateRandomHashes(hashCount); + + CountingBloomFilter<16> filter; + for (auto hash : hashes) + filter.add(hash); + for (auto hash : hashes) + filter.add(hash); + + filter.clear(); + + for (auto hash : hashes) + EXPECT_TRUE(!filter.mayContain(hash)); +} + +TEST(WTF_BloomFilter, CountingOverflow) +{ + const unsigned hashCount = 1000; + auto hashes = generateRandomHashes(hashCount); + + CountingBloomFilter<16> filter; + for (auto hash : hashes) + filter.add(hash); + + for (unsigned i = 0; i < filter.maximumCount() + 100; ++i) + filter.add(hashes[0]); + + for (auto hash : hashes) + EXPECT_TRUE(filter.mayContain(hash)); + + for (auto hash : hashes) + filter.remove(hash); + + unsigned mayContainCount = 0; + for (auto hash : hashes) { + if (hash == hashes[0]) + EXPECT_TRUE(filter.mayContain(hash)); + else + mayContainCount += filter.mayContain(hash) ? 1 : 0; + } + // False positive rate should be very low. + EXPECT_TRUE(mayContainCount < hashCount / 100); + + for (unsigned i = 0; i < filter.maximumCount() + 100; ++i) + filter.remove(hashes[0]); + + // The bucket has overflowed and is stuck. + EXPECT_TRUE(filter.mayContain(hashes[0])); +} + +TEST(WTF_BloomFilter, Combine) +{ + const unsigned hashCount = 1000; + auto hashes = generateRandomHashes(hashCount); + + BloomFilter<16> filter; + for (auto hash : hashes) + filter.add(hash); + + auto moreHashes = generateRandomHashes(hashCount); + + BloomFilter<16> anotherFilter; + for (auto hash : moreHashes) + anotherFilter.add(hash); + + filter.add(anotherFilter); + + for (auto hash : hashes) + EXPECT_TRUE(filter.mayContain(hash)); + for (auto hash : moreHashes) + EXPECT_TRUE(filter.mayContain(hash)); +} + +} diff --git a/Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp b/Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp index 77b8ff458..d6b548316 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,117 +28,397 @@ namespace TestWebKitAPI { -#define CheckedArithmeticTest(type, coerceLiteral, MixedSignednessTest) \ +class OverflowCrashLogger { +protected: + void overflowed() + { + m_overflowCount++; + } + + void clearOverflow() + { + m_overflowCount = 0; + } + + static void crash() + { + s_didCrash = true; + } + +public: + void reset() + { + m_overflowCount = 0; + s_didCrash = false; + } + + bool hasOverflowed() const { return m_overflowCount > 0; } + int overflowCount() const { return m_overflowCount; } + + bool didCrash() const { return s_didCrash; } + +private: + int m_overflowCount { 0 }; + static bool s_didCrash; +}; + +bool OverflowCrashLogger::s_didCrash = false; + +template <typename type> +static void resetOverflow(Checked<type, OverflowCrashLogger>& value) +{ + value.reset(); + value = 100; + value *= std::numeric_limits<type>::max(); +} + +#define CheckedArithmeticTest(type, Coercer, MixedSignednessTester) \ TEST(WTF, Checked_##type) \ { \ - Checked<type, RecordOverflow> value; \ - EXPECT_EQ(coerceLiteral(0), value.unsafeGet()); \ - EXPECT_EQ(std::numeric_limits<type>::max(), (value + std::numeric_limits<type>::max()).unsafeGet()); \ - EXPECT_EQ(std::numeric_limits<type>::max(), (std::numeric_limits<type>::max() + value).unsafeGet()); \ - EXPECT_EQ(std::numeric_limits<type>::min(), (value + std::numeric_limits<type>::min()).unsafeGet()); \ - EXPECT_EQ(std::numeric_limits<type>::min(), (std::numeric_limits<type>::min() + value).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (value * coerceLiteral(0)).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) * value).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (value * value).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(0)).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) - value).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (value - value).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (value++).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(1), (value--).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(1), (++value).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (--value).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(10), (value += coerceLiteral(10)).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); \ - EXPECT_EQ(coerceLiteral(100), (value *= coerceLiteral(10)).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(100), value.unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (value -= coerceLiteral(100)).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), value.unsafeGet()); \ - value = 10; \ - EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); \ - EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(10)).unsafeGet()); \ - EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); \ - value = std::numeric_limits<type>::min(); \ - EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - coerceLiteral(1))).hasOverflowed()); \ - EXPECT_EQ(true, !((value--).hasOverflowed())); \ - EXPECT_EQ(true, value.hasOverflowed()); \ - value = std::numeric_limits<type>::max(); \ - EXPECT_EQ(true, !value.hasOverflowed()); \ - EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + coerceLiteral(1))).hasOverflowed()); \ - EXPECT_EQ(true, !(value++).hasOverflowed()); \ - EXPECT_EQ(true, value.hasOverflowed()); \ - value = std::numeric_limits<type>::max(); \ - EXPECT_EQ(true, (value += coerceLiteral(1)).hasOverflowed()); \ - EXPECT_EQ(true, value.hasOverflowed()); \ - value = 10; \ - type _value = 0; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(0)).safeGet(_value)); \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(0) * value).safeGet(_value)); \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); \ - value = 0; \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); \ - value = 1; \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); \ - _value = 0; \ - value = 0; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)0).safeGet(_value)); \ - _value = 0; \ - value = 1; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)1).safeGet(_value)); \ - _value = 0; \ - value = 2; \ - EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ - _value = 0; \ - EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)2).safeGet(_value)); \ - value = 10; \ - EXPECT_EQ(true, (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).hasOverflowed()); \ - MixedSignednessTest(EXPECT_EQ(coerceLiteral(0), (value + -10).unsafeGet())); \ - MixedSignednessTest(EXPECT_EQ(0U, (value - 10U).unsafeGet())); \ - MixedSignednessTest(EXPECT_EQ(coerceLiteral(0), (-10 + value).unsafeGet())); \ - MixedSignednessTest(EXPECT_EQ(0U, (10U - value).unsafeGet())); \ - value = std::numeric_limits<type>::min(); \ - MixedSignednessTest(EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - 1)).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, !(value--).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ - value = std::numeric_limits<type>::max(); \ - MixedSignednessTest(EXPECT_EQ(true, !value.hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1)).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, !(value++).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ - value = std::numeric_limits<type>::max(); \ - MixedSignednessTest(EXPECT_EQ(true, (value += 1).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ - value = std::numeric_limits<type>::min(); \ - MixedSignednessTest(EXPECT_EQ(true, (value - 1U).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, !(value--).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ - value = std::numeric_limits<type>::max(); \ - MixedSignednessTest(EXPECT_EQ(true, !value.hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1U)).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, !(value++).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ - value = std::numeric_limits<type>::max(); \ - MixedSignednessTest(EXPECT_EQ(true, (value += 1U).hasOverflowed())); \ - MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ + typedef Coercer<type> CoercerType; \ + typedef MixedSignednessTester<type, CoercerType> MixedSignednessTesterType; \ + CheckedArithmeticTester<type, CoercerType, MixedSignednessTesterType>::run(); \ } + +#define coerceLiteral(x) Coercer::coerce(x) + +template <typename type, typename Coercer, typename MixedSignednessTester> +class CheckedArithmeticTester { +public: + static void run() + { + Checked<type, RecordOverflow> value; + EXPECT_EQ(coerceLiteral(0), value.unsafeGet()); + EXPECT_EQ(std::numeric_limits<type>::max(), (value + std::numeric_limits<type>::max()).unsafeGet()); + EXPECT_EQ(std::numeric_limits<type>::max(), (std::numeric_limits<type>::max() + value).unsafeGet()); + EXPECT_EQ(std::numeric_limits<type>::min(), (value + std::numeric_limits<type>::min()).unsafeGet()); + EXPECT_EQ(std::numeric_limits<type>::min(), (std::numeric_limits<type>::min() + value).unsafeGet()); + + EXPECT_EQ(coerceLiteral(0), (value * coerceLiteral(0)).unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) * value).unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (value * value).unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(0)).unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) - value).unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (value - value).unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (value++).unsafeGet()); + EXPECT_EQ(coerceLiteral(1), (value--).unsafeGet()); + EXPECT_EQ(coerceLiteral(1), (++value).unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (--value).unsafeGet()); + EXPECT_EQ(coerceLiteral(10), (value += coerceLiteral(10)).unsafeGet()); + EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); + EXPECT_EQ(coerceLiteral(100), (value *= coerceLiteral(10)).unsafeGet()); + EXPECT_EQ(coerceLiteral(100), value.unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (value -= coerceLiteral(100)).unsafeGet()); + EXPECT_EQ(coerceLiteral(0), value.unsafeGet()); + value = 10; + EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(10)).unsafeGet()); + EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); + + value = std::numeric_limits<type>::min(); + EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - coerceLiteral(1))).hasOverflowed()); + EXPECT_EQ(true, !((value--).hasOverflowed())); + EXPECT_EQ(true, value.hasOverflowed()); + value = std::numeric_limits<type>::max(); + EXPECT_EQ(true, !value.hasOverflowed()); + EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + coerceLiteral(1))).hasOverflowed()); + EXPECT_EQ(true, !(value++).hasOverflowed()); + EXPECT_EQ(true, value.hasOverflowed()); + value = std::numeric_limits<type>::max(); + EXPECT_EQ(true, (value += coerceLiteral(1)).hasOverflowed()); + EXPECT_EQ(true, value.hasOverflowed()); + + value = 10; + type _value = 0; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(0)).safeGet(_value)); + _value = 0; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(0) * value).safeGet(_value)); + _value = 0; + EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); + _value = 0; + EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); + value = 0; + _value = 0; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); + _value = 0; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); + value = 1; + _value = 0; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); + _value = 0; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); + _value = 0; + value = 0; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); + _value = 0; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)0).safeGet(_value)); + _value = 0; + value = 1; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); + _value = 0; + EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)1).safeGet(_value)); + _value = 0; + value = 2; + EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); + _value = 0; + EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)2).safeGet(_value)); + value = 10; + EXPECT_EQ(true, (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).hasOverflowed()); + + + Checked<type, OverflowCrashLogger> nvalue; // to hold a not overflowed value. + Checked<type, OverflowCrashLogger> ovalue; // to hold an overflowed value. + bool unused; + + _value = 75; + type _largeValue = 100; + type _smallValue = 50; + + value = _smallValue; + nvalue = _value; + ovalue = _value; + + // Make sure the OverflowCrashLogger is working as expected. + EXPECT_EQ(false, (ovalue.hasOverflowed())); + EXPECT_EQ(true, (resetOverflow(ovalue), ovalue.hasOverflowed())); + EXPECT_EQ(false, (resetOverflow(ovalue), ovalue.didCrash())); + EXPECT_EQ(true, (unused = (ovalue == ovalue), ovalue.didCrash())); + EXPECT_EQ(false, (resetOverflow(ovalue), ovalue.didCrash())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + EXPECT_EQ(false, nvalue.didCrash()); + + // Test operator== that should not overflow nor crash. + EXPECT_EQ(true, (nvalue == nvalue)); + EXPECT_EQ(true, (nvalue == Checked<type, OverflowCrashLogger>(_value))); + EXPECT_EQ(false, (nvalue == value)); + EXPECT_EQ(true, (nvalue == _value)); + EXPECT_EQ(false, (nvalue == Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max()))); + EXPECT_EQ(false, (nvalue == std::numeric_limits<type>::max())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + EXPECT_EQ(false, nvalue.didCrash()); + + // Test operator!= that should not overflow nor crash. + EXPECT_EQ(false, (nvalue != nvalue)); + EXPECT_EQ(false, (nvalue != Checked<type, OverflowCrashLogger>(_value))); + EXPECT_EQ(true, (nvalue != value)); + EXPECT_EQ(false, (nvalue != _value)); + EXPECT_EQ(true, (nvalue != Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max()))); + EXPECT_EQ(true, (nvalue != std::numeric_limits<type>::max())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + EXPECT_EQ(false, nvalue.didCrash()); + + // Test operator< that should not overflow nor crash. + EXPECT_EQ(false, (nvalue < nvalue)); + EXPECT_EQ(false, (nvalue < value)); + EXPECT_EQ(true, (nvalue < Checked<type, OverflowCrashLogger>(_largeValue))); + EXPECT_EQ(false, (nvalue < Checked<type, OverflowCrashLogger>(_value))); + EXPECT_EQ(false, (nvalue < Checked<type, OverflowCrashLogger>(_smallValue))); + EXPECT_EQ(true, (nvalue < _largeValue)); + EXPECT_EQ(false, (nvalue < _value)); + EXPECT_EQ(false, (nvalue < _smallValue)); + EXPECT_EQ(true, (nvalue < Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max()))); + EXPECT_EQ(true, (nvalue < std::numeric_limits<type>::max())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + EXPECT_EQ(false, nvalue.didCrash()); + + // Test operator<= that should not overflow nor crash. + EXPECT_EQ(true, (nvalue <= nvalue)); + EXPECT_EQ(false, (nvalue <= value)); + EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(_largeValue))); + EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(_value))); + EXPECT_EQ(false, (nvalue <= Checked<type, OverflowCrashLogger>(_smallValue))); + EXPECT_EQ(true, (nvalue <= _largeValue)); + EXPECT_EQ(true, (nvalue <= _value)); + EXPECT_EQ(false, (nvalue <= _smallValue)); + EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max()))); + EXPECT_EQ(true, (nvalue <= std::numeric_limits<type>::max())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + EXPECT_EQ(false, nvalue.didCrash()); + + // Test operator> that should not overflow nor crash. + EXPECT_EQ(false, (nvalue > nvalue)); + EXPECT_EQ(true, (nvalue > value)); + EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(_largeValue))); + EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(_value))); + EXPECT_EQ(true, (nvalue > Checked<type, OverflowCrashLogger>(_smallValue))); + EXPECT_EQ(false, (nvalue > _largeValue)); + EXPECT_EQ(false, (nvalue > _value)); + EXPECT_EQ(true, (nvalue > _smallValue)); + EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max()))); + EXPECT_EQ(false, (nvalue > std::numeric_limits<type>::max())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + EXPECT_EQ(false, nvalue.didCrash()); + + // Test operator>= that should not overflow nor crash. + EXPECT_EQ(true, (nvalue >= nvalue)); + EXPECT_EQ(true, (nvalue >= value)); + EXPECT_EQ(false, (nvalue >= Checked<type, OverflowCrashLogger>(_largeValue))); + EXPECT_EQ(true, (nvalue >= Checked<type, OverflowCrashLogger>(_value))); + EXPECT_EQ(true, (nvalue >= Checked<type, OverflowCrashLogger>(_smallValue))); + EXPECT_EQ(false, (nvalue >= _largeValue)); + EXPECT_EQ(true, (nvalue >= _value)); + EXPECT_EQ(true, (nvalue >= _smallValue)); + EXPECT_EQ(false, (nvalue >= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max()))); + EXPECT_EQ(false, (nvalue >= std::numeric_limits<type>::max())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + EXPECT_EQ(false, nvalue.didCrash()); + + // Test operator== with an overflowed value. + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == ovalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == _value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == _value * std::numeric_limits<type>::max()), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == std::numeric_limits<type>::max()), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == nvalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue == ovalue), ovalue.didCrash())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + + // Test operator!= with an overflowed value. + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != ovalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != _value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != _value * std::numeric_limits<type>::max()), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != std::numeric_limits<type>::max()), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != nvalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue != ovalue), ovalue.didCrash())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + + // Test operator< with an overflowed value. + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < ovalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _largeValue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _smallValue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < std::numeric_limits<type>::max()), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < nvalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue < ovalue), ovalue.didCrash())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + + // Test operator<= with an overflowed value. + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= ovalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _largeValue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _smallValue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= std::numeric_limits<type>::max()), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= nvalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue <= ovalue), ovalue.didCrash())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + + // Test operator> with an overflowed value. + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > ovalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _largeValue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _smallValue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > std::numeric_limits<type>::max()), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > nvalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue > ovalue), ovalue.didCrash())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + + // Test operator>= with an overflowed value. + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= ovalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _largeValue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _value), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _smallValue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= std::numeric_limits<type>::max()), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= nvalue), ovalue.didCrash())); + EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue >= ovalue), ovalue.didCrash())); + + EXPECT_EQ(false, nvalue.hasOverflowed()); + + MixedSignednessTester::run(); + } +}; + +template <typename type, typename Coercer> +class AllowMixedSignednessTest { +public: + static void run() + { + Checked<type, RecordOverflow> value; + value = 10; + + EXPECT_EQ(coerceLiteral(0), (value + -10).unsafeGet()); + EXPECT_EQ(0U, (value - 10U).unsafeGet()); + EXPECT_EQ(coerceLiteral(0), (-10 + value).unsafeGet()); + EXPECT_EQ(0U, (10U - value).unsafeGet()); + value = std::numeric_limits<type>::min(); + EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - 1)).hasOverflowed()); + EXPECT_EQ(true, !(value--).hasOverflowed()); + EXPECT_EQ(true, value.hasOverflowed()); + value = std::numeric_limits<type>::max(); + EXPECT_EQ(true, !value.hasOverflowed()); + EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1)).hasOverflowed()); + EXPECT_EQ(true, !(value++).hasOverflowed()); + EXPECT_EQ(true, value.hasOverflowed()); + value = std::numeric_limits<type>::max(); + EXPECT_EQ(true, (value += 1).hasOverflowed()); + EXPECT_EQ(true, value.hasOverflowed()); + value = std::numeric_limits<type>::min(); + EXPECT_EQ(true, (value - 1U).hasOverflowed()); + EXPECT_EQ(true, !(value--).hasOverflowed()); + EXPECT_EQ(true, value.hasOverflowed()); + value = std::numeric_limits<type>::max(); + EXPECT_EQ(true, !value.hasOverflowed()); + EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1U)).hasOverflowed()); + EXPECT_EQ(true, !(value++).hasOverflowed()); + EXPECT_EQ(true, value.hasOverflowed()); + value = std::numeric_limits<type>::max(); + EXPECT_EQ(true, (value += 1U).hasOverflowed()); + EXPECT_EQ(true, value.hasOverflowed()); + } +}; + +template <typename type, typename Coercer> +class IgnoreMixedSignednessTest { +public: + static void run() { } +}; + +template <typename type> class CoerceLiteralToUnsigned { +public: + static unsigned coerce(type x) { return static_cast<unsigned>(x); } +}; + +template <typename type> class CoerceLiteralNop { +public: + static type coerce(type x) { return x; } +}; -#define CoerceLiteralToUnsigned(x) x##U -#define CoerceLiteralNop(x) x -#define AllowMixedSignednessTest(x) x -#define IgnoreMixedSignednessTest(x) CheckedArithmeticTest(int8_t, CoerceLiteralNop, IgnoreMixedSignednessTest) CheckedArithmeticTest(int16_t, CoerceLiteralNop, IgnoreMixedSignednessTest) CheckedArithmeticTest(int32_t, CoerceLiteralNop, AllowMixedSignednessTest) @@ -146,4 +426,62 @@ CheckedArithmeticTest(uint32_t, CoerceLiteralToUnsigned, AllowMixedSignednessTes CheckedArithmeticTest(int64_t, CoerceLiteralNop, IgnoreMixedSignednessTest) CheckedArithmeticTest(uint64_t, CoerceLiteralToUnsigned, IgnoreMixedSignednessTest) +TEST(CheckedArithmeticTest, IsInBounds) +{ + // bigger precision, signed, signed + EXPECT_TRUE(WTF::isInBounds<int32_t>(std::numeric_limits<int16_t>::max())); + EXPECT_TRUE(WTF::isInBounds<int32_t>(std::numeric_limits<int16_t>::min())); + + // bigger precision, unsigned, signed + EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<int32_t>::max())); + EXPECT_FALSE(WTF::isInBounds<uint32_t>(std::numeric_limits<int16_t>::min())); + + EXPECT_FALSE(WTF::isInBounds<uint32_t>((int32_t)-1)); + EXPECT_FALSE(WTF::isInBounds<uint16_t>((int32_t)-1)); + EXPECT_FALSE(WTF::isInBounds<unsigned long>((int)-1)); + + EXPECT_TRUE(WTF::isInBounds<uint32_t>((int32_t)1)); + EXPECT_TRUE(WTF::isInBounds<uint32_t>((int16_t)1)); + EXPECT_TRUE(WTF::isInBounds<unsigned>((int)1)); + + EXPECT_TRUE(WTF::isInBounds<uint32_t>((int32_t)0)); + EXPECT_TRUE(WTF::isInBounds<uint16_t>((int32_t)0)); + EXPECT_TRUE(WTF::isInBounds<uint32_t>((int16_t)0)); + EXPECT_TRUE(WTF::isInBounds<unsigned>((int)0)); + + EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<int32_t>::max())); + EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<int16_t>::max())); + EXPECT_TRUE(WTF::isInBounds<unsigned>(std::numeric_limits<int>::max())); + + // bigger precision, signed, unsigned + EXPECT_TRUE(WTF::isInBounds<int32_t>(std::numeric_limits<uint16_t>::max())); + EXPECT_FALSE(WTF::isInBounds<int32_t>(std::numeric_limits<uint32_t>::max())); + EXPECT_TRUE(WTF::isInBounds<int32_t>((uint32_t)0)); + + // bigger precision, unsigned, unsigned + EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<uint16_t>::max())); + EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<uint16_t>::min())); + + // lower precision, signed signed + EXPECT_FALSE(WTF::isInBounds<int16_t>(std::numeric_limits<int32_t>::max())); + EXPECT_FALSE(WTF::isInBounds<int16_t>(std::numeric_limits<int32_t>::min())); + EXPECT_TRUE(WTF::isInBounds<int16_t>((int32_t)-1)); + EXPECT_TRUE(WTF::isInBounds<int16_t>((int32_t)0)); + EXPECT_TRUE(WTF::isInBounds<int16_t>((int32_t)1)); + // lower precision, unsigned, signed + EXPECT_FALSE(WTF::isInBounds<uint16_t>(std::numeric_limits<int32_t>::max())); + EXPECT_FALSE(WTF::isInBounds<uint16_t>(std::numeric_limits<int32_t>::min())); + EXPECT_FALSE(WTF::isInBounds<uint16_t>((int32_t)-1)); + EXPECT_TRUE(WTF::isInBounds<uint16_t>((int32_t)0)); + EXPECT_TRUE(WTF::isInBounds<uint16_t>((int32_t)1)); + // lower precision, signed, unsigned + EXPECT_FALSE(WTF::isInBounds<int16_t>(std::numeric_limits<uint32_t>::max())); + EXPECT_TRUE(WTF::isInBounds<int16_t>((uint32_t)0)); + EXPECT_TRUE(WTF::isInBounds<int16_t>((uint32_t)1)); + // lower precision, unsigned, unsigned + EXPECT_FALSE(WTF::isInBounds<uint16_t>(std::numeric_limits<uint32_t>::max())); + EXPECT_TRUE(WTF::isInBounds<uint16_t>((uint32_t)0)); + EXPECT_TRUE(WTF::isInBounds<uint16_t>((uint32_t)1)); +} + } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/Condition.cpp b/Tools/TestWebKitAPI/Tests/WTF/Condition.cpp new file mode 100644 index 000000000..c450d8953 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/Condition.cpp @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2015 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 <mutex> +#include <thread> +#include <wtf/Condition.h> +#include <wtf/DataLog.h> +#include <wtf/Deque.h> +#include <wtf/Lock.h> +#include <wtf/StringPrintStream.h> +#include <wtf/Threading.h> +#include <wtf/Vector.h> + +using namespace WTF; + +namespace TestWebKitAPI { + +namespace { + +const bool verbose = false; + +enum NotifyStyle { + AlwaysNotifyOne, + TacticallyNotifyAll +}; + +template<typename Functor> +void wait(Condition& condition, std::unique_lock<Lock>& locker, const Functor& predicate, std::chrono::microseconds timeout) +{ + if (timeout == std::chrono::microseconds::max()) + condition.wait(locker, predicate); + else { + // This tests timeouts in the sense that it verifies that we can call wait() again after a + // timeout happened. That's a non-trivial piece of functionality since upon timeout the + // ParkingLot has to remove us from the queue. + while (!predicate()) + condition.waitFor(locker, timeout, predicate); + } +} + +void notify(NotifyStyle notifyStyle, Condition& condition, bool shouldNotify) +{ + switch (notifyStyle) { + case AlwaysNotifyOne: + condition.notifyOne(); + break; + case TacticallyNotifyAll: + if (shouldNotify) + condition.notifyAll(); + break; + } +} + +void runTest( + unsigned numProducers, + unsigned numConsumers, + unsigned maxQueueSize, + unsigned numMessagesPerProducer, + NotifyStyle notifyStyle, + std::chrono::microseconds timeout = std::chrono::microseconds::max(), + std::chrono::microseconds delay = std::chrono::microseconds::zero()) +{ + Deque<unsigned> queue; + bool shouldContinue = true; + Lock lock; + Condition emptyCondition; + Condition fullCondition; + + Vector<ThreadIdentifier> consumerThreads; + Vector<ThreadIdentifier> producerThreads; + + Vector<unsigned> received; + Lock receivedLock; + + for (unsigned i = numConsumers; i--;) { + ThreadIdentifier threadIdentifier = createThread( + "Consumer thread", + [&] () { + for (;;) { + unsigned result; + unsigned shouldNotify = false; + { + std::unique_lock<Lock> locker(lock); + wait( + emptyCondition, locker, + [&] () { + if (verbose) + dataLog(toString(currentThread(), ": Checking consumption predicate with shouldContinue = ", shouldContinue, ", queue.size() == ", queue.size(), "\n")); + return !shouldContinue || !queue.isEmpty(); + }, + timeout); + if (!shouldContinue && queue.isEmpty()) + return; + shouldNotify = queue.size() == maxQueueSize; + result = queue.takeFirst(); + } + notify(notifyStyle, fullCondition, shouldNotify); + + { + std::lock_guard<Lock> locker(receivedLock); + received.append(result); + } + } + }); + consumerThreads.append(threadIdentifier); + } + + std::this_thread::sleep_for(delay); + + for (unsigned i = numProducers; i--;) { + ThreadIdentifier threadIdentifier = createThread( + "Producer Thread", + [&] () { + for (unsigned i = 0; i < numMessagesPerProducer; ++i) { + bool shouldNotify = false; + { + std::unique_lock<Lock> locker(lock); + wait( + fullCondition, locker, + [&] () { + if (verbose) + dataLog(toString(currentThread(), ": Checking production predicate with shouldContinue = ", shouldContinue, ", queue.size() == ", queue.size(), "\n")); + return queue.size() < maxQueueSize; + }, + timeout); + shouldNotify = queue.isEmpty(); + queue.append(i); + } + notify(notifyStyle, emptyCondition, shouldNotify); + } + }); + producerThreads.append(threadIdentifier); + } + + for (ThreadIdentifier threadIdentifier : producerThreads) + waitForThreadCompletion(threadIdentifier); + + { + std::lock_guard<Lock> locker(lock); + shouldContinue = false; + } + emptyCondition.notifyAll(); + + for (ThreadIdentifier threadIdentifier : consumerThreads) + waitForThreadCompletion(threadIdentifier); + + EXPECT_EQ(numProducers * numMessagesPerProducer, received.size()); + std::sort(received.begin(), received.end()); + for (unsigned messageIndex = 0; messageIndex < numMessagesPerProducer; ++messageIndex) { + for (unsigned producerIndex = 0; producerIndex < numProducers; ++producerIndex) + EXPECT_EQ(messageIndex, received[messageIndex * numProducers + producerIndex]); + } +} + +} // anonymous namespace + +TEST(WTF_Condition, OneProducerOneConsumerOneSlot) +{ + runTest(1, 1, 1, 100000, TacticallyNotifyAll); +} + +TEST(WTF_Condition, OneProducerOneConsumerOneSlotTimeout) +{ + runTest( + 1, 1, 1, 100000, TacticallyNotifyAll, + std::chrono::microseconds(10000), + std::chrono::microseconds(1000000)); +} + +TEST(WTF_Condition, OneProducerOneConsumerHundredSlots) +{ + runTest(1, 1, 100, 1000000, TacticallyNotifyAll); +} + +TEST(WTF_Condition, TenProducersOneConsumerOneSlot) +{ + runTest(10, 1, 1, 10000, TacticallyNotifyAll); +} + +TEST(WTF_Condition, TenProducersOneConsumerHundredSlotsNotifyAll) +{ + runTest(10, 1, 100, 10000, TacticallyNotifyAll); +} + +TEST(WTF_Condition, TenProducersOneConsumerHundredSlotsNotifyOne) +{ + runTest(10, 1, 100, 10000, AlwaysNotifyOne); +} + +TEST(WTF_Condition, OneProducerTenConsumersOneSlot) +{ + runTest(1, 10, 1, 10000, TacticallyNotifyAll); +} + +TEST(WTF_Condition, OneProducerTenConsumersHundredSlotsNotifyAll) +{ + runTest(1, 10, 100, 100000, TacticallyNotifyAll); +} + +TEST(WTF_Condition, OneProducerTenConsumersHundredSlotsNotifyOne) +{ + runTest(1, 10, 100, 100000, AlwaysNotifyOne); +} + +TEST(WTF_Condition, TenProducersTenConsumersOneSlot) +{ + runTest(10, 10, 1, 50000, TacticallyNotifyAll); +} + +TEST(WTF_Condition, TenProducersTenConsumersHundredSlotsNotifyAll) +{ + runTest(10, 10, 100, 50000, TacticallyNotifyAll); +} + +TEST(WTF_Condition, TenProducersTenConsumersHundredSlotsNotifyOne) +{ + runTest(10, 10, 100, 50000, AlwaysNotifyOne); +} + +TEST(WTF_Condition, TimeoutTimesOut) +{ + Lock lock; + Condition condition; + + lock.lock(); + bool result = condition.waitFor( + lock, std::chrono::microseconds(10000), [] () -> bool { return false; }); + lock.unlock(); + + EXPECT_FALSE(result); +} + +} // namespace TestWebKitAPI + diff --git a/Tools/TestWebKitAPI/Tests/WTF/DateMath.cpp b/Tools/TestWebKitAPI/Tests/WTF/DateMath.cpp new file mode 100644 index 000000000..463041d48 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/DateMath.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2015 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 "Test.h" +#include <wtf/DateMath.h> + +namespace TestWebKitAPI { + +// Note: The results of these function look weird if you do not understand the following mappings: +// dayOfWeek: [0, 6] 0 being Monday, day: [1, 31], month: [0, 11], year: ex: 2011, +// hours: [0, 23], minutes: [0, 59], seconds: [0, 59], utcOffset: [-720,720]. + +TEST(WTF_DateMath, dateToDaysFrom1970) +{ + EXPECT_EQ(0.0, dateToDaysFrom1970(1970, 0, 1)); + EXPECT_EQ(157.0, dateToDaysFrom1970(1970, 5, 7)); + EXPECT_EQ(-145.0, dateToDaysFrom1970(1969, 7, 9)); + EXPECT_EQ(16322, dateToDaysFrom1970(2014, 8, 9)); +} + + +TEST(WTF_DateMath, isLeapYear) +{ + EXPECT_TRUE(isLeapYear(1804)); + EXPECT_FALSE(isLeapYear(1900)); + EXPECT_TRUE(isLeapYear(1968)); + EXPECT_TRUE(isLeapYear(1976)); + EXPECT_TRUE(isLeapYear(2000)); + EXPECT_FALSE(isLeapYear(2010)); + EXPECT_TRUE(isLeapYear(2012)); + EXPECT_FALSE(isLeapYear(2100)); +} + +TEST(WTF_DateMath, msToYear) +{ + EXPECT_EQ(1962, msToYear(-220953600000)); + EXPECT_EQ(1970, msToYear(0)); + EXPECT_EQ(1970, msToYear(100)); + EXPECT_EQ(1977, msToYear(220953600000)); + EXPECT_EQ(2013, msToYear(1365318000000)); +} + +TEST(WTF_DateMath, msToDays) +{ + EXPECT_EQ(0, msToDays(0)); + EXPECT_EQ(2557, msToDays(220953600000)); + EXPECT_EQ(255, msToDays(22095360000)); + EXPECT_EQ(25, msToDays(2209536000)); + EXPECT_EQ(2, msToDays(220953600)); + EXPECT_EQ(0, msToDays(22095360)); + EXPECT_EQ(0, msToDays(2209536)); +} + +TEST(WTF_DateMath, msToMinutes) +{ + EXPECT_EQ(0, msToMinutes(0)); + EXPECT_EQ(0, msToMinutes(220953600000)); + EXPECT_EQ(36, msToMinutes(22095360000)); + EXPECT_EQ(36, msToMinutes(22095360000)); + EXPECT_EQ(45, msToMinutes(2209536000)); + EXPECT_EQ(22, msToMinutes(220953600)); + EXPECT_EQ(8, msToMinutes(22095360)); + EXPECT_EQ(36, msToMinutes(2209536)); +} + +TEST(WTF_DateMath, msToHours) +{ + EXPECT_EQ(0, msToHours(0)); + EXPECT_EQ(8, msToHours(220953600000)); + EXPECT_EQ(17, msToHours(22095360000)); + EXPECT_EQ(13, msToHours(2209536000)); + EXPECT_EQ(13, msToHours(220953600)); + EXPECT_EQ(6, msToHours(22095360)); + EXPECT_EQ(0, msToHours(2209536)); +} + +TEST(WTF_DateMath, dayInYear) +{ + EXPECT_EQ(59, dayInYear(2015, 2, 1)); + EXPECT_EQ(60, dayInYear(2012, 2, 1)); + EXPECT_EQ(0, dayInYear(2015, 0, 1)); + EXPECT_EQ(31, dayInYear(2015, 1, 1)); +} + +TEST(WTF_DateMath, monthFromDayInYear) +{ + EXPECT_EQ(2, monthFromDayInYear(59, false)); + EXPECT_EQ(1, monthFromDayInYear(59, true)); + EXPECT_EQ(2, monthFromDayInYear(60, true)); + EXPECT_EQ(0, monthFromDayInYear(0, false)); + EXPECT_EQ(0, monthFromDayInYear(0, true)); + EXPECT_EQ(1, monthFromDayInYear(31, true)); + EXPECT_EQ(1, monthFromDayInYear(31, false)); +} + +TEST(WTF_DateMath, dayInMonthFromDayInYear) +{ + EXPECT_EQ(1, dayInMonthFromDayInYear(0, false)); + EXPECT_EQ(1, dayInMonthFromDayInYear(0, true)); + EXPECT_EQ(1, dayInMonthFromDayInYear(59, false)); + EXPECT_EQ(29, dayInMonthFromDayInYear(59, true)); + EXPECT_EQ(1, dayInMonthFromDayInYear(60, true)); + EXPECT_EQ(1, dayInMonthFromDayInYear(0, false)); + EXPECT_EQ(1, dayInMonthFromDayInYear(0, true)); + EXPECT_EQ(31, dayInMonthFromDayInYear(30, true)); + EXPECT_EQ(31, dayInMonthFromDayInYear(30, false)); + EXPECT_EQ(31, dayInMonthFromDayInYear(365, true)); + EXPECT_EQ(32, dayInMonthFromDayInYear(365, false)); + EXPECT_EQ(32, dayInMonthFromDayInYear(366, true)); +} + +TEST(WTF_DateMath, calculateLocalTimeOffset) +{ + // DST Start: April 30, 1967 (02:00 am) + LocalTimeOffset dstStart1967 = calculateLocalTimeOffset(-84301200000, WTF::LocalTime); + EXPECT_TRUE(dstStart1967.isDST); + EXPECT_EQ(-25200000, dstStart1967.offset); + + // November 1, 1967 (02:00 am) + LocalTimeOffset dstAlmostEnd1967 = calculateLocalTimeOffset(-68317200000, WTF::LocalTime); + EXPECT_TRUE(dstAlmostEnd1967.isDST); + EXPECT_EQ(-25200000, dstAlmostEnd1967.offset); + + // DST End: November 11, 1967 (02:00 am) + LocalTimeOffset dstEnd1967 = calculateLocalTimeOffset(-67536000000, WTF::LocalTime); + EXPECT_FALSE(dstEnd1967.isDST); + EXPECT_EQ(-25200000, dstStart1967.offset); + + // DST Start: April 3, 1988 (02:00 am) + LocalTimeOffset dstStart1988 = calculateLocalTimeOffset(576054000000, WTF::LocalTime); + EXPECT_TRUE(dstStart1988.isDST); + EXPECT_EQ(-25200000, dstStart1988.offset); + + // DST End: November 4, 2012 (02:00 am) + LocalTimeOffset dstEnd2012 = calculateLocalTimeOffset(1352012400000, WTF::LocalTime); + EXPECT_FALSE(dstEnd2012.isDST); + EXPECT_EQ(-28800000, dstEnd2012.offset); + + // DST Begin: March 8, 2015 + LocalTimeOffset dstBegin2015 = calculateLocalTimeOffset(1425801600000, WTF::LocalTime); + EXPECT_TRUE(dstBegin2015.isDST); + EXPECT_EQ(-25200000, dstBegin2015.offset); + + LocalTimeOffset dstBegin2015UTC = calculateLocalTimeOffset(1425801600000, WTF::UTCTime); + EXPECT_FALSE(dstBegin2015UTC.isDST); + EXPECT_EQ(-28800000, dstBegin2015UTC.offset); + + // DST End: November 1, 2015 + LocalTimeOffset dstEnd2015 = calculateLocalTimeOffset(1446361200000, WTF::LocalTime); + EXPECT_FALSE(dstEnd2015.isDST); + EXPECT_EQ(-28800000, dstEnd2015.offset); + + // DST Begin: March 13, 2016 + LocalTimeOffset dstBegin2016 = calculateLocalTimeOffset(1458111600000, WTF::LocalTime); + EXPECT_TRUE(dstBegin2016.isDST); + EXPECT_EQ(-25200000, dstBegin2016.offset); + + // DST End: November 6, 2016 + LocalTimeOffset dstEnd2016 = calculateLocalTimeOffset(1478415600000, WTF::LocalTime); + EXPECT_FALSE(dstEnd2016.isDST); + EXPECT_EQ(-28800000, dstEnd2016.offset); + + // DST Begin: March 12, 2017 + LocalTimeOffset dstBegin2017 = calculateLocalTimeOffset(1489305600000, WTF::LocalTime); + EXPECT_TRUE(dstBegin2017.isDST); + EXPECT_EQ(-25200000, dstBegin2017.offset); + + // DST End: November 5, 2017 + LocalTimeOffset dstEnd2017 = calculateLocalTimeOffset(1509865200000, WTF::LocalTime); + EXPECT_FALSE(dstEnd2017.isDST); + EXPECT_EQ(-28800000, dstEnd2017.offset); + + // DST Begin: March 11, 2018 + LocalTimeOffset dstBegin2018 = calculateLocalTimeOffset(1520755200000, WTF::LocalTime); + EXPECT_TRUE(dstBegin2018.isDST); + EXPECT_EQ(-25200000, dstBegin2018.offset); + + // DST End: November 4, 2018 + LocalTimeOffset dstEnd2018 = calculateLocalTimeOffset(1541314800000, WTF::LocalTime); + EXPECT_FALSE(dstEnd2018.isDST); + EXPECT_EQ(-28800000, dstEnd2018.offset); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/Deque.cpp b/Tools/TestWebKitAPI/Tests/WTF/Deque.cpp index 26a815aba..83f1f82ee 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/Deque.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/Deque.cpp @@ -24,11 +24,13 @@ */ #include "config.h" + +#include "MoveOnly.h" #include <wtf/Deque.h> namespace TestWebKitAPI { -TEST(WTF, DequeIterator) +TEST(WTF_Deque, Iterator) { Deque<int> deque; deque.append(11); @@ -52,6 +54,28 @@ TEST(WTF, DequeIterator) EXPECT_TRUE(end == it); } +TEST(WTF_Deque, InitializerList) +{ + Deque<int> deque = { 1, 2, 3, 4 }; + + EXPECT_EQ(4u, deque.size()); + + auto it = deque.begin(); + auto end = deque.end(); + EXPECT_TRUE(end != it); + + EXPECT_EQ(1, *it); + ++it; + EXPECT_EQ(2, *it); + ++it; + EXPECT_EQ(3, *it); + ++it; + EXPECT_EQ(4, *it); + ++it; + + EXPECT_TRUE(end == it); +} + TEST(WTF, DequeReverseIterator) { Deque<int> deque; @@ -76,7 +100,7 @@ TEST(WTF, DequeReverseIterator) EXPECT_TRUE(end == it); } -TEST(WTF, DequeRemove) +TEST(WTF_Deque, Remove) { Deque<int> deque; deque.append(11); @@ -103,4 +127,65 @@ TEST(WTF, DequeRemove) EXPECT_TRUE(deque.isEmpty()); } +TEST(WTF_Deque, MoveOnly) +{ + Deque<MoveOnly> deque; + + deque.append(MoveOnly(1)); + deque.prepend(MoveOnly(0)); + + EXPECT_EQ(0U, deque.first().value()); + EXPECT_EQ(1U, deque.last().value()); + + auto first = deque.takeFirst(); + EXPECT_EQ(0U, first.value()); + + auto last = deque.takeLast(); + EXPECT_EQ(1U, last.value()); +} + +TEST(WTF_Deque, MoveConstructor) +{ + Deque<MoveOnly, 4> deque; + + for (unsigned i = 0; i < 10; ++i) + deque.append(MoveOnly(i)); + + EXPECT_EQ(10u, deque.size()); + + Deque<MoveOnly, 4> deque2 = WTFMove(deque); + + EXPECT_EQ(10u, deque2.size()); + + unsigned i = 0; + for (auto& element : deque2) { + EXPECT_EQ(i, element.value()); + ++i; + } +} + +TEST(WTF_Deque, MoveAssignmentOperator) +{ + Deque<MoveOnly, 4> deque1; + + for (unsigned i = 0; i < 10; ++i) + deque1.append(MoveOnly(i)); + + EXPECT_EQ(10u, deque1.size()); + + Deque<MoveOnly, 4> deque2; + for (unsigned i = 0; i < 10; ++i) + deque2.append(MoveOnly(i * 2)); + + deque1 = WTFMove(deque2); + + EXPECT_EQ(10u, deque2.size()); + + unsigned i = 0; + for (auto& element : deque1) { + EXPECT_EQ(i * 2, element.value()); + ++i; + } +} + } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/HashCountedSet.cpp b/Tools/TestWebKitAPI/Tests/WTF/HashCountedSet.cpp new file mode 100644 index 000000000..4c1afd105 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/HashCountedSet.cpp @@ -0,0 +1,468 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * Copyright (C) 2011 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: + * 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 "Counters.h" +#include "MoveOnly.h" +#include "RefLogger.h" +#include <string> +#include <wtf/HashCountedSet.h> +#include <wtf/text/StringHash.h> + +namespace TestWebKitAPI { + +typedef WTF::HashCountedSet<int> IntHashCountedSet; + +TEST(WTF_HashCountedSet, HashTableIteratorComparison) +{ + IntHashCountedSet hashCountedSet; + hashCountedSet.add(1); + ASSERT_TRUE(hashCountedSet.begin() != hashCountedSet.end()); + ASSERT_FALSE(hashCountedSet.begin() == hashCountedSet.end()); + + IntHashCountedSet::const_iterator begin = hashCountedSet.begin(); + ASSERT_TRUE(begin == hashCountedSet.begin()); + ASSERT_TRUE(hashCountedSet.begin() == begin); + ASSERT_TRUE(begin != hashCountedSet.end()); + ASSERT_TRUE(hashCountedSet.end() != begin); + ASSERT_FALSE(begin != hashCountedSet.begin()); + ASSERT_FALSE(hashCountedSet.begin() != begin); + ASSERT_FALSE(begin == hashCountedSet.end()); + ASSERT_FALSE(hashCountedSet.end() == begin); +} + +struct TestDoubleHashTraits : HashTraits<double> { + static const int minimumTableSize = 8; +}; + +typedef HashCountedSet<double, DefaultHash<double>::Hash, TestDoubleHashTraits> DoubleHashCountedSet; + +static int bucketForKey(double key) +{ + return DefaultHash<double>::Hash::hash(key) & (TestDoubleHashTraits::minimumTableSize - 1); +} + +TEST(WTF_HashCountedSet, 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; + + DoubleHashCountedSet hashCountedSet; + + hashCountedSet.add(clobberKey); + + ASSERT_EQ(hashCountedSet.count(clobberKey), 1u); + ASSERT_EQ(hashCountedSet.count(zeroKey), 0u); + ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 0u); + + hashCountedSet.add(zeroKey); + hashCountedSet.add(negativeZeroKey); + + ASSERT_EQ(bucketForKey(clobberKey), bucketForKey(negativeZeroKey)); + ASSERT_EQ(hashCountedSet.count(clobberKey), 1u); + ASSERT_EQ(hashCountedSet.count(zeroKey), 1u); + ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 1u); + + hashCountedSet.add(clobberKey); + hashCountedSet.add(zeroKey); + hashCountedSet.add(negativeZeroKey); + + ASSERT_EQ(hashCountedSet.count(clobberKey), 2u); + ASSERT_EQ(hashCountedSet.count(zeroKey), 2u); + ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 2u); + + hashCountedSet.add(clobberKey, 12); + hashCountedSet.add(zeroKey, 15); + hashCountedSet.add(negativeZeroKey, 17); + + ASSERT_EQ(hashCountedSet.count(clobberKey), 14u); + ASSERT_EQ(hashCountedSet.count(zeroKey), 17u); + ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 19u); +} + +TEST(WTF_HashCountedSet, DoubleHashCollisionsInitialCount) +{ + // 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; + + DoubleHashCountedSet hashCountedSet; + + hashCountedSet.add(clobberKey, 5); + + ASSERT_EQ(hashCountedSet.count(clobberKey), 5u); + ASSERT_EQ(hashCountedSet.count(zeroKey), 0u); + ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 0u); + + hashCountedSet.add(zeroKey, 22); + hashCountedSet.add(negativeZeroKey, 0); + + ASSERT_EQ(bucketForKey(clobberKey), bucketForKey(negativeZeroKey)); + ASSERT_EQ(hashCountedSet.count(clobberKey), 5u); + ASSERT_EQ(hashCountedSet.count(zeroKey), 22u); + ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 0u); + + hashCountedSet.add(clobberKey); + hashCountedSet.add(zeroKey); + hashCountedSet.add(negativeZeroKey); + + ASSERT_EQ(hashCountedSet.count(clobberKey), 6u); + ASSERT_EQ(hashCountedSet.count(zeroKey), 23u); + ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 1u); +} + + +TEST(WTF_HashCountedSet, MoveOnlyKeys) +{ + HashCountedSet<MoveOnly> moveOnlyKeys; + + for (size_t i = 0; i < 100; ++i) { + MoveOnly moveOnly(i + 1); + moveOnlyKeys.add(WTFMove(moveOnly)); + } + + for (size_t i = 0; i < 100; ++i) { + auto it = moveOnlyKeys.find(MoveOnly(i + 1)); + ASSERT_FALSE(it == moveOnlyKeys.end()); + ASSERT_EQ(it->value, 1u); + } + + for (size_t i = 0; i < 100; ++i) + ASSERT_FALSE(moveOnlyKeys.add(MoveOnly(i + 1)).isNewEntry); + + for (size_t i = 0; i < 100; ++i) + ASSERT_FALSE(moveOnlyKeys.remove(MoveOnly(i + 1))); + + for (size_t i = 0; i < 100; ++i) + ASSERT_TRUE(moveOnlyKeys.remove(MoveOnly(i + 1))); + + ASSERT_TRUE(moveOnlyKeys.isEmpty()); +} + +TEST(WTF_HashCountedSet, MoveOnlyKeysInitialCount) +{ + HashCountedSet<MoveOnly> moveOnlyKeys; + + for (size_t i = 0; i < 100; ++i) { + MoveOnly moveOnly(i + 1); + moveOnlyKeys.add(WTFMove(moveOnly), i + 1); + } + + for (size_t i = 0; i < 100; ++i) { + auto it = moveOnlyKeys.find(MoveOnly(i + 1)); + ASSERT_FALSE(it == moveOnlyKeys.end()); + ASSERT_EQ(it->value, i + 1); + } + + for (size_t i = 0; i < 100; ++i) + ASSERT_FALSE(moveOnlyKeys.add(MoveOnly(i + 1)).isNewEntry); + + for (size_t i = 0; i < 100; ++i) + ASSERT_EQ(moveOnlyKeys.count(MoveOnly(i + 1)), i + 2); + + for (size_t i = 0; i < 100; ++i) + ASSERT_FALSE(moveOnlyKeys.remove(MoveOnly(i + 1))); + + for (size_t i = 0; i < 100; ++i) + ASSERT_EQ(moveOnlyKeys.count(MoveOnly(i + 1)), i + 1); +} + +TEST(WTF_HashCountedSet, InitializerList) +{ + HashCountedSet<String> hashCountedSet = { + "one", + "two", + "three", + "four", + "four", + "four", + "four", + }; + + EXPECT_EQ(4u, hashCountedSet.size()); + + EXPECT_EQ(hashCountedSet.count("one"), 1u); + EXPECT_EQ(hashCountedSet.count("two"), 1u); + EXPECT_EQ(hashCountedSet.count("three"), 1u); + EXPECT_EQ(hashCountedSet.count("four"), 4u); +} + +TEST(WTF_HashCountedSet, InitializerListInitialCount) +{ + HashCountedSet<String> hashCountedSet = { + { String("one"), 1u }, + { String("two"), 2u }, + { String("three"), 3u }, + { String("four"), 4u }, + }; + + EXPECT_EQ(4u, hashCountedSet.size()); + + EXPECT_EQ(hashCountedSet.count("one"), 1u); + EXPECT_EQ(hashCountedSet.count("two"), 2u); + EXPECT_EQ(hashCountedSet.count("three"), 3u); + EXPECT_EQ(hashCountedSet.count("four"), 4u); +} + +TEST(WTF_HashCountedSet, UniquePtrKey) +{ + ConstructorDestructorCounter::TestingScope scope; + + HashCountedSet<std::unique_ptr<ConstructorDestructorCounter>> hashCountedSet; + + auto uniquePtr = std::make_unique<ConstructorDestructorCounter>(); + hashCountedSet.add(WTFMove(uniquePtr)); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + hashCountedSet.clear(); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); +} + +TEST(WTF_HashCountedSet, UniquePtrKeyInitialCount) +{ + ConstructorDestructorCounter::TestingScope scope; + + HashCountedSet<std::unique_ptr<ConstructorDestructorCounter>> hashCountedSet; + + auto uniquePtr = std::make_unique<ConstructorDestructorCounter>(); + hashCountedSet.add(WTFMove(uniquePtr), 12); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + hashCountedSet.clear(); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); +} + +TEST(WTF_HashCountedSet, UniquePtrKey_CustomDeleter) +{ + ConstructorDestructorCounter::TestingScope constructorDestructorCounterScope; + DeleterCounter<ConstructorDestructorCounter>::TestingScope deleterCounterScope; + + HashCountedSet<std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>>> hashCountedSet; + + std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>> uniquePtr(new ConstructorDestructorCounter(), DeleterCounter<ConstructorDestructorCounter>()); + hashCountedSet.add(WTFMove(uniquePtr)); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + EXPECT_EQ(0u, DeleterCounter<ConstructorDestructorCounter>::deleterCount); + + hashCountedSet.clear(); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); + + EXPECT_EQ(1u, DeleterCounter<ConstructorDestructorCounter>::deleterCount); +} + +TEST(WTF_HashCountedSet, UniquePtrKey_FindUsingRawPointer) +{ + HashCountedSet<std::unique_ptr<int>> hashCountedSet; + + auto uniquePtr = std::make_unique<int>(5); + int* ptr = uniquePtr.get(); + hashCountedSet.add(WTFMove(uniquePtr)); + + auto it = hashCountedSet.find(ptr); + ASSERT_TRUE(it != hashCountedSet.end()); + EXPECT_EQ(ptr, it->key.get()); + EXPECT_EQ(1u, it->value); +} + +TEST(WTF_HashCountedSet, UniquePtrKey_ContainsUsingRawPointer) +{ + HashCountedSet<std::unique_ptr<int>> hashCountedSet; + + auto uniquePtr = std::make_unique<int>(5); + int* ptr = uniquePtr.get(); + hashCountedSet.add(WTFMove(uniquePtr)); + + EXPECT_EQ(true, hashCountedSet.contains(ptr)); +} + +TEST(WTF_HashCountedSet, UniquePtrKey_GetUsingRawPointer) +{ + HashCountedSet<std::unique_ptr<int>> hashCountedSet; + + auto uniquePtr = std::make_unique<int>(5); + int* ptr = uniquePtr.get(); + hashCountedSet.add(WTFMove(uniquePtr)); + + int value = hashCountedSet.count(ptr); + EXPECT_EQ(1, value); +} + +TEST(WTF_HashCountedSet, UniquePtrKey_RemoveUsingRawPointer) +{ + ConstructorDestructorCounter::TestingScope scope; + + HashCountedSet<std::unique_ptr<ConstructorDestructorCounter>> hashCountedSet; + + auto uniquePtr = std::make_unique<ConstructorDestructorCounter>(); + ConstructorDestructorCounter* ptr = uniquePtr.get(); + hashCountedSet.add(WTFMove(uniquePtr)); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + bool result = hashCountedSet.remove(ptr); + EXPECT_EQ(true, result); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); +} + +TEST(WTF_HashCountedSet, RefPtrKey_Add) +{ + HashCountedSet<RefPtr<RefLogger>> hashCountedSet; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + hashCountedSet.add(ptr); + + ASSERT_STREQ("ref(a) ref(a) ", takeLogStr().c_str()); + EXPECT_EQ(1U, hashCountedSet.count(ptr)); + EXPECT_EQ(1U, hashCountedSet.count(ptr.get())); +} + +TEST(WTF_HashCountedSet, RefPtrKey_AddUsingRelease) +{ + HashCountedSet<RefPtr<RefLogger>> hashCountedSet; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + hashCountedSet.add(ptr.release()); + + EXPECT_STREQ("ref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashCountedSet, RefPtrKey_AddUsingMove) +{ + HashCountedSet<RefPtr<RefLogger>> hashCountedSet; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + hashCountedSet.add(WTFMove(ptr)); + + EXPECT_STREQ("ref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashCountedSet, RefPtrKey_AddUsingRaw) +{ + HashCountedSet<RefPtr<RefLogger>> hashCountedSet; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + hashCountedSet.add(ptr.get()); + + EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str()); + EXPECT_EQ(1U, hashCountedSet.count(ptr)); + EXPECT_EQ(1U, hashCountedSet.count(ptr.get())); +} + +TEST(WTF_HashCountedSet, RefPtrKey_AddKeyAlreadyPresent) +{ + HashCountedSet<RefPtr<RefLogger>> hashCountedSet; + + DerivedRefLogger a("a"); + + { + RefPtr<RefLogger> ptr(&a); + hashCountedSet.add(ptr); + } + + EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr2(&a); + auto addResult = hashCountedSet.add(ptr2); + EXPECT_FALSE(addResult.isNewEntry); + } + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashCountedSet, RefPtrKey_AddUsingReleaseKeyAlreadyPresent) +{ + HashCountedSet<RefPtr<RefLogger>> hashCountedSet; + + DerivedRefLogger a("a"); + + { + RefPtr<RefLogger> ptr(&a); + hashCountedSet.add(ptr); + } + + EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr2(&a); + auto addResult = hashCountedSet.add(ptr2.release()); + EXPECT_FALSE(addResult.isNewEntry); + } + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashCountedSet, RefPtrKey_AddUsingMoveKeyAlreadyPresent) +{ + HashCountedSet<RefPtr<RefLogger>> hashCountedSet; + + DerivedRefLogger a("a"); + + { + RefPtr<RefLogger> ptr(&a); + hashCountedSet.add(ptr); + } + + EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr2(&a); + auto addResult = hashCountedSet.add(WTFMove(ptr2)); + EXPECT_FALSE(addResult.isNewEntry); + } + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp b/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp index db6ca814f..145edae1a 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp @@ -25,13 +25,18 @@ #include "config.h" +#include "Counters.h" +#include "MoveOnly.h" +#include "RefLogger.h" +#include <string> #include <wtf/HashMap.h> +#include <wtf/text/StringHash.h> namespace TestWebKitAPI { typedef WTF::HashMap<int, int> IntHashMap; -TEST(WTF, HashTableIteratorComparison) +TEST(WTF_HashMap, HashTableIteratorComparison) { IntHashMap map; map.add(1, 2); @@ -60,7 +65,7 @@ static int bucketForKey(double key) return DefaultHash<double>::Hash::hash(key) & (TestDoubleHashTraits::minimumTableSize - 1); } -TEST(WTF, DoubleHashCollisions) +TEST(WTF_HashMap, 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 @@ -81,4 +86,617 @@ TEST(WTF, DoubleHashCollisions) ASSERT_EQ(map.get(negativeZeroKey), 3); } +TEST(WTF_HashMap, MoveOnlyValues) +{ + HashMap<unsigned, MoveOnly> moveOnlyValues; + + for (size_t i = 0; i < 100; ++i) { + MoveOnly moveOnly(i + 1); + moveOnlyValues.set(i + 1, WTFMove(moveOnly)); + } + + for (size_t i = 0; i < 100; ++i) { + auto it = moveOnlyValues.find(i + 1); + ASSERT_FALSE(it == moveOnlyValues.end()); + } + + for (size_t i = 0; i < 50; ++i) + ASSERT_EQ(moveOnlyValues.take(i + 1).value(), i + 1); + + for (size_t i = 50; i < 100; ++i) + ASSERT_TRUE(moveOnlyValues.remove(i + 1)); + + ASSERT_TRUE(moveOnlyValues.isEmpty()); +} + +TEST(WTF_HashMap, MoveOnlyKeys) +{ + HashMap<MoveOnly, unsigned> moveOnlyKeys; + + for (size_t i = 0; i < 100; ++i) { + MoveOnly moveOnly(i + 1); + moveOnlyKeys.set(WTFMove(moveOnly), i + 1); + } + + for (size_t i = 0; i < 100; ++i) { + auto it = moveOnlyKeys.find(MoveOnly(i + 1)); + ASSERT_FALSE(it == moveOnlyKeys.end()); + } + + for (size_t i = 0; i < 100; ++i) + ASSERT_FALSE(moveOnlyKeys.add(MoveOnly(i + 1), i + 1).isNewEntry); + + for (size_t i = 0; i < 100; ++i) + ASSERT_TRUE(moveOnlyKeys.remove(MoveOnly(i + 1))); + + ASSERT_TRUE(moveOnlyKeys.isEmpty()); +} + +TEST(WTF_HashMap, InitializerList) +{ + HashMap<unsigned, std::string> map = { + { 1, "one" }, + { 2, "two" }, + { 3, "three" }, + { 4, "four" }, + }; + + EXPECT_EQ(4u, map.size()); + + EXPECT_EQ("one", map.get(1)); + EXPECT_EQ("two", map.get(2)); + EXPECT_EQ("three", map.get(3)); + EXPECT_EQ("four", map.get(4)); + EXPECT_EQ(std::string(), map.get(5)); +} + +TEST(WTF_HashMap, EfficientGetter) +{ + HashMap<unsigned, CopyMoveCounter> map; + map.set(1, CopyMoveCounter()); + + { + CopyMoveCounter::TestingScope scope; + map.get(1); + EXPECT_EQ(0U, CopyMoveCounter::constructionCount); + EXPECT_EQ(1U, CopyMoveCounter::copyCount); + EXPECT_EQ(0U, CopyMoveCounter::moveCount); + } + + { + CopyMoveCounter::TestingScope scope; + map.get(2); + EXPECT_EQ(1U, CopyMoveCounter::constructionCount); + EXPECT_EQ(0U, CopyMoveCounter::copyCount); + EXPECT_EQ(1U, CopyMoveCounter::moveCount); + } +} + +TEST(WTF_HashMap, UniquePtrKey) +{ + ConstructorDestructorCounter::TestingScope scope; + + HashMap<std::unique_ptr<ConstructorDestructorCounter>, int> map; + + auto uniquePtr = std::make_unique<ConstructorDestructorCounter>(); + map.add(WTFMove(uniquePtr), 2); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + map.clear(); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); +} + +TEST(WTF_HashMap, UniquePtrKey_CustomDeleter) +{ + ConstructorDestructorCounter::TestingScope constructorDestructorCounterScope; + DeleterCounter<ConstructorDestructorCounter>::TestingScope deleterCounterScope; + + HashMap<std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>>, int> map; + + std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>> uniquePtr(new ConstructorDestructorCounter(), DeleterCounter<ConstructorDestructorCounter>()); + map.add(WTFMove(uniquePtr), 2); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + EXPECT_EQ(0u, DeleterCounter<ConstructorDestructorCounter>::deleterCount); + + map.clear(); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); + + EXPECT_EQ(1u, DeleterCounter<ConstructorDestructorCounter>::deleterCount); +} + +TEST(WTF_HashMap, UniquePtrKey_FindUsingRawPointer) +{ + HashMap<std::unique_ptr<int>, int> map; + + auto uniquePtr = std::make_unique<int>(5); + int* ptr = uniquePtr.get(); + map.add(WTFMove(uniquePtr), 2); + + auto it = map.find(ptr); + ASSERT_TRUE(it != map.end()); + EXPECT_EQ(ptr, it->key.get()); + EXPECT_EQ(2, it->value); +} + +TEST(WTF_HashMap, UniquePtrKey_ContainsUsingRawPointer) +{ + HashMap<std::unique_ptr<int>, int> map; + + auto uniquePtr = std::make_unique<int>(5); + int* ptr = uniquePtr.get(); + map.add(WTFMove(uniquePtr), 2); + + EXPECT_EQ(true, map.contains(ptr)); +} + +TEST(WTF_HashMap, UniquePtrKey_GetUsingRawPointer) +{ + HashMap<std::unique_ptr<int>, int> map; + + auto uniquePtr = std::make_unique<int>(5); + int* ptr = uniquePtr.get(); + map.add(WTFMove(uniquePtr), 2); + + int value = map.get(ptr); + EXPECT_EQ(2, value); +} + +TEST(WTF_HashMap, UniquePtrKey_RemoveUsingRawPointer) +{ + ConstructorDestructorCounter::TestingScope scope; + + HashMap<std::unique_ptr<ConstructorDestructorCounter>, int> map; + + auto uniquePtr = std::make_unique<ConstructorDestructorCounter>(); + ConstructorDestructorCounter* ptr = uniquePtr.get(); + map.add(WTFMove(uniquePtr), 2); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + bool result = map.remove(ptr); + EXPECT_EQ(true, result); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); +} + +TEST(WTF_HashMap, UniquePtrKey_TakeUsingRawPointer) +{ + ConstructorDestructorCounter::TestingScope scope; + + HashMap<std::unique_ptr<ConstructorDestructorCounter>, int> map; + + auto uniquePtr = std::make_unique<ConstructorDestructorCounter>(); + ConstructorDestructorCounter* ptr = uniquePtr.get(); + map.add(WTFMove(uniquePtr), 2); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + int result = map.take(ptr); + EXPECT_EQ(2, result); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); +} + +TEST(WTF_HashMap, RefPtrKey_Add) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + map.add(ptr, 0); + + ASSERT_STREQ("ref(a) ref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_AddUsingRelease) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + map.add(ptr.release(), 0); + + EXPECT_STREQ("ref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_AddUsingMove) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + map.add(WTFMove(ptr), 0); + + EXPECT_STREQ("ref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_AddUsingRaw) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + map.add(ptr.get(), 0); + + EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_AddKeyAlreadyPresent) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + + { + RefPtr<RefLogger> ptr(&a); + map.add(ptr, 0); + } + + EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr2(&a); + auto addResult = map.add(ptr2, 0); + EXPECT_FALSE(addResult.isNewEntry); + } + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_AddUsingReleaseKeyAlreadyPresent) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + + { + RefPtr<RefLogger> ptr(&a); + map.add(ptr, 0); + } + + EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr2(&a); + auto addResult = map.add(ptr2.release(), 0); + EXPECT_FALSE(addResult.isNewEntry); + } + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_AddUsingMoveKeyAlreadyPresent) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + + { + RefPtr<RefLogger> ptr(&a); + map.add(ptr, 0); + } + + EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr2(&a); + auto addResult = map.add(WTFMove(ptr2), 0); + EXPECT_FALSE(addResult.isNewEntry); + } + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_Set) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + map.set(ptr, 0); + + ASSERT_STREQ("ref(a) ref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_SetUsingRelease) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + map.set(ptr.release(), 0); + + EXPECT_STREQ("ref(a) ", takeLogStr().c_str()); +} + + +TEST(WTF_HashMap, RefPtrKey_SetUsingMove) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + map.set(WTFMove(ptr), 0); + + EXPECT_STREQ("ref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_SetUsingRaw) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + RefPtr<RefLogger> ptr(&a); + map.set(ptr.get(), 0); + + EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_SetKeyAlreadyPresent) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + + RefPtr<RefLogger> ptr(&a); + map.set(ptr, 0); + + EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr2(&a); + auto addResult = map.set(ptr2, 1); + EXPECT_FALSE(addResult.isNewEntry); + EXPECT_EQ(1, map.get(ptr.get())); + } + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_SetUsingReleaseKeyAlreadyPresent) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + + RefPtr<RefLogger> ptr(&a); + map.set(ptr, 0); + + EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr2(&a); + auto addResult = map.set(ptr2.release(), 1); + EXPECT_FALSE(addResult.isNewEntry); + EXPECT_EQ(1, map.get(ptr.get())); + } + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, RefPtrKey_SetUsingMoveKeyAlreadyPresent) +{ + HashMap<RefPtr<RefLogger>, int> map; + + DerivedRefLogger a("a"); + + RefPtr<RefLogger> ptr(&a); + map.set(ptr, 0); + + EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr2(&a); + auto addResult = map.set(WTFMove(ptr2), 1); + EXPECT_FALSE(addResult.isNewEntry); + EXPECT_EQ(1, map.get(ptr.get())); + } + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_HashMap, Ensure) +{ + HashMap<unsigned, unsigned> map; + { + auto addResult = map.ensure(1, [] { return 1; }); + EXPECT_EQ(1u, addResult.iterator->value); + EXPECT_EQ(1u, addResult.iterator->key); + EXPECT_TRUE(addResult.isNewEntry); + auto addResult2 = map.ensure(1, [] { return 2; }); + EXPECT_EQ(1u, addResult2.iterator->value); + EXPECT_EQ(1u, addResult2.iterator->key); + EXPECT_FALSE(addResult2.isNewEntry); + } +} + +TEST(WTF_HashMap, Ensure_MoveOnlyValues) +{ + HashMap<unsigned, MoveOnly> moveOnlyValues; + { + auto addResult = moveOnlyValues.ensure(1, [] { return MoveOnly(1); }); + EXPECT_EQ(1u, addResult.iterator->value.value()); + EXPECT_EQ(1u, addResult.iterator->key); + EXPECT_TRUE(addResult.isNewEntry); + auto addResult2 = moveOnlyValues.ensure(1, [] { return MoveOnly(2); }); + EXPECT_EQ(1u, addResult2.iterator->value.value()); + EXPECT_EQ(1u, addResult2.iterator->key); + EXPECT_FALSE(addResult2.isNewEntry); + } +} + +TEST(WTF_HashMap, Ensure_UniquePointer) +{ + HashMap<unsigned, std::unique_ptr<unsigned>> map; + { + auto addResult = map.ensure(1, [] { return std::make_unique<unsigned>(1); }); + EXPECT_EQ(1u, *map.get(1)); + EXPECT_EQ(1u, *addResult.iterator->value.get()); + EXPECT_EQ(1u, addResult.iterator->key); + EXPECT_TRUE(addResult.isNewEntry); + auto addResult2 = map.ensure(1, [] { return std::make_unique<unsigned>(2); }); + EXPECT_EQ(1u, *map.get(1)); + EXPECT_EQ(1u, *addResult2.iterator->value.get()); + EXPECT_EQ(1u, addResult2.iterator->key); + EXPECT_FALSE(addResult2.isNewEntry); + } +} + +TEST(WTF_HashMap, Ensure_RefPtr) +{ + HashMap<unsigned, RefPtr<RefLogger>> map; + + { + DerivedRefLogger a("a"); + + map.ensure(1, [&] { return RefPtr<RefLogger>(&a); }); + EXPECT_STREQ("ref(a) ", takeLogStr().c_str()); + + map.ensure(1, [&] { return RefPtr<RefLogger>(&a); }); + EXPECT_STREQ("", takeLogStr().c_str()); + } +} + +class ObjectWithRefLogger { +public: + ObjectWithRefLogger(Ref<RefLogger>&& logger) + : m_logger(WTFMove(logger)) + { + } + + Ref<RefLogger> m_logger; +}; + + +void testMovingUsingEnsure(Ref<RefLogger>&& logger) +{ + HashMap<unsigned, std::unique_ptr<ObjectWithRefLogger>> map; + + map.ensure(1, [&] { return std::make_unique<ObjectWithRefLogger>(WTFMove(logger)); }); +} + +void testMovingUsingAdd(Ref<RefLogger>&& logger) +{ + HashMap<unsigned, std::unique_ptr<ObjectWithRefLogger>> map; + + auto& slot = map.add(1, nullptr).iterator->value; + slot = std::make_unique<ObjectWithRefLogger>(WTFMove(logger)); +} + +TEST(WTF_HashMap, Ensure_LambdasCapturingByReference) +{ + { + DerivedRefLogger a("a"); + Ref<RefLogger> ref(a); + testMovingUsingEnsure(WTFMove(ref)); + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + } + + { + DerivedRefLogger a("a"); + Ref<RefLogger> ref(a); + testMovingUsingAdd(WTFMove(ref)); + + EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + } +} + + +TEST(WTF_HashMap, ValueIsDestructedOnRemove) +{ + struct DestructorObserver { + DestructorObserver() = default; + + DestructorObserver(bool* destructed) + : destructed(destructed) + { + } + + ~DestructorObserver() + { + if (destructed) + *destructed = true; + } + + DestructorObserver(DestructorObserver&& other) + : destructed(other.destructed) + { + other.destructed = nullptr; + } + + DestructorObserver& operator=(DestructorObserver&& other) + { + destructed = other.destructed; + other.destructed = nullptr; + return *this; + } + + bool* destructed { nullptr }; + }; + + HashMap<int, DestructorObserver> map; + + bool destructed = false; + map.add(5, DestructorObserver { &destructed }); + + EXPECT_FALSE(destructed); + + bool removeResult = map.remove(5); + + EXPECT_TRUE(removeResult); + EXPECT_TRUE(destructed); +} + +TEST(WTF_HashMap, RefPtrNotZeroedBeforeDeref) +{ + struct DerefObserver { + NEVER_INLINE void ref() + { + ++count; + } + NEVER_INLINE void deref() + { + --count; + observedBucket = bucketAddress->get(); + } + unsigned count { 1 }; + const RefPtr<DerefObserver>* bucketAddress { nullptr }; + const DerefObserver* observedBucket { nullptr }; + }; + + auto observer = std::make_unique<DerefObserver>(); + + HashMap<RefPtr<DerefObserver>, int> map; + map.add(adoptRef(observer.get()), 5); + + auto iterator = map.find(observer.get()); + EXPECT_TRUE(iterator != map.end()); + + observer->bucketAddress = &iterator->key; + + EXPECT_TRUE(observer->observedBucket == nullptr); + EXPECT_TRUE(map.remove(observer.get())); + + // It if fine to either leave the old value intact at deletion or already set it to the deleted + // value. + // A zero would be a incorrect outcome as it would mean we nulled the bucket before an opaque + // call. + EXPECT_TRUE(observer->observedBucket == observer.get() || observer->observedBucket == RefPtr<DerefObserver>::hashTableDeletedValue()); + EXPECT_EQ(observer->count, 0u); +} + } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp b/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp index 71e21aa28..1d6ffc039 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp @@ -25,7 +25,10 @@ #include "config.h" +#include "Counters.h" +#include "MoveOnly.h" #include <wtf/HashSet.h> +#include <wtf/RefPtr.h> namespace TestWebKitAPI { @@ -41,7 +44,7 @@ void testInitialCapacity() HashSet<int, DefaultHash<int>::Hash, InitialCapacityTestHashTraits<initialCapacity> > testSet; // Initial capacity is null. - ASSERT_EQ(0, testSet.capacity()); + ASSERT_EQ(0u, testSet.capacity()); // Adding items up to size should never change the capacity. for (size_t i = 0; i < size; ++i) { @@ -71,9 +74,279 @@ template<unsigned size> void generateTestCapacityUpToSize() testInitialCapacity<size>(); } -TEST(WTF, HashSetInitialCapacity) +TEST(WTF_HashSet, InitialCapacity) { generateTestCapacityUpToSize<128>(); } +TEST(WTF_HashSet, MoveOnly) +{ + HashSet<MoveOnly> hashSet; + + for (size_t i = 0; i < 100; ++i) { + MoveOnly moveOnly(i + 1); + hashSet.add(WTFMove(moveOnly)); + } + + for (size_t i = 0; i < 100; ++i) + EXPECT_TRUE(hashSet.contains(MoveOnly(i + 1))); + + for (size_t i = 0; i < 100; ++i) + EXPECT_TRUE(hashSet.remove(MoveOnly(i + 1))); + + EXPECT_TRUE(hashSet.isEmpty()); + + for (size_t i = 0; i < 100; ++i) + hashSet.add(MoveOnly(i + 1)); + + for (size_t i = 0; i < 100; ++i) + EXPECT_TRUE(hashSet.take(MoveOnly(i + 1)) == MoveOnly(i + 1)); + + EXPECT_TRUE(hashSet.isEmpty()); + + for (size_t i = 0; i < 100; ++i) + hashSet.add(MoveOnly(i + 1)); + + HashSet<MoveOnly> secondSet; + + for (size_t i = 0; i < 100; ++i) + secondSet.add(hashSet.takeAny()); + + EXPECT_TRUE(hashSet.isEmpty()); + + for (size_t i = 0; i < 100; ++i) + EXPECT_TRUE(secondSet.contains(MoveOnly(i + 1))); +} + + +TEST(WTF_HashSet, UniquePtrKey) +{ + ConstructorDestructorCounter::TestingScope scope; + + HashSet<std::unique_ptr<ConstructorDestructorCounter>> set; + + auto uniquePtr = std::make_unique<ConstructorDestructorCounter>(); + set.add(WTFMove(uniquePtr)); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + set.clear(); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); +} + +TEST(WTF_HashSet, UniquePtrKey_FindUsingRawPointer) +{ + HashSet<std::unique_ptr<int>> set; + + auto uniquePtr = std::make_unique<int>(5); + int* ptr = uniquePtr.get(); + set.add(WTFMove(uniquePtr)); + + auto it = set.find(ptr); + ASSERT_TRUE(it != set.end()); + EXPECT_EQ(ptr, it->get()); + EXPECT_EQ(5, *it->get()); +} + +TEST(WTF_HashSet, UniquePtrKey_ContainsUsingRawPointer) +{ + HashSet<std::unique_ptr<int>> set; + + auto uniquePtr = std::make_unique<int>(5); + int* ptr = uniquePtr.get(); + set.add(WTFMove(uniquePtr)); + + EXPECT_EQ(true, set.contains(ptr)); +} + +TEST(WTF_HashSet, UniquePtrKey_RemoveUsingRawPointer) +{ + ConstructorDestructorCounter::TestingScope scope; + + HashSet<std::unique_ptr<ConstructorDestructorCounter>> set; + + auto uniquePtr = std::make_unique<ConstructorDestructorCounter>(); + ConstructorDestructorCounter* ptr = uniquePtr.get(); + set.add(WTFMove(uniquePtr)); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + bool result = set.remove(ptr); + EXPECT_EQ(true, result); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); +} + +TEST(WTF_HashSet, UniquePtrKey_TakeUsingRawPointer) +{ + ConstructorDestructorCounter::TestingScope scope; + + HashSet<std::unique_ptr<ConstructorDestructorCounter>> set; + + auto uniquePtr = std::make_unique<ConstructorDestructorCounter>(); + ConstructorDestructorCounter* ptr = uniquePtr.get(); + set.add(WTFMove(uniquePtr)); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + auto result = set.take(ptr); + EXPECT_EQ(ptr, result.get()); + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount); + + result = nullptr; + + EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount); + EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount); +} + +TEST(WTF_HashSet, CopyEmpty) +{ + { + HashSet<unsigned> foo; + HashSet<unsigned> bar(foo); + + EXPECT_EQ(0u, bar.capacity()); + EXPECT_EQ(0u, bar.size()); + } + { + HashSet<unsigned> foo({ 1, 5, 64, 42 }); + EXPECT_EQ(4u, foo.size()); + foo.remove(1); + foo.remove(5); + foo.remove(42); + foo.remove(64); + HashSet<unsigned> bar(foo); + + EXPECT_EQ(0u, bar.capacity()); + EXPECT_EQ(0u, bar.size()); + } +} + +TEST(WTF_HashSet, CopyAllocateAtLeastMinimumCapacity) +{ + HashSet<unsigned> foo({ 42 }); + EXPECT_EQ(1u, foo.size()); + HashSet<unsigned> bar(foo); + + EXPECT_EQ(8u, bar.capacity()); + EXPECT_EQ(1u, bar.size()); +} + +TEST(WTF_HashSet, CopyCapacityIsNotOnBoundary) +{ + // Starting at 4 because the minimum size is 8. + // With a size of 8, a medium load can be up to 3.3333->3. + // Adding 1 to 3 would reach max load. + // While correct, that's not really what we care about here. + for (unsigned size = 4; size < 100; ++size) { + HashSet<unsigned> source; + for (unsigned i = 1; i < size + 1; ++i) + source.add(i); + + HashSet<unsigned> copy1(source); + HashSet<unsigned> copy2(source); + HashSet<unsigned> copy3(source); + + EXPECT_EQ(size, copy1.size()); + EXPECT_EQ(size, copy2.size()); + EXPECT_EQ(size, copy3.size()); + for (unsigned i = 1; i < size + 1; ++i) { + EXPECT_TRUE(copy1.contains(i)); + EXPECT_TRUE(copy2.contains(i)); + EXPECT_TRUE(copy3.contains(i)); + } + EXPECT_FALSE(copy1.contains(size + 2)); + EXPECT_FALSE(copy2.contains(size + 2)); + EXPECT_FALSE(copy3.contains(size + 2)); + + EXPECT_TRUE(copy2.remove(1)); + EXPECT_EQ(copy1.capacity(), copy2.capacity()); + EXPECT_FALSE(copy2.contains(1)); + + EXPECT_TRUE(copy3.add(size + 2).isNewEntry); + EXPECT_EQ(copy1.capacity(), copy3.capacity()); + EXPECT_TRUE(copy3.contains(size + 2)); + } +} + +TEST(WTF_HashSet, RefPtrNotZeroedBeforeDeref) +{ + struct DerefObserver { + NEVER_INLINE void ref() + { + ++count; + } + NEVER_INLINE void deref() + { + --count; + observedBucket = bucketAddress->get(); + } + unsigned count { 1 }; + const RefPtr<DerefObserver>* bucketAddress { nullptr }; + const DerefObserver* observedBucket { nullptr }; + }; + + auto observer = std::make_unique<DerefObserver>(); + + HashSet<RefPtr<DerefObserver>> set; + set.add(adoptRef(observer.get())); + + auto iterator = set.find(observer.get()); + EXPECT_TRUE(iterator != set.end()); + + observer->bucketAddress = iterator.get(); + + EXPECT_TRUE(observer->observedBucket == nullptr); + EXPECT_TRUE(set.remove(observer.get())); + + // It if fine to either leave the old value intact at deletion or already set it to the deleted + // value. + // A zero would be a incorrect outcome as it would mean we nulled the bucket before an opaque + // call. + EXPECT_TRUE(observer->observedBucket == observer.get() || observer->observedBucket == RefPtr<DerefObserver>::hashTableDeletedValue()); + EXPECT_EQ(observer->count, 0u); +} + + +TEST(WTF_HashSet, UniquePtrNotZeroedBeforeDestructor) +{ + struct DestructorObserver { + ~DestructorObserver() + { + observe(); + } + std::function<void()> observe; + }; + + const std::unique_ptr<DestructorObserver>* bucketAddress = nullptr; + const DestructorObserver* observedBucket = nullptr; + std::unique_ptr<DestructorObserver> observer(new DestructorObserver { [&]() { + observedBucket = bucketAddress->get(); + }}); + + const DestructorObserver* observerAddress = observer.get(); + + HashSet<std::unique_ptr<DestructorObserver>> set; + auto addResult = set.add(WTFMove(observer)); + + EXPECT_TRUE(addResult.isNewEntry); + EXPECT_TRUE(observedBucket == nullptr); + + bucketAddress = addResult.iterator.get(); + + EXPECT_TRUE(observedBucket == nullptr); + EXPECT_TRUE(set.remove(*addResult.iterator)); + + EXPECT_TRUE(observedBucket == observerAddress || observedBucket == reinterpret_cast<const DestructorObserver*>(-1)); +} + + } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/ListHashSet.cpp b/Tools/TestWebKitAPI/Tests/WTF/ListHashSet.cpp index 7579c4299..d81dcfcfe 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/ListHashSet.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/ListHashSet.cpp @@ -25,11 +25,12 @@ #include "config.h" +#include "MoveOnly.h" #include <wtf/ListHashSet.h> namespace TestWebKitAPI { -TEST(WTF, ListHashSetRemoveFirst) +TEST(WTF_ListHashSet, RemoveFirst) { ListHashSet<int> list; list.add(1); @@ -48,7 +49,26 @@ TEST(WTF, ListHashSetRemoveFirst) ASSERT_TRUE(list.isEmpty()); } -TEST(WTF, ListHashSetAppendOrMoveToLastNewItems) +TEST(WTF_ListHashSet, RemoveLast) +{ + ListHashSet<int> list; + list.add(1); + list.add(2); + list.add(3); + + ASSERT_EQ(3, list.last()); + + list.removeLast(); + ASSERT_EQ(2, list.last()); + + list.removeLast(); + ASSERT_EQ(1, list.last()); + + list.removeLast(); + ASSERT_TRUE(list.isEmpty()); +} + +TEST(WTF_ListHashSet, AppendOrMoveToLastNewItems) { ListHashSet<int> list; ListHashSet<int>::AddResult result = list.appendOrMoveToLast(1); @@ -58,7 +78,7 @@ TEST(WTF, ListHashSetAppendOrMoveToLastNewItems) result = list.appendOrMoveToLast(3); ASSERT_TRUE(result.isNewEntry); - ASSERT_EQ(list.size(), 3); + ASSERT_EQ(list.size(), 3u); // The list should be in order 1, 2, 3. ListHashSet<int>::iterator iterator = list.begin(); @@ -70,7 +90,7 @@ TEST(WTF, ListHashSetAppendOrMoveToLastNewItems) ++iterator; } -TEST(WTF, ListHashSetAppendOrMoveToLastWithDuplicates) +TEST(WTF_ListHashSet, AppendOrMoveToLastWithDuplicates) { ListHashSet<int> list; @@ -79,11 +99,11 @@ TEST(WTF, ListHashSetAppendOrMoveToLastWithDuplicates) ASSERT_TRUE(result.isNewEntry); result = list.appendOrMoveToLast(1); ASSERT_FALSE(result.isNewEntry); - ASSERT_EQ(1, list.size()); + ASSERT_EQ(1u, list.size()); list.add(2); list.add(3); - ASSERT_EQ(3, list.size()); + ASSERT_EQ(3u, list.size()); // Appending 2 move it to the end. ASSERT_EQ(3, list.last()); @@ -98,7 +118,7 @@ TEST(WTF, ListHashSetAppendOrMoveToLastWithDuplicates) ASSERT_FALSE(result.isNewEntry); result = list.appendOrMoveToLast(1); ASSERT_FALSE(result.isNewEntry); - ASSERT_EQ(3, list.size()); + ASSERT_EQ(3u, list.size()); ListHashSet<int>::iterator iterator = list.begin(); ASSERT_EQ(3, *iterator); @@ -109,7 +129,7 @@ TEST(WTF, ListHashSetAppendOrMoveToLastWithDuplicates) ++iterator; } -TEST(WTF, ListHashSetPrependOrMoveToLastNewItems) +TEST(WTF_ListHashSet, PrependOrMoveToLastNewItems) { ListHashSet<int> list; ListHashSet<int>::AddResult result = list.prependOrMoveToFirst(1); @@ -119,7 +139,7 @@ TEST(WTF, ListHashSetPrependOrMoveToLastNewItems) result = list.prependOrMoveToFirst(3); ASSERT_TRUE(result.isNewEntry); - ASSERT_EQ(list.size(), 3); + ASSERT_EQ(list.size(), 3u); // The list should be in order 3, 1, 2. ListHashSet<int>::iterator iterator = list.begin(); @@ -131,7 +151,7 @@ TEST(WTF, ListHashSetPrependOrMoveToLastNewItems) ++iterator; } -TEST(WTF, ListHashSetPrependOrMoveToLastWithDuplicates) +TEST(WTF_ListHashSet, PrependOrMoveToLastWithDuplicates) { ListHashSet<int> list; @@ -140,11 +160,11 @@ TEST(WTF, ListHashSetPrependOrMoveToLastWithDuplicates) ASSERT_TRUE(result.isNewEntry); result = list.prependOrMoveToFirst(1); ASSERT_FALSE(result.isNewEntry); - ASSERT_EQ(1, list.size()); + ASSERT_EQ(1u, list.size()); list.add(2); list.add(3); - ASSERT_EQ(3, list.size()); + ASSERT_EQ(3u, list.size()); // Prepending 2 move it to the beginning. ASSERT_EQ(1, list.first()); @@ -159,7 +179,7 @@ TEST(WTF, ListHashSetPrependOrMoveToLastWithDuplicates) ASSERT_FALSE(result.isNewEntry); result = list.prependOrMoveToFirst(3); ASSERT_FALSE(result.isNewEntry); - ASSERT_EQ(3, list.size()); + ASSERT_EQ(3u, list.size()); ListHashSet<int>::iterator iterator = list.begin(); ASSERT_EQ(3, *iterator); @@ -170,4 +190,80 @@ TEST(WTF, ListHashSetPrependOrMoveToLastWithDuplicates) ++iterator; } +TEST(WTF_ListHashSet, ReverseIterator) +{ + ListHashSet<int> list; + + list.add(1); + list.add(2); + list.add(3); + + auto it = list.rbegin(); + ASSERT_EQ(3, *it); + ++it; + ASSERT_EQ(2, *it); + ++it; + ASSERT_EQ(1, *it); + ++it; + ASSERT_TRUE(it == list.rend()); + + const auto& listHashSet = list; + + auto constIt = listHashSet.rbegin(); + ASSERT_EQ(3, *constIt); + ++constIt; + ASSERT_EQ(2, *constIt); + ++constIt; + ASSERT_EQ(1, *constIt); + ++constIt; + ASSERT_TRUE(constIt == listHashSet.rend()); +} + +TEST(WTF_ListHashSet, MoveOnly) +{ + ListHashSet<MoveOnly> list; + list.add(MoveOnly(2)); + list.add(MoveOnly(4)); + + // { 2, 4 } + ASSERT_EQ(2U, list.first().value()); + ASSERT_EQ(4U, list.last().value()); + + list.appendOrMoveToLast(MoveOnly(3)); + + // { 2, 4, 3 } + ASSERT_EQ(3U, list.last().value()); + + // { 4, 3, 2 } + list.appendOrMoveToLast(MoveOnly(2)); + ASSERT_EQ(4U, list.first().value()); + ASSERT_EQ(2U, list.last().value()); + + list.prependOrMoveToFirst(MoveOnly(5)); + + // { 5, 2, 4, 3 } + ASSERT_EQ(5U, list.first().value()); + + list.prependOrMoveToFirst(MoveOnly(3)); + + // { 3, 5, 4, 2 } + ASSERT_EQ(3U, list.first().value()); + ASSERT_EQ(2U, list.last().value()); + + list.insertBefore(MoveOnly(4), MoveOnly(1)); + list.insertBefore(list.end(), MoveOnly(6)); + + // { 3, 5, 1, 4, 2, 6 } + ASSERT_EQ(3U, list.takeFirst().value()); + ASSERT_EQ(5U, list.takeFirst().value()); + ASSERT_EQ(1U, list.takeFirst().value()); + + // { 4, 2, 6 } + ASSERT_EQ(6U, list.takeLast().value()); + ASSERT_EQ(2U, list.takeLast().value()); + ASSERT_EQ(4U, list.takeLast().value()); + + ASSERT_TRUE(list.isEmpty()); +} + } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/Lock.cpp b/Tools/TestWebKitAPI/Tests/WTF/Lock.cpp new file mode 100644 index 000000000..5576302d6 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/Lock.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2015 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/Lock.h> +#include <wtf/Threading.h> +#include <wtf/ThreadingPrimitives.h> +#include <wtf/WordLock.h> + +using namespace WTF; + +namespace TestWebKitAPI { + +struct LockInspector { + template<typename LockType> + static bool isFullyReset(LockType& lock) + { + return lock.isFullyReset(); + } +}; + +template<typename LockType> +void runLockTest(unsigned numThreadGroups, unsigned numThreadsPerGroup, unsigned workPerCriticalSection, unsigned numIterations) +{ + std::unique_ptr<LockType[]> locks = std::make_unique<LockType[]>(numThreadGroups); + std::unique_ptr<double[]> words = std::make_unique<double[]>(numThreadGroups); + std::unique_ptr<ThreadIdentifier[]> threads = std::make_unique<ThreadIdentifier[]>(numThreadGroups * numThreadsPerGroup); + + for (unsigned threadGroupIndex = numThreadGroups; threadGroupIndex--;) { + words[threadGroupIndex] = 0; + + for (unsigned threadIndex = numThreadsPerGroup; threadIndex--;) { + threads[threadGroupIndex * numThreadsPerGroup + threadIndex] = createThread( + "Lock test thread", + [threadGroupIndex, &locks, &words, numIterations, workPerCriticalSection] () { + for (unsigned i = numIterations; i--;) { + locks[threadGroupIndex].lock(); + for (unsigned j = workPerCriticalSection; j--;) + words[threadGroupIndex]++; + locks[threadGroupIndex].unlock(); + } + }); + } + } + + for (unsigned threadIndex = numThreadGroups * numThreadsPerGroup; threadIndex--;) + waitForThreadCompletion(threads[threadIndex]); + + double expected = 0; + for (uint64_t i = static_cast<uint64_t>(numIterations) * workPerCriticalSection * numThreadsPerGroup; i--;) + expected++; + + for (unsigned threadGroupIndex = numThreadGroups; threadGroupIndex--;) + EXPECT_EQ(expected, words[threadGroupIndex]); + + // Now test that the locks correctly reset themselves. We expect that if a single thread locks + // each of the locks twice in a row, then the lock should be in a pristine state. + for (unsigned threadGroupIndex = numThreadGroups; threadGroupIndex--;) { + for (unsigned i = 2; i--;) { + locks[threadGroupIndex].lock(); + locks[threadGroupIndex].unlock(); + } + + EXPECT_EQ(true, LockInspector::isFullyReset(locks[threadGroupIndex])); + } +} + +bool skipSlow() +{ +#if PLATFORM(WIN) && !defined(NDEBUG) + return true; +#else + return false; +#endif +} + +TEST(WTF_WordLock, UncontendedShortSection) +{ + runLockTest<WordLock>(1, 1, 1, 10000000); +} + +TEST(WTF_WordLock, UncontendedLongSection) +{ + runLockTest<WordLock>(1, 1, 10000, 1000); +} + +TEST(WTF_WordLock, ContendedShortSection) +{ + if (skipSlow()) + return; + runLockTest<WordLock>(1, 10, 1, 5000000); +} + +TEST(WTF_WordLock, ContendedLongSection) +{ + if (skipSlow()) + return; + runLockTest<WordLock>(1, 10, 10000, 10000); +} + +TEST(WTF_WordLock, ManyContendedShortSections) +{ + if (skipSlow()) + return; + runLockTest<WordLock>(10, 10, 1, 500000); +} + +TEST(WTF_WordLock, ManyContendedLongSections) +{ + if (skipSlow()) + return; + runLockTest<WordLock>(10, 10, 10000, 500); +} + +TEST(WTF_Lock, UncontendedShortSection) +{ + runLockTest<Lock>(1, 1, 1, 10000000); +} + +TEST(WTF_Lock, UncontendedLongSection) +{ + runLockTest<Lock>(1, 1, 10000, 1000); +} + +TEST(WTF_Lock, ContendedShortSection) +{ + if (skipSlow()) + return; + runLockTest<Lock>(1, 10, 1, 10000000); +} + +TEST(WTF_Lock, ContendedLongSection) +{ + if (skipSlow()) + return; + runLockTest<Lock>(1, 10, 10000, 10000); +} + +TEST(WTF_Lock, ManyContendedShortSections) +{ + if (skipSlow()) + return; + runLockTest<Lock>(10, 10, 1, 500000); +} + +TEST(WTF_Lock, ManyContendedLongSections) +{ + if (skipSlow()) + return; + runLockTest<Lock>(10, 10, 10000, 1000); +} + +TEST(WTF_Lock, ManyContendedLongerSections) +{ + if (skipSlow()) + return; + runLockTest<Lock>(10, 10, 100000, 1); +} + +TEST(WTF_Lock, SectionAddressCollision) +{ + if (skipSlow()) + return; + runLockTest<Lock>(4, 2, 10000, 2000); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/MD5.cpp b/Tools/TestWebKitAPI/Tests/WTF/MD5.cpp index 7f592aee4..2c862a9cf 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/MD5.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/MD5.cpp @@ -21,12 +21,12 @@ static void expectMD5(CString input, CString expected) { MD5 md5; md5.addBytes(reinterpret_cast<const uint8_t*>(input.data()), input.length()); - Vector<uint8_t, 16> digest; + MD5::Digest digest; md5.checksum(digest); char* buf = 0; CString actual = CString::newUninitialized(32, buf); - for (size_t i = 0; i < 16; i++, buf += 2) - snprintf(buf, 3, "%02x", digest.at(i)); + for (size_t i = 0; i < MD5::hashSize; i++, buf += 2) + snprintf(buf, 3, "%02x", digest[i]); ASSERT_EQ(expected.length(), actual.length()); ASSERT_STREQ(expected.data(), actual.data()); diff --git a/Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp b/Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp index d6d48fc61..2386143e3 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/MediaTime.cpp @@ -10,7 +10,7 @@ * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -26,24 +26,14 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define _USE_MATH_DEFINES 1 #include "config.h" +#include <limits> +#include <wtf/MathExtras.h> #include <wtf/MediaTime.h> using namespace std; -#if COMPILER(MSVC) -// Work around Visual Studio 2008's lack of an INFINITY or NAN definition. -#include <limits> -#if !defined(INFINITY) -#define INFINITY (numeric_limits<double>::infinity()) -#endif -#if !defined(NAN) -#define NAN (numeric_limits<double>::quiet_NaN()) -#endif -#endif - namespace WTF { std::ostream& operator<<(std::ostream& out, const MediaTime& val) @@ -55,6 +45,8 @@ std::ostream& operator<<(std::ostream& out, const MediaTime& val) out << "+infinite"; else if (val.isNegativeInfinite()) out << "-infinite"; + else if (val.hasDoubleValue()) + out << "double: " << val.toDouble(); else out << "value: " << val.timeValue() << ", scale: " << val.timeScale(); return out << " }"; @@ -71,12 +63,17 @@ TEST(WTF, MediaTime) EXPECT_EQ(MediaTime::negativeInfiniteTime() < MediaTime::positiveInfiniteTime(), true); EXPECT_EQ(MediaTime::negativeInfiniteTime() == MediaTime::negativeInfiniteTime(), true); EXPECT_EQ(MediaTime::positiveInfiniteTime() == MediaTime::positiveInfiniteTime(), true); + EXPECT_EQ(MediaTime::positiveInfiniteTime() != MediaTime::negativeInfiniteTime(), true); EXPECT_EQ(MediaTime::invalidTime() == MediaTime::invalidTime(), true); + EXPECT_EQ(MediaTime::invalidTime() != MediaTime::invalidTime(), false); + EXPECT_EQ(MediaTime::invalidTime() != MediaTime::zeroTime(), true); EXPECT_EQ(MediaTime::invalidTime() > MediaTime::negativeInfiniteTime(), true); EXPECT_EQ(MediaTime::invalidTime() > MediaTime::positiveInfiniteTime(), true); EXPECT_EQ(MediaTime::negativeInfiniteTime() < MediaTime::invalidTime(), true); EXPECT_EQ(MediaTime::positiveInfiniteTime() < MediaTime::invalidTime(), true); EXPECT_EQ(MediaTime::indefiniteTime() == MediaTime::indefiniteTime(), true); + EXPECT_EQ(MediaTime::indefiniteTime() != MediaTime::indefiniteTime(), false); + EXPECT_EQ(MediaTime::indefiniteTime() != MediaTime::zeroTime(), true); EXPECT_EQ(MediaTime::indefiniteTime() > MediaTime::negativeInfiniteTime(), true); EXPECT_EQ(MediaTime::indefiniteTime() < MediaTime::positiveInfiniteTime(), true); EXPECT_EQ(MediaTime::negativeInfiniteTime() < MediaTime::indefiniteTime(), true); @@ -85,6 +82,7 @@ TEST(WTF, MediaTime) EXPECT_EQ(MediaTime::indefiniteTime() > MediaTime(1, 1), true); EXPECT_EQ(MediaTime(1, 1) < MediaTime(2, 1), true); EXPECT_EQ(MediaTime(2, 1) > MediaTime(1, 1), true); + EXPECT_EQ(MediaTime(1, 1) != MediaTime(2, 1), true); EXPECT_EQ(MediaTime(2, 1) == MediaTime(2, 1), true); EXPECT_EQ(MediaTime(2, 1) == MediaTime(4, 2), true); @@ -93,6 +91,10 @@ TEST(WTF, MediaTime) EXPECT_EQ(MediaTime::negativeInfiniteTime() + MediaTime::negativeInfiniteTime(), MediaTime::negativeInfiniteTime()); EXPECT_EQ(MediaTime::positiveInfiniteTime() + MediaTime::negativeInfiniteTime(), MediaTime::invalidTime()); EXPECT_EQ(MediaTime::negativeInfiniteTime() + MediaTime::positiveInfiniteTime(), MediaTime::invalidTime()); + EXPECT_EQ(MediaTime::positiveInfiniteTime() + MediaTime(1, 1), MediaTime::positiveInfiniteTime()); + EXPECT_EQ(MediaTime(1, 1) + MediaTime::positiveInfiniteTime(), MediaTime::positiveInfiniteTime()); + EXPECT_EQ(MediaTime::negativeInfiniteTime() + MediaTime(1, 1), MediaTime::negativeInfiniteTime()); + EXPECT_EQ(MediaTime(1, 1) + MediaTime::negativeInfiniteTime(), MediaTime::negativeInfiniteTime()); EXPECT_EQ(MediaTime::invalidTime() + MediaTime::positiveInfiniteTime(), MediaTime::invalidTime()); EXPECT_EQ(MediaTime::invalidTime() + MediaTime::negativeInfiniteTime(), MediaTime::invalidTime()); EXPECT_EQ(MediaTime::invalidTime() + MediaTime::invalidTime(), MediaTime::invalidTime()); @@ -110,6 +112,10 @@ TEST(WTF, MediaTime) EXPECT_EQ(MediaTime::negativeInfiniteTime() - MediaTime::negativeInfiniteTime(), MediaTime::invalidTime()); EXPECT_EQ(MediaTime::positiveInfiniteTime() - MediaTime::negativeInfiniteTime(), MediaTime::positiveInfiniteTime()); EXPECT_EQ(MediaTime::negativeInfiniteTime() - MediaTime::positiveInfiniteTime(), MediaTime::negativeInfiniteTime()); + EXPECT_EQ(MediaTime::positiveInfiniteTime() - MediaTime(1, 1), MediaTime::positiveInfiniteTime()); + EXPECT_EQ(MediaTime(1, 1) - MediaTime::positiveInfiniteTime(), MediaTime::negativeInfiniteTime()); + EXPECT_EQ(MediaTime::negativeInfiniteTime() - MediaTime(1, 1), MediaTime::negativeInfiniteTime()); + EXPECT_EQ(MediaTime(1, 1) - MediaTime::negativeInfiniteTime(), MediaTime::positiveInfiniteTime()); EXPECT_EQ(MediaTime::invalidTime() - MediaTime::positiveInfiniteTime(), MediaTime::invalidTime()); EXPECT_EQ(MediaTime::invalidTime() - MediaTime::negativeInfiniteTime(), MediaTime::invalidTime()); EXPECT_EQ(MediaTime::invalidTime() - MediaTime::invalidTime(), MediaTime::invalidTime()); @@ -122,6 +128,23 @@ TEST(WTF, MediaTime) EXPECT_EQ(MediaTime(1, 2) - MediaTime(1, 3), MediaTime(1, 6)); EXPECT_EQ(MediaTime(2, numeric_limits<int32_t>::max()-1) - MediaTime(1, numeric_limits<int32_t>::max()-2), MediaTime(1, numeric_limits<int32_t>::max())); + // Multiplication Operators + EXPECT_EQ(MediaTime::positiveInfiniteTime(), MediaTime::positiveInfiniteTime() * 2); + EXPECT_EQ(MediaTime::negativeInfiniteTime(), MediaTime::negativeInfiniteTime() * 2); + EXPECT_EQ(MediaTime::negativeInfiniteTime(), MediaTime::positiveInfiniteTime() * -2); + EXPECT_EQ(MediaTime::positiveInfiniteTime(), MediaTime::negativeInfiniteTime() * -2); + EXPECT_EQ(MediaTime::invalidTime(), MediaTime::invalidTime() * 2); + EXPECT_EQ(MediaTime::invalidTime(), MediaTime::invalidTime() * -2); + EXPECT_EQ(MediaTime::indefiniteTime(), MediaTime::indefiniteTime() * 2); + EXPECT_EQ(MediaTime::indefiniteTime(), MediaTime::indefiniteTime() * -2); + EXPECT_EQ(MediaTime(6, 1), MediaTime(3, 1) * 2); + EXPECT_EQ(MediaTime(0, 1), MediaTime(0, 1) * 2); + EXPECT_EQ(MediaTime(int64_t(1) << 60, 1), MediaTime(int64_t(1) << 60, 2) * 2); + EXPECT_EQ(MediaTime::positiveInfiniteTime(), MediaTime(numeric_limits<int64_t>::max(), 1) * 2); + EXPECT_EQ(MediaTime::positiveInfiniteTime(), MediaTime(numeric_limits<int64_t>::min(), 1) * -2); + EXPECT_EQ(MediaTime::negativeInfiniteTime(), MediaTime(numeric_limits<int64_t>::max(), 1) * -2); + EXPECT_EQ(MediaTime::negativeInfiniteTime(), MediaTime(numeric_limits<int64_t>::min(), 1) * 2); + // Constants EXPECT_EQ(MediaTime::zeroTime(), MediaTime(0, 1)); EXPECT_EQ(MediaTime::invalidTime(), MediaTime(-1, 1, 0)); @@ -149,13 +172,29 @@ TEST(WTF, MediaTime) EXPECT_EQ(MediaTime(3, 2).toDouble(), 1.5); EXPECT_EQ(MediaTime(1, 1 << 16).toFloat(), 1 / pow(2.0f, 16.0f)); EXPECT_EQ(MediaTime(1, 1 << 30).toDouble(), 1 / pow(2.0, 30.0)); - EXPECT_EQ(MediaTime::createWithDouble(M_PI, 1 << 30), MediaTime(3373259426U, 1 << 30)); - EXPECT_EQ(MediaTime::createWithFloat(INFINITY), MediaTime::positiveInfiniteTime()); - EXPECT_EQ(MediaTime::createWithFloat(-INFINITY), MediaTime::negativeInfiniteTime()); - EXPECT_EQ(MediaTime::createWithFloat(NAN), MediaTime::invalidTime()); - EXPECT_EQ(MediaTime::createWithDouble(INFINITY), MediaTime::positiveInfiniteTime()); - EXPECT_EQ(MediaTime::createWithDouble(-INFINITY), MediaTime::negativeInfiniteTime()); - EXPECT_EQ(MediaTime::createWithDouble(NAN), MediaTime::invalidTime()); + EXPECT_EQ(MediaTime::createWithDouble(piDouble, 1 << 30), MediaTime(3373259426U, 1 << 30)); + + EXPECT_EQ(MediaTime::createWithFloat(std::numeric_limits<float>::infinity()), MediaTime::positiveInfiniteTime()); + EXPECT_EQ(MediaTime::createWithFloat(-std::numeric_limits<float>::infinity()), MediaTime::negativeInfiniteTime()); + EXPECT_EQ(MediaTime::createWithFloat(std::numeric_limits<float>::quiet_NaN()), MediaTime::invalidTime()); + + EXPECT_EQ(MediaTime::createWithDouble(std::numeric_limits<double>::infinity()), MediaTime::positiveInfiniteTime()); + EXPECT_EQ(MediaTime::createWithDouble(-std::numeric_limits<double>::infinity()), MediaTime::negativeInfiniteTime()); + EXPECT_EQ(MediaTime::createWithDouble(std::numeric_limits<double>::quiet_NaN()), MediaTime::invalidTime()); + + // Floating Point Round Trip + EXPECT_EQ(10.0123456789f, MediaTime::createWithFloat(10.0123456789f).toFloat()); + EXPECT_EQ(10.0123456789, MediaTime::createWithDouble(10.0123456789).toDouble()); + + // Floating Point Math + EXPECT_EQ(1.5 + 3.3, (MediaTime::createWithDouble(1.5) + MediaTime::createWithDouble(3.3)).toDouble()); + EXPECT_EQ(1.5 - 3.3, (MediaTime::createWithDouble(1.5) - MediaTime::createWithDouble(3.3)).toDouble()); + EXPECT_EQ(-3.3, (-MediaTime::createWithDouble(3.3)).toDouble()); + EXPECT_EQ(3.3 * 2, (MediaTime::createWithDouble(3.3) * 2).toDouble()); + + // Floating Point and non-Floating Point math + EXPECT_EQ(2.0, (MediaTime::createWithDouble(1.5) + MediaTime(1, 2)).toDouble()); + EXPECT_EQ(1.0, (MediaTime::createWithDouble(1.5) - MediaTime(1, 2)).toDouble()); // Overflow Behavior EXPECT_EQ(MediaTime::createWithFloat(pow(2.0f, 64.0f)), MediaTime::positiveInfiniteTime()); diff --git a/Tools/TestWebKitAPI/Tests/WTF/MetaAllocator.cpp b/Tools/TestWebKitAPI/Tests/WTF/MetaAllocator.cpp index 61c16d1ab..59af4f849 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/MetaAllocator.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/MetaAllocator.cpp @@ -10,7 +10,7 @@ * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -31,6 +31,10 @@ #include <wtf/MetaAllocator.h> #include <wtf/Vector.h> +#if OS(WINDOWS) +#undef small +#endif + using namespace WTF; namespace TestWebKitAPI { diff --git a/Tools/TestWebKitAPI/Tests/WTF/MoveOnly.h b/Tools/TestWebKitAPI/Tests/WTF/MoveOnly.h new file mode 100644 index 000000000..cecc49152 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/MoveOnly.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2013 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. + */ + +#ifndef MoveOnly_h +#define MoveOnly_h + +#include <wtf/HashFunctions.h> +#include <wtf/HashTraits.h> + +class MoveOnly { +public: + MoveOnly() + : m_value(0) + { + } + + MoveOnly(unsigned value) + : m_value(value) + { + } + + unsigned value() const + { + return m_value; + } + + MoveOnly(MoveOnly&& other) + : m_value(other.m_value) + { + other.m_value = 0; + } + + MoveOnly& operator=(MoveOnly&& other) + { + if (this == &other) + return *this; + + m_value = other.m_value; + other.m_value = 0; + return *this; + } + + friend bool operator==(const MoveOnly& a, const MoveOnly& b) + { + return a.m_value == b.m_value; + } + +private: + unsigned m_value; +}; + +namespace WTF { + +template<> struct HashTraits<MoveOnly> : public GenericHashTraits<MoveOnly> { + static void constructDeletedValue(MoveOnly& slot) { slot = MoveOnly(std::numeric_limits<unsigned>::max()); } + static bool isDeletedValue(const MoveOnly& slot) { return slot.value() == std::numeric_limits<unsigned>::max(); } +}; + +template<> struct DefaultHash<MoveOnly> { + struct Hash { + static unsigned hash(const MoveOnly& key) + { + return intHash(key.value()); + } + + static bool equal(const MoveOnly& a, const MoveOnly& b) + { + return a == b; + } + + static const bool safeToCompareToEmptyOrDeleted = true; + }; +}; +} // namespace WTF + +#endif // MoveOnly_h diff --git a/Tools/TestWebKitAPI/Tests/WTF/NakedPtr.cpp b/Tools/TestWebKitAPI/Tests/WTF/NakedPtr.cpp new file mode 100644 index 000000000..f4b4836cd --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/NakedPtr.cpp @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2015 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. ``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 + * 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 "RefLogger.h" +#include <wtf/NakedPtr.h> + +namespace TestWebKitAPI { + +// For these tests, we need a base class and a derived class. For this purpose, +// we reuse the RefLogger and DerivedRefLogger classes. + +TEST(WTF_NakedPtr, Basic) +{ + DerivedRefLogger a("a"); + + NakedPtr<RefLogger> empty; + ASSERT_EQ(nullptr, empty.get()); + + { + NakedPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ASSERT_EQ(&a, &*ptr); + ASSERT_EQ(&a.name, &ptr->name); + } + + { + NakedPtr<RefLogger> ptr = &a; + ASSERT_EQ(&a, ptr.get()); + } + + { + NakedPtr<RefLogger> p1 = &a; + NakedPtr<RefLogger> p2(p1); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + + { + NakedPtr<RefLogger> p1 = &a; + NakedPtr<RefLogger> p2 = p1; + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + + { + NakedPtr<RefLogger> p1 = &a; + NakedPtr<RefLogger> p2 = WTFMove(p1); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + + { + NakedPtr<RefLogger> p1 = &a; + NakedPtr<RefLogger> p2(WTFMove(p1)); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + + { + NakedPtr<DerivedRefLogger> p1 = &a; + NakedPtr<RefLogger> p2 = p1; + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + + { + NakedPtr<DerivedRefLogger> p1 = &a; + NakedPtr<RefLogger> p2 = WTFMove(p1); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + + { + NakedPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ptr.clear(); + ASSERT_EQ(nullptr, ptr.get()); + } +} + +TEST(WTF_NakedPtr, Assignment) +{ + DerivedRefLogger a("a"); + RefLogger b("b"); + DerivedRefLogger c("c"); + + { + NakedPtr<RefLogger> p1(&a); + NakedPtr<RefLogger> p2(&b); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&b, p2.get()); + p1 = p2; + ASSERT_EQ(&b, p1.get()); + ASSERT_EQ(&b, p2.get()); + } + + { + NakedPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ptr = &b; + ASSERT_EQ(&b, ptr.get()); + } + + { + NakedPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ptr = nullptr; + ASSERT_EQ(nullptr, ptr.get()); + } + + { + NakedPtr<RefLogger> p1(&a); + NakedPtr<RefLogger> p2(&b); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&b, p2.get()); + p1 = WTFMove(p2); + ASSERT_EQ(&b, p1.get()); + ASSERT_EQ(&b, p2.get()); + } + + { + NakedPtr<RefLogger> p1(&a); + NakedPtr<DerivedRefLogger> p2(&c); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&c, p2.get()); + p1 = p2; + ASSERT_EQ(&c, p1.get()); + ASSERT_EQ(&c, p2.get()); + } + + { + NakedPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ptr = &c; + ASSERT_EQ(&c, ptr.get()); + } + + { + NakedPtr<RefLogger> p1(&a); + NakedPtr<DerivedRefLogger> p2(&c); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&c, p2.get()); + p1 = WTFMove(p2); + ASSERT_EQ(&c, p1.get()); + ASSERT_EQ(&c, p2.get()); + } + + { + NakedPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ptr = ptr; + ASSERT_EQ(&a, ptr.get()); + } + + { + NakedPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); +#if COMPILER(CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wself-move" +#endif + ptr = WTFMove(ptr); +#if COMPILER(CLANG) +#pragma clang diagnostic pop +#endif + ASSERT_EQ(&a, ptr.get()); + } +} + +TEST(WTF_NakedPtr, Swap) +{ + RefLogger a("a"); + RefLogger b("b"); + + { + NakedPtr<RefLogger> p1(&a); + NakedPtr<RefLogger> p2(&b); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&b, p2.get()); + p1.swap(p2); + ASSERT_EQ(&b, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + + { + NakedPtr<RefLogger> p1(&a); + NakedPtr<RefLogger> p2(&b); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&b, p2.get()); + std::swap(p1, p2); + ASSERT_EQ(&b, p1.get()); + ASSERT_EQ(&a, p2.get()); + } +} + +NakedPtr<RefLogger> nakedPtrFoo(RefLogger& logger) +{ + return NakedPtr<RefLogger>(&logger); +} + +TEST(WTF_NakedPtr, ReturnValue) +{ + DerivedRefLogger a("a"); + + { + auto ptr = nakedPtrFoo(a); + ASSERT_EQ(&a, ptr.get()); + ASSERT_EQ(&a, &*ptr); + ASSERT_EQ(&a.name, &ptr->name); + } +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/OptionSet.cpp b/Tools/TestWebKitAPI/Tests/WTF/OptionSet.cpp new file mode 100644 index 000000000..37efc9939 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/OptionSet.cpp @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2016 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 "Test.h" +#include <wtf/OptionSet.h> + +namespace TestWebKitAPI { + +enum class ExampleFlags : uint64_t { + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, + D = 1ULL << 31, + E = 1ULL << 63, +}; + +TEST(WTF_OptionSet, EmptySet) +{ + OptionSet<ExampleFlags> set; + EXPECT_TRUE(set.isEmpty()); + EXPECT_FALSE(set.contains(ExampleFlags::A)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + EXPECT_FALSE(set.contains(ExampleFlags::C)); + EXPECT_FALSE(set.contains(ExampleFlags::D)); + EXPECT_FALSE(set.contains(ExampleFlags::E)); +} + +TEST(WTF_OptionSet, ContainsOneFlag) +{ + OptionSet<ExampleFlags> set = ExampleFlags::A; + EXPECT_FALSE(set.isEmpty()); + EXPECT_TRUE(set.contains(ExampleFlags::A)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + EXPECT_FALSE(set.contains(ExampleFlags::C)); + EXPECT_FALSE(set.contains(ExampleFlags::D)); + EXPECT_FALSE(set.contains(ExampleFlags::E)); +} + +TEST(WTF_OptionSet, ContainsTwoFlags) +{ + OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::B }; + EXPECT_FALSE(set.isEmpty()); + EXPECT_TRUE(set.contains(ExampleFlags::A)); + EXPECT_TRUE(set.contains(ExampleFlags::B)); + EXPECT_FALSE(set.contains(ExampleFlags::C)); + EXPECT_FALSE(set.contains(ExampleFlags::D)); + EXPECT_FALSE(set.contains(ExampleFlags::E)); +} + +TEST(WTF_OptionSet, ContainsTwoFlags2) +{ + OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::D }; + EXPECT_FALSE(set.isEmpty()); + EXPECT_TRUE(set.contains(ExampleFlags::A)); + EXPECT_TRUE(set.contains(ExampleFlags::D)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + EXPECT_FALSE(set.contains(ExampleFlags::C)); + EXPECT_FALSE(set.contains(ExampleFlags::E)); +} + +TEST(WTF_OptionSet, ContainsTwoFlags3) +{ + OptionSet<ExampleFlags> set { ExampleFlags::D, ExampleFlags::E }; + EXPECT_FALSE(set.isEmpty()); + EXPECT_TRUE(set.contains(ExampleFlags::D)); + EXPECT_TRUE(set.contains(ExampleFlags::E)); + EXPECT_FALSE(set.contains(ExampleFlags::A)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + EXPECT_FALSE(set.contains(ExampleFlags::C)); +} + +TEST(WTF_OptionSet, OperatorBitwiseOr) +{ + OptionSet<ExampleFlags> set = ExampleFlags::A; + set |= ExampleFlags::C; + EXPECT_TRUE(set.contains(ExampleFlags::A)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + EXPECT_TRUE(set.contains(ExampleFlags::C)); +} + +TEST(WTF_OptionSet, EmptyOptionSetToRawValueToOptionSet) +{ + OptionSet<ExampleFlags> set; + EXPECT_TRUE(set.isEmpty()); + EXPECT_FALSE(set.contains(ExampleFlags::A)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + EXPECT_FALSE(set.contains(ExampleFlags::C)); + + auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw()); + EXPECT_TRUE(set2.isEmpty()); + EXPECT_FALSE(set2.contains(ExampleFlags::A)); + EXPECT_FALSE(set2.contains(ExampleFlags::B)); + EXPECT_FALSE(set2.contains(ExampleFlags::C)); +} + +TEST(WTF_OptionSet, OptionSetThatContainsOneFlagToRawValueToOptionSet) +{ + OptionSet<ExampleFlags> set = ExampleFlags::A; + EXPECT_FALSE(set.isEmpty()); + EXPECT_TRUE(set.contains(ExampleFlags::A)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + EXPECT_FALSE(set.contains(ExampleFlags::C)); + EXPECT_FALSE(set.contains(ExampleFlags::D)); + EXPECT_FALSE(set.contains(ExampleFlags::E)); + + auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw()); + EXPECT_FALSE(set2.isEmpty()); + EXPECT_TRUE(set2.contains(ExampleFlags::A)); + EXPECT_FALSE(set2.contains(ExampleFlags::B)); + EXPECT_FALSE(set2.contains(ExampleFlags::C)); + EXPECT_FALSE(set2.contains(ExampleFlags::D)); + EXPECT_FALSE(set2.contains(ExampleFlags::E)); +} + +TEST(WTF_OptionSet, OptionSetThatContainsOneFlagToRawValueToOptionSet2) +{ + OptionSet<ExampleFlags> set = ExampleFlags::E; + EXPECT_FALSE(set.isEmpty()); + EXPECT_TRUE(set.contains(ExampleFlags::E)); + EXPECT_FALSE(set.contains(ExampleFlags::A)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + EXPECT_FALSE(set.contains(ExampleFlags::C)); + EXPECT_FALSE(set.contains(ExampleFlags::D)); + + auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw()); + EXPECT_FALSE(set2.isEmpty()); + EXPECT_TRUE(set2.contains(ExampleFlags::E)); + EXPECT_FALSE(set2.contains(ExampleFlags::A)); + EXPECT_FALSE(set2.contains(ExampleFlags::B)); + EXPECT_FALSE(set2.contains(ExampleFlags::C)); + EXPECT_FALSE(set2.contains(ExampleFlags::D)); +} + +TEST(WTF_OptionSet, OptionSetThatContainsTwoFlagsToRawValueToOptionSet) +{ + OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::C }; + EXPECT_FALSE(set.isEmpty()); + EXPECT_TRUE(set.contains(ExampleFlags::A)); + EXPECT_TRUE(set.contains(ExampleFlags::C)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + + auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw()); + EXPECT_FALSE(set2.isEmpty()); + EXPECT_TRUE(set2.contains(ExampleFlags::A)); + EXPECT_TRUE(set2.contains(ExampleFlags::C)); + EXPECT_FALSE(set2.contains(ExampleFlags::B)); +} + +TEST(WTF_OptionSet, OptionSetThatContainsTwoFlagsToRawValueToOptionSet2) +{ + OptionSet<ExampleFlags> set { ExampleFlags::D, ExampleFlags::E }; + EXPECT_FALSE(set.isEmpty()); + EXPECT_TRUE(set.contains(ExampleFlags::D)); + EXPECT_TRUE(set.contains(ExampleFlags::E)); + EXPECT_FALSE(set.contains(ExampleFlags::A)); + EXPECT_FALSE(set.contains(ExampleFlags::B)); + EXPECT_FALSE(set.contains(ExampleFlags::C)); + + auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw()); + EXPECT_FALSE(set2.isEmpty()); + EXPECT_TRUE(set2.contains(ExampleFlags::D)); + EXPECT_TRUE(set2.contains(ExampleFlags::E)); + EXPECT_FALSE(set2.contains(ExampleFlags::A)); + EXPECT_FALSE(set2.contains(ExampleFlags::B)); + EXPECT_FALSE(set2.contains(ExampleFlags::C)); +} + +TEST(WTF_OptionSet, TwoIteratorsIntoSameOptionSet) +{ + OptionSet<ExampleFlags> set { ExampleFlags::C, ExampleFlags::B }; + OptionSet<ExampleFlags>::iterator it1 = set.begin(); + OptionSet<ExampleFlags>::iterator it2 = it1; + ++it1; + EXPECT_STRONG_ENUM_EQ(ExampleFlags::C, *it1); + EXPECT_STRONG_ENUM_EQ(ExampleFlags::B, *it2); +} + +TEST(WTF_OptionSet, IterateOverOptionSetThatContainsTwoFlags) +{ + OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::C }; + OptionSet<ExampleFlags>::iterator it = set.begin(); + OptionSet<ExampleFlags>::iterator end = set.end(); + EXPECT_TRUE(it != end); + EXPECT_STRONG_ENUM_EQ(ExampleFlags::A, *it); + ++it; + EXPECT_STRONG_ENUM_EQ(ExampleFlags::C, *it); + ++it; + EXPECT_TRUE(it == end); +} + +TEST(WTF_OptionSet, IterateOverOptionSetThatContainsFlags2) +{ + OptionSet<ExampleFlags> set { ExampleFlags::D, ExampleFlags::E }; + OptionSet<ExampleFlags>::iterator it = set.begin(); + OptionSet<ExampleFlags>::iterator end = set.end(); + EXPECT_TRUE(it != end); + EXPECT_STRONG_ENUM_EQ(ExampleFlags::D, *it); + ++it; + EXPECT_STRONG_ENUM_EQ(ExampleFlags::E, *it); + ++it; + EXPECT_TRUE(it == end); +} + +TEST(WTF_OptionSet, NextItemAfterLargestIn32BitFlagSet) +{ + enum class ThirtyTwoBitFlags : uint32_t { + A = 1UL << 31, + }; + OptionSet<ThirtyTwoBitFlags> set { ThirtyTwoBitFlags::A }; + OptionSet<ThirtyTwoBitFlags>::iterator it = set.begin(); + OptionSet<ThirtyTwoBitFlags>::iterator end = set.end(); + EXPECT_TRUE(it != end); + ++it; + EXPECT_TRUE(it == end); +} + +TEST(WTF_OptionSet, NextItemAfterLargestIn64BitFlagSet) +{ + enum class SixtyFourBitFlags : uint64_t { + A = 1ULL << 63, + }; + OptionSet<SixtyFourBitFlags> set { SixtyFourBitFlags::A }; + OptionSet<SixtyFourBitFlags>::iterator it = set.begin(); + OptionSet<SixtyFourBitFlags>::iterator end = set.end(); + EXPECT_TRUE(it != end); + ++it; + EXPECT_TRUE(it == end); +} + +TEST(WTF_OptionSet, IterationOrderTheSameRegardlessOfInsertionOrder) +{ + OptionSet<ExampleFlags> set1 = ExampleFlags::C; + set1 |= ExampleFlags::A; + + OptionSet<ExampleFlags> set2 = ExampleFlags::A; + set2 |= ExampleFlags::C; + + OptionSet<ExampleFlags>::iterator it1 = set1.begin(); + OptionSet<ExampleFlags>::iterator it2 = set2.begin(); + + EXPECT_TRUE(*it1 == *it2); + ++it1; + ++it2; + EXPECT_TRUE(*it1 == *it2); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/Optional.cpp b/Tools/TestWebKitAPI/Tests/WTF/Optional.cpp new file mode 100644 index 000000000..a0715fd62 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/Optional.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2014 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/Optional.h> + +namespace TestWebKitAPI { + +TEST(WTF_Optional, Disengaged) +{ + { + Optional<int> optional; + + EXPECT_FALSE(static_cast<bool>(optional)); + } + + { + Optional<int> optional { Nullopt }; + + EXPECT_FALSE(static_cast<bool>(optional)); + } +} + +TEST(WTF_Optional, Engaged) +{ + Optional<int> optional { 10 }; + + EXPECT_TRUE(static_cast<bool>(optional)); + EXPECT_EQ(10, optional.value()); +} + +TEST(WTF_Optional, Destructor) +{ + static bool didCallDestructor = false; + struct A { + ~A() + { + EXPECT_FALSE(didCallDestructor); + didCallDestructor = true; + } + }; + + { + Optional<A> optional { InPlace }; + + EXPECT_TRUE(static_cast<bool>(optional)); + } + + EXPECT_TRUE(didCallDestructor); +} + +TEST(WTF_Optional, Callback) +{ + bool called = false; + Optional<int> a; + int result = a.valueOrCompute([&] { + called = true; + return 300; + }); + EXPECT_TRUE(called); + EXPECT_EQ(result, 300); + + a = 250; + called = false; + result = a.valueOrCompute([&] { + called = true; + return 300; + }); + EXPECT_FALSE(called); + EXPECT_EQ(result, 250); +} + +TEST(WTF_Optional, Equality) +{ + Optional<int> unengaged1; + Optional<int> unengaged2; + + Optional<int> engaged1 { 1 }; + Optional<int> engaged2 { 2 }; + Optional<int> engagedx2 { 2 }; + + EXPECT_TRUE(unengaged1 == unengaged2); + EXPECT_FALSE(engaged1 == engaged2); + EXPECT_FALSE(engaged1 == unengaged1); + EXPECT_TRUE(engaged2 == engagedx2); + + EXPECT_TRUE(unengaged1 == Nullopt); + EXPECT_FALSE(engaged1 == Nullopt); + EXPECT_TRUE(Nullopt == unengaged1); + EXPECT_FALSE(Nullopt == engaged1); + + EXPECT_TRUE(engaged1 == 1); + EXPECT_TRUE(1 == engaged1); + EXPECT_FALSE(unengaged1 == 1); + EXPECT_FALSE(1 == unengaged1); +} + +TEST(WTF_Optional, Inequality) +{ + Optional<int> unengaged1; + Optional<int> unengaged2; + + Optional<int> engaged1 { 1 }; + Optional<int> engaged2 { 2 }; + Optional<int> engagedx2 { 2 }; + + EXPECT_FALSE(unengaged1 != unengaged2); + EXPECT_TRUE(engaged1 != engaged2); + EXPECT_TRUE(engaged1 != unengaged1); + EXPECT_FALSE(engaged2 != engagedx2); + + EXPECT_FALSE(unengaged1 != Nullopt); + EXPECT_TRUE(engaged1 != Nullopt); + EXPECT_FALSE(Nullopt != unengaged1); + EXPECT_TRUE(Nullopt != engaged1); + + EXPECT_FALSE(engaged1 != 1); + EXPECT_TRUE(engaged1 != 2); + EXPECT_FALSE(1 != engaged1); + EXPECT_TRUE(2 != engaged1); + + EXPECT_TRUE(unengaged1 != 1); + EXPECT_TRUE(1 != unengaged1); +} + + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/ParkingLot.cpp b/Tools/TestWebKitAPI/Tests/WTF/ParkingLot.cpp new file mode 100644 index 000000000..b6a881fe0 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/ParkingLot.cpp @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2015 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 <condition_variable> +#include <mutex> +#include <thread> +#include <wtf/DataLog.h> +#include <wtf/HashSet.h> +#include <wtf/ListDump.h> +#include <wtf/ParkingLot.h> +#include <wtf/Threading.h> +#include <wtf/ThreadingPrimitives.h> + +using namespace WTF; + +namespace TestWebKitAPI { + +namespace { + +struct SingleLatchTest { + void initialize(unsigned numThreads) + { + // This implements a fair (FIFO) semaphore, and it starts out unavailable. + semaphore.store(0); + + for (unsigned i = numThreads; i--;) { + threads.append( + createThread( + "Parking Test Thread", + [&] () { + EXPECT_NE(0u, currentThread()); + + down(); + + std::lock_guard<std::mutex> locker(lock); + awake.add(currentThread()); + lastAwoken = currentThread(); + condition.notify_one(); + })); + } + } + + void unparkOne(unsigned singleUnparkIndex) + { + EXPECT_EQ(0u, lastAwoken); + + unsigned numWaitingOnAddress = 0; + Vector<ThreadIdentifier, 8> queue; + ParkingLot::forEach( + [&] (ThreadIdentifier threadIdentifier, const void* address) { + if (address != &semaphore) + return; + + queue.append(threadIdentifier); + + numWaitingOnAddress++; + }); + + EXPECT_LE(numWaitingOnAddress, threads.size() - singleUnparkIndex); + + up(); + + { + std::unique_lock<std::mutex> locker(lock); + while (awake.size() < singleUnparkIndex + 1) + condition.wait(locker); + EXPECT_NE(0u, lastAwoken); + if (!queue.isEmpty() && queue[0] != lastAwoken) { + dataLog("Woke up wrong thread: queue = ", listDump(queue), ", last awoken = ", lastAwoken, "\n"); + EXPECT_EQ(queue[0], lastAwoken); + } + lastAwoken = 0; + } + } + + void finish(unsigned numSingleUnparks) + { + unsigned numWaitingOnAddress = 0; + ParkingLot::forEach( + [&] (ThreadIdentifier, const void* address) { + if (address != &semaphore) + return; + + numWaitingOnAddress++; + }); + + EXPECT_LE(numWaitingOnAddress, threads.size() - numSingleUnparks); + + semaphore.store(threads.size() - numSingleUnparks); + ParkingLot::unparkAll(&semaphore); + + numWaitingOnAddress = 0; + ParkingLot::forEach( + [&] (ThreadIdentifier, const void* address) { + if (address != &semaphore) + return; + + numWaitingOnAddress++; + }); + + EXPECT_EQ(0u, numWaitingOnAddress); + + { + std::unique_lock<std::mutex> locker(lock); + while (awake.size() < threads.size()) + condition.wait(locker); + } + + for (ThreadIdentifier threadIdentifier : threads) + waitForThreadCompletion(threadIdentifier); + } + + // Semaphore operations. + void down() + { + for (;;) { + int oldSemaphoreValue = semaphore.load(); + int newSemaphoreValue = oldSemaphoreValue - 1; + if (!semaphore.compareExchangeWeak(oldSemaphoreValue, newSemaphoreValue)) + continue; + + if (oldSemaphoreValue > 0) { + // We acquired the semaphore. Done. + return; + } + + // We need to wait. + if (ParkingLot::compareAndPark(&semaphore, newSemaphoreValue)) { + // We did wait, and then got woken up. This means that someone who up'd the semaphore + // passed ownership onto us. + return; + } + + // We never parked, because the semaphore value changed. Undo our decrement and try again. + for (;;) { + int oldSemaphoreValue = semaphore.load(); + if (semaphore.compareExchangeWeak(oldSemaphoreValue, oldSemaphoreValue + 1)) + break; + } + } + } + void up() + { + int oldSemaphoreValue; + for (;;) { + oldSemaphoreValue = semaphore.load(); + if (semaphore.compareExchangeWeak(oldSemaphoreValue, oldSemaphoreValue + 1)) + break; + } + + // Check if anyone was waiting on the semaphore. If they were, then pass ownership to them. + if (oldSemaphoreValue < 0) + ParkingLot::unparkOne(&semaphore); + } + + Atomic<int> semaphore; + std::mutex lock; + std::condition_variable condition; + HashSet<ThreadIdentifier> awake; + Vector<ThreadIdentifier> threads; + ThreadIdentifier lastAwoken { 0 }; +}; + +void runParkingTest(unsigned numLatches, unsigned delay, unsigned numThreads, unsigned numSingleUnparks) +{ + std::unique_ptr<SingleLatchTest[]> tests = std::make_unique<SingleLatchTest[]>(numLatches); + + for (unsigned latchIndex = numLatches; latchIndex--;) + tests[latchIndex].initialize(numThreads); + + for (unsigned unparkIndex = 0; unparkIndex < numSingleUnparks; ++unparkIndex) { + std::this_thread::sleep_for(std::chrono::microseconds(delay)); + for (unsigned latchIndex = numLatches; latchIndex--;) + tests[latchIndex].unparkOne(unparkIndex); + } + + for (unsigned latchIndex = numLatches; latchIndex--;) + tests[latchIndex].finish(numSingleUnparks); +} + +void repeatParkingTest(unsigned numRepeats, unsigned numLatches, unsigned delay, unsigned numThreads, unsigned numSingleUnparks) +{ + while (numRepeats--) + runParkingTest(numLatches, delay, numThreads, numSingleUnparks); +} + +} // anonymous namespace + +TEST(WTF_ParkingLot, UnparkAllOneFast) +{ + repeatParkingTest(10000, 1, 0, 1, 0); +} + +TEST(WTF_ParkingLot, UnparkAllHundredFast) +{ + repeatParkingTest(100, 1, 0, 100, 0); +} + +TEST(WTF_ParkingLot, UnparkOneOneFast) +{ + repeatParkingTest(1000, 1, 0, 1, 1); +} + +TEST(WTF_ParkingLot, UnparkOneHundredFast) +{ + repeatParkingTest(20, 1, 0, 100, 100); +} + +TEST(WTF_ParkingLot, UnparkOneFiftyThenFiftyAllFast) +{ + repeatParkingTest(50, 1, 0, 100, 50); +} + +TEST(WTF_ParkingLot, UnparkAllOne) +{ + repeatParkingTest(100, 1, 10000, 1, 0); +} + +TEST(WTF_ParkingLot, UnparkAllHundred) +{ + repeatParkingTest(100, 1, 10000, 100, 0); +} + +TEST(WTF_ParkingLot, UnparkOneOne) +{ + repeatParkingTest(10, 1, 10000, 1, 1); +} + +TEST(WTF_ParkingLot, UnparkOneFifty) +{ + repeatParkingTest(1, 1, 10000, 50, 50); +} + +#if !PLATFORM(IOS) +TEST(WTF_ParkingLot, UnparkOneFiftyThenFiftyAll) +{ + repeatParkingTest(2, 1, 10000, 100, 50); +} +#endif + +TEST(WTF_ParkingLot, HundredUnparkAllOneFast) +{ + repeatParkingTest(100, 100, 0, 1, 0); +} + +TEST(WTF_ParkingLot, HundredUnparkAllOne) +{ + repeatParkingTest(1, 100, 10000, 1, 0); +} + +} // namespace TestWebKitAPI + diff --git a/Tools/TestWebKitAPI/Tests/WTF/RedBlackTree.cpp b/Tools/TestWebKitAPI/Tests/WTF/RedBlackTree.cpp index 1a1c9fdfc..5e5c8adc4 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/RedBlackTree.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/RedBlackTree.cpp @@ -10,7 +10,7 @@ * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * diff --git a/Tools/TestWebKitAPI/Tests/WTF/Ref.cpp b/Tools/TestWebKitAPI/Tests/WTF/Ref.cpp new file mode 100644 index 000000000..c35606e23 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/Ref.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2013 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 "RefLogger.h" +#include <wtf/Ref.h> +#include <wtf/RefPtr.h> + +namespace TestWebKitAPI { + +TEST(WTF_Ref, Basic) +{ + DerivedRefLogger a("a"); + + { + Ref<RefLogger> ptr(a); + ASSERT_EQ(&a, ptr.ptr()); + ASSERT_EQ(&a.name, &ptr->name); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + Ref<RefLogger> ptr(adoptRef(a)); + ASSERT_EQ(&a, ptr.ptr()); + ASSERT_EQ(&a.name, &ptr->name); + } + ASSERT_STREQ("deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_Ref, Assignment) +{ + DerivedRefLogger a("a"); + RefLogger b("b"); + DerivedRefLogger c("c"); + + { + Ref<RefLogger> ptr(a); + ASSERT_EQ(&a, ptr.ptr()); + log() << "| "; + ptr = b; + ASSERT_EQ(&b, ptr.ptr()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | ref(b) deref(a) | deref(b) ", takeLogStr().c_str()); + + { + Ref<RefLogger> ptr(a); + ASSERT_EQ(&a, ptr.ptr()); + log() << "| "; + ptr = c; + ASSERT_EQ(&c, ptr.ptr()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | ref(c) deref(a) | deref(c) ", takeLogStr().c_str()); + + { + Ref<RefLogger> ptr(a); + ASSERT_EQ(&a, ptr.ptr()); + log() << "| "; + ptr = adoptRef(b); + ASSERT_EQ(&b, ptr.ptr()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | deref(a) | deref(b) ", takeLogStr().c_str()); + + { + Ref<RefLogger> ptr(a); + ASSERT_EQ(&a, ptr.ptr()); + log() << "| "; + ptr = adoptRef(c); + ASSERT_EQ(&c, ptr.ptr()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | deref(a) | deref(c) ", takeLogStr().c_str()); +} + +static Ref<RefLogger> passWithRef(Ref<RefLogger>&& reference) +{ + return WTFMove(reference); +} + +static RefPtr<RefLogger> passWithPassRefPtr(PassRefPtr<RefLogger> reference) +{ + return reference; +} + +TEST(WTF_Ref, ReturnValue) +{ + DerivedRefLogger a("a"); + RefLogger b("b"); + DerivedRefLogger c("c"); + + { + Ref<RefLogger> ptr(passWithRef(Ref<RefLogger>(a))); + ASSERT_EQ(&a, ptr.ptr()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + Ref<RefLogger> ptr(a); + ASSERT_EQ(&a, ptr.ptr()); + log() << "| "; + ptr = passWithRef(b); + ASSERT_EQ(&b, ptr.ptr()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | ref(b) deref(a) | deref(b) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(passWithRef(a)); + ASSERT_EQ(&a, ptr.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(passWithPassRefPtr(passWithRef(a))); + ASSERT_EQ(&a, ptr.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<DerivedRefLogger> ptr(&a); + RefPtr<RefLogger> ptr2(WTFMove(ptr)); + ASSERT_EQ(nullptr, ptr.get()); + ASSERT_EQ(&a, ptr2.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + Ref<DerivedRefLogger> derivedReference(a); + Ref<RefLogger> baseReference(passWithRef(derivedReference.copyRef())); + ASSERT_EQ(&a, derivedReference.ptr()); + ASSERT_EQ(&a, baseReference.ptr()); + } + ASSERT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str()); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp b/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp new file mode 100644 index 000000000..f8771e0c2 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp @@ -0,0 +1,158 @@ +/* + * 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 CallbackExpected = 0xC0FFEE; +static const int CallbackNotExpected = 0xDECAF; + +enum CounterType { }; +typedef RefCounter::Token<CounterType> 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. + RefCounter* counterPtr = nullptr; + RefCounter counter([&](bool value) { + // Check that the callback is called at the expected times, and the correct number of times. + EXPECT_EQ(callbackValue, CallbackExpected); + // Value provided should be equal to the counter value. + EXPECT_EQ(value, counterPtr->value()); + // return the value of the counter in the callback. + callbackValue = 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 = CallbackExpected; + TokenType incTo1(counter.token<CounterType>()); + // Testing (4b) & (4c) - values within & after callback. + EXPECT_EQ(true, callbackValue); + EXPECT_EQ(1, static_cast<int>(counter.value())); + + // Testing (3b) - ref with callback from 1 -> 2. + TokenType incTo2(incTo1); + // Testing (4b) & (4c) - values within & after callback. + EXPECT_EQ(2, static_cast<int>(counter.value())); + + // Testing (3c) - deref with callback from >1 -> 1. + incTo1 = nullptr; + // Testing (4b) & (4c) - values within & after callback. + EXPECT_EQ(1, static_cast<int>(counter.value())); + + { + // Testing (3j) - ref using a Ref rather than a RefPtr. + TokenType incTo2Again(counter.token<CounterType>()); + // Testing (4b) & (4c) - values within & after callback. + EXPECT_EQ(2, static_cast<int>(counter.value())); + // Testing (3k) - deref using a Ref rather than a RefPtr. + } + EXPECT_EQ(1, static_cast<int>(counter.value())); + // Testing (4b) & (4c) - values within & after callback. + + // Testing (3d) - deref with callback from 1 -> 0. + callbackValue = CallbackExpected; + 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 RefCounter::Count has a non-zero reference count. + callbackValue = CallbackExpected; + incTo1Again = counter.token<CounterType>(); + 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. + RefCounter counter; + // Testing (4a) - after construction value() is 0. + EXPECT_EQ(0, static_cast<int>(counter.value())); + // Testing (3h) - ref without callback + TokenType incTo1(counter.token<CounterType>()); + // 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 diff --git a/Tools/TestWebKitAPI/ios/mainIOS.mm b/Tools/TestWebKitAPI/Tests/WTF/RefLogger.h index 3eec9b005..c5cfb071f 100644 --- a/Tools/TestWebKitAPI/ios/mainIOS.mm +++ b/Tools/TestWebKitAPI/Tests/WTF/RefLogger.h @@ -23,16 +23,34 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#import "config.h" -#import "TestsController.h" +#ifndef RefLogger_h -int main(int argc, char** argv) +namespace TestWebKitAPI { + +inline std::ostringstream& log() +{ + static std::ostringstream log; + return log; +} + +inline std::string takeLogStr() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + std::string string = log().str(); + log().str(""); + return string; +} - bool passed = TestWebKitAPI::TestsController::shared().run(argc, argv); +struct RefLogger { + RefLogger(const char* name) : name(*name) { } + void ref() { log() << "ref(" << &name << ") "; } + void deref() { log() << "deref(" << &name << ") "; } + const char& name; +}; - [pool drain]; +struct DerivedRefLogger : RefLogger { + DerivedRefLogger(const char* name) : RefLogger(name) { log().str(""); } +}; - return passed ? EXIT_SUCCESS : EXIT_FAILURE; } + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WTF/RefPtr.cpp b/Tools/TestWebKitAPI/Tests/WTF/RefPtr.cpp new file mode 100644 index 000000000..aebe98c48 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/RefPtr.cpp @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2013 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 "RefLogger.h" +#include <wtf/RefPtr.h> + +namespace TestWebKitAPI { + +TEST(WTF_RefPtr, Basic) +{ + DerivedRefLogger a("a"); + + RefPtr<RefLogger> empty; + ASSERT_EQ(nullptr, empty.get()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ASSERT_EQ(&a, &*ptr); + ASSERT_EQ(&a.name, &ptr->name); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr = &a; + ASSERT_EQ(&a, ptr.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1 = &a; + RefPtr<RefLogger> p2(p1); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + ASSERT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1 = &a; + RefPtr<RefLogger> p2 = p1; + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + ASSERT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1 = &a; + RefPtr<RefLogger> p2 = WTFMove(p1); + ASSERT_EQ(nullptr, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1 = &a; + RefPtr<RefLogger> p2(WTFMove(p1)); + ASSERT_EQ(nullptr, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<DerivedRefLogger> p1 = &a; + RefPtr<RefLogger> p2 = p1; + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + ASSERT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<DerivedRefLogger> p1 = &a; + RefPtr<RefLogger> p2 = WTFMove(p1); + ASSERT_EQ(nullptr, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ptr = nullptr; + ASSERT_EQ(nullptr, ptr.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ptr.release(); + ASSERT_EQ(nullptr, ptr.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_RefPtr, AssignPassRefToRefPtr) +{ + DerivedRefLogger a("a"); + { + Ref<RefLogger> passRef(a); + RefPtr<RefLogger> ptr = WTFMove(passRef); + ASSERT_EQ(&a, ptr.get()); + ptr.release(); + ASSERT_EQ(nullptr, ptr.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_RefPtr, Adopt) +{ + DerivedRefLogger a("a"); + + RefPtr<RefLogger> empty; + ASSERT_EQ(nullptr, empty.get()); + + { + RefPtr<RefLogger> ptr(adoptRef(&a)); + ASSERT_EQ(&a, ptr.get()); + ASSERT_EQ(&a, &*ptr); + ASSERT_EQ(&a.name, &ptr->name); + } + ASSERT_STREQ("deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr = adoptRef(&a); + ASSERT_EQ(&a, ptr.get()); + } + ASSERT_STREQ("deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_RefPtr, Assignment) +{ + DerivedRefLogger a("a"); + RefLogger b("b"); + DerivedRefLogger c("c"); + + { + RefPtr<RefLogger> p1(&a); + RefPtr<RefLogger> p2(&b); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&b, p2.get()); + log() << "| "; + p1 = p2; + ASSERT_EQ(&b, p1.get()); + ASSERT_EQ(&b, p2.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) ref(b) | ref(b) deref(a) | deref(b) deref(b) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + log() << "| "; + ptr = &b; + ASSERT_EQ(&b, ptr.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | ref(b) deref(a) | deref(b) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + log() << "| "; + ptr = adoptRef(&b); + ASSERT_EQ(&b, ptr.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | deref(a) | deref(b) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + ptr = nullptr; + ASSERT_EQ(nullptr, ptr.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1(&a); + RefPtr<RefLogger> p2(&b); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&b, p2.get()); + log() << "| "; + p1 = WTFMove(p2); + ASSERT_EQ(&b, p1.get()); + ASSERT_EQ(nullptr, p2.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) ref(b) | deref(a) | deref(b) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1(&a); + RefPtr<DerivedRefLogger> p2(&c); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&c, p2.get()); + log() << "| "; + p1 = p2; + ASSERT_EQ(&c, p1.get()); + ASSERT_EQ(&c, p2.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) ref(c) | ref(c) deref(a) | deref(c) deref(c) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + log() << "| "; + ptr = &c; + ASSERT_EQ(&c, ptr.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | ref(c) deref(a) | deref(c) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + log() << "| "; + ptr = adoptRef(&c); + ASSERT_EQ(&c, ptr.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | deref(a) | deref(c) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1(&a); + RefPtr<DerivedRefLogger> p2(&c); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&c, p2.get()); + log() << "| "; + p1 = WTFMove(p2); + ASSERT_EQ(&c, p1.get()); + ASSERT_EQ(nullptr, p2.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) ref(c) | deref(a) | deref(c) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); + log() << "| "; + ptr = ptr; + ASSERT_EQ(&a, ptr.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) | ref(a) deref(a) | deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> ptr(&a); + ASSERT_EQ(&a, ptr.get()); +#if COMPILER(CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wself-move" +#endif + ptr = WTFMove(ptr); +#if COMPILER(CLANG) +#pragma clang diagnostic pop +#endif + ASSERT_EQ(&a, ptr.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_RefPtr, Swap) +{ + RefLogger a("a"); + RefLogger b("b"); + + { + RefPtr<RefLogger> p1(&a); + RefPtr<RefLogger> p2(&b); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&b, p2.get()); + p1.swap(p2); + ASSERT_EQ(&b, p1.get()); + ASSERT_EQ(&a, p2.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) ref(b) | deref(a) deref(b) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1(&a); + RefPtr<RefLogger> p2(&b); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&b, p2.get()); + std::swap(p1, p2); + ASSERT_EQ(&b, p1.get()); + ASSERT_EQ(&a, p2.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) ref(b) | deref(a) deref(b) ", takeLogStr().c_str()); +} + +TEST(WTF_RefPtr, ReleaseNonNull) +{ + RefLogger a("a"); + + { + RefPtr<RefLogger> refPtr = &a; + RefPtr<RefLogger> ref = refPtr.releaseNonNull(); + } + + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +TEST(WTF_RefPtr, Release) +{ + DerivedRefLogger a("a"); + RefLogger b("b"); + DerivedRefLogger c("c"); + + { + RefPtr<RefLogger> p1 = &a; + RefPtr<RefLogger> p2 = p1.release(); + ASSERT_EQ(nullptr, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1 = &a; + RefPtr<RefLogger> p2(p1.release()); + ASSERT_EQ(nullptr, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<DerivedRefLogger> p1 = &a; + RefPtr<RefLogger> p2 = p1.release(); + ASSERT_EQ(nullptr, p1.get()); + ASSERT_EQ(&a, p2.get()); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1(&a); + RefPtr<RefLogger> p2(&b); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&b, p2.get()); + log() << "| "; + p1 = p2.release(); + ASSERT_EQ(&b, p1.get()); + ASSERT_EQ(nullptr, p2.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) ref(b) | deref(a) | deref(b) ", takeLogStr().c_str()); + + { + RefPtr<RefLogger> p1(&a); + RefPtr<DerivedRefLogger> p2(&c); + ASSERT_EQ(&a, p1.get()); + ASSERT_EQ(&c, p2.get()); + log() << "| "; + p1 = p2.release(); + ASSERT_EQ(&c, p1.get()); + ASSERT_EQ(nullptr, p2.get()); + log() << "| "; + } + ASSERT_STREQ("ref(a) ref(c) | deref(a) | deref(c) ", takeLogStr().c_str()); +} + +RefPtr<RefLogger> f1(RefLogger& logger) +{ + return RefPtr<RefLogger>(&logger); +} + +TEST(WTF_RefPtr, ReturnValue) +{ + DerivedRefLogger a("a"); + + { + f1(a); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); + + { + auto ptr = f1(a); + } + ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str()); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/win/WMPrint.cpp b/Tools/TestWebKitAPI/Tests/WTF/RunLoop.cpp index 36a18ca41..e7e3d9f99 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/win/WMPrint.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/RunLoop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,22 +24,34 @@ */ #include "config.h" + #include "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <wtf/RunLoop.h> namespace TestWebKitAPI { -TEST(WebKit2, WMPrint) +static bool testFinished; +static int count = 100; + +TEST(WTF_RunLoop, Deadlock) { - WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - PlatformWebView webView(context.get()); - - HWND window = WKViewGetWindow(webView.platformView()); - HDC dc = ::CreateCompatibleDC(0); - // FIXME: It would be nice to test that this actually paints the view into dc. - ::SendMessage(window, WM_PRINT, reinterpret_cast<WPARAM>(dc), PRF_CLIENT | PRF_CHILDREN); - ::DeleteDC(dc); + RunLoop::initializeMainRunLoop(); + + struct DispatchFromDestructorTester { + ~DispatchFromDestructorTester() { + RunLoop::main().dispatch([] { + if (!(--count)) + testFinished = true; + }); + } + }; + + for (int i = 0; i < count; ++i) { + auto capture = std::make_shared<DispatchFromDestructorTester>(); + RunLoop::main().dispatch([capture] { }); + } + + Util::run(&testFinished); } } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/StringBuilder.cpp b/Tools/TestWebKitAPI/Tests/WTF/StringBuilder.cpp index d1b5b43bd..11bf3590e 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/StringBuilder.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/StringBuilder.cpp @@ -38,14 +38,17 @@ static void expectBuilderContent(const String& expected, const StringBuilder& bu { // Not using builder.toString() or builder.toStringPreserveCapacity() because they all // change internal state of builder. - EXPECT_EQ(expected, String(builder.characters(), builder.length())); + if (builder.is8Bit()) + EXPECT_EQ(expected, String(builder.characters8(), builder.length())); + else + EXPECT_EQ(expected, String(builder.characters16(), builder.length())); } void expectEmpty(const StringBuilder& builder) { EXPECT_EQ(0U, builder.length()); EXPECT_TRUE(builder.isEmpty()); - EXPECT_EQ(0, builder.characters()); + EXPECT_EQ(0, builder.characters8()); } TEST(StringBuilderTest, DefaultConstructor) @@ -72,20 +75,20 @@ TEST(StringBuilderTest, Append) StringBuilder builder1; builder.append("", 0); expectBuilderContent("0123456789abcdefg#", builder); - builder1.append(builder.characters(), builder.length()); + builder1.append(builder.characters8(), builder.length()); builder1.append("XYZ"); - builder.append(builder1.characters(), builder1.length()); + builder.append(builder1.characters8(), builder1.length()); expectBuilderContent("0123456789abcdefg#0123456789abcdefg#XYZ", builder); StringBuilder builder2; builder2.reserveCapacity(100); builder2.append("xyz"); - const UChar* characters = builder2.characters(); + const LChar* characters = builder2.characters8(); builder2.append("0123456789"); - ASSERT_EQ(characters, builder2.characters()); + ASSERT_EQ(characters, builder2.characters8()); builder2.toStringPreserveCapacity(); // Test after reifyString with buffer preserved. builder2.append("abcd"); - ASSERT_EQ(characters, builder2.characters()); + ASSERT_EQ(characters, builder2.characters8()); // Test appending UChar32 characters to StringBuilder. StringBuilder builderForUChar32Append; @@ -140,7 +143,7 @@ TEST(StringBuilderTest, ToStringPreserveCapacity) ASSERT_EQ(capacity, builder.capacity()); ASSERT_EQ(String("0123456789"), string); ASSERT_EQ(string.impl(), builder.toStringPreserveCapacity().impl()); - ASSERT_EQ(string.characters(), builder.characters()); + ASSERT_EQ(string.characters8(), builder.characters8()); // Changing the StringBuilder should not affect the original result of toStringPreserveCapacity(). builder.append("abcdefghijklmnopqrstuvwxyz"); @@ -151,7 +154,7 @@ TEST(StringBuilderTest, ToStringPreserveCapacity) capacity = builder.capacity(); string = builder.toStringPreserveCapacity(); ASSERT_EQ(capacity, builder.capacity()); - ASSERT_EQ(string.characters(), builder.characters()); + ASSERT_EQ(string.characters8(), builder.characters8()); ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyz"), string); builder.append("ABC"); ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyz"), string); @@ -160,7 +163,7 @@ TEST(StringBuilderTest, ToStringPreserveCapacity) capacity = builder.capacity(); String string1 = builder.toStringPreserveCapacity(); ASSERT_EQ(capacity, builder.capacity()); - ASSERT_EQ(string1.characters(), builder.characters()); + ASSERT_EQ(string1.characters8(), builder.characters8()); ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyzABC"), string1); string1.append("DEF"); ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyzABC"), builder.toStringPreserveCapacity()); @@ -170,7 +173,7 @@ TEST(StringBuilderTest, ToStringPreserveCapacity) capacity = builder.capacity(); string1 = builder.toStringPreserveCapacity(); ASSERT_EQ(capacity, builder.capacity()); - ASSERT_EQ(string.characters(), builder.characters()); + ASSERT_EQ(string.characters8(), builder.characters8()); builder.resize(10); builder.append("###"); ASSERT_EQ(String("0123456789abcdefghijklmnopqrstuvwxyzABC"), string1); diff --git a/Tools/TestWebKitAPI/Tests/WTF/StringHasher.cpp b/Tools/TestWebKitAPI/Tests/WTF/StringHasher.cpp index a4d223c99..739a8190e 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/StringHasher.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/StringHasher.cpp @@ -25,7 +25,7 @@ #include "config.h" -#include <wtf/StringHasher.h> +#include <wtf/Hasher.h> namespace TestWebKitAPI { diff --git a/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp b/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp index 35d64844c..01f36f7b6 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp @@ -25,7 +25,7 @@ #include "config.h" -#include <wtf/text/StringImpl.h> +#include <wtf/text/SymbolImpl.h> #include <wtf/text/WTFString.h> namespace TestWebKitAPI { @@ -37,7 +37,6 @@ TEST(WTF, StringImplCreationFromLiteral) ASSERT_EQ(strlen("Template Literal"), stringWithTemplate->length()); ASSERT_TRUE(equal(stringWithTemplate.get(), "Template Literal")); ASSERT_TRUE(stringWithTemplate->is8Bit()); - ASSERT_TRUE(stringWithTemplate->hasTerminatingNullCharacter()); // Constructor taking the size explicitely. const char* programmaticStringData = "Explicit Size Literal"; @@ -46,7 +45,6 @@ TEST(WTF, StringImplCreationFromLiteral) ASSERT_TRUE(equal(programmaticString.get(), programmaticStringData)); ASSERT_EQ(programmaticStringData, reinterpret_cast<const char*>(programmaticString->characters8())); ASSERT_TRUE(programmaticString->is8Bit()); - ASSERT_TRUE(programmaticString->hasTerminatingNullCharacter()); // Constructor without explicit size. const char* stringWithoutLengthLiteral = "No Size Literal"; @@ -55,18 +53,6 @@ TEST(WTF, StringImplCreationFromLiteral) ASSERT_TRUE(equal(programmaticStringNoLength.get(), stringWithoutLengthLiteral)); ASSERT_EQ(stringWithoutLengthLiteral, reinterpret_cast<const char*>(programmaticStringNoLength->characters8())); ASSERT_TRUE(programmaticStringNoLength->is8Bit()); - ASSERT_TRUE(programmaticStringNoLength->hasTerminatingNullCharacter()); -} - -TEST(WTF, StringImplFromLiteralLoop16BitConversion) -{ - RefPtr<StringImpl> controlString = StringImpl::create("Template Literal"); - for (size_t i = 0; i < 10; ++i) { - RefPtr<StringImpl> string = StringImpl::createFromLiteral("Template Literal"); - - ASSERT_EQ(0, memcmp(controlString->characters(), string->characters(), controlString->length() * sizeof(UChar))); - ASSERT_TRUE(string->has16BitShadow()); - } } TEST(WTF, StringImplReplaceWithLiteral) @@ -113,4 +99,451 @@ TEST(WTF, StringImplReplaceWithLiteral) ASSERT_TRUE(equal(testStringImpl.get(), "r555sum555")); } +TEST(WTF, StringImplEqualIgnoringASCIICaseBasic) +{ + RefPtr<StringImpl> a = StringImpl::createFromLiteral("aBcDeFG"); + RefPtr<StringImpl> b = StringImpl::createFromLiteral("ABCDEFG"); + RefPtr<StringImpl> c = StringImpl::createFromLiteral("abcdefg"); + const char d[] = "aBcDeFG"; + RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>("")); + RefPtr<StringImpl> shorter = StringImpl::createFromLiteral("abcdef"); + RefPtr<StringImpl> different = StringImpl::createFromLiteral("abcrefg"); + + // Identity. + ASSERT_TRUE(equalIgnoringASCIICase(a.get(), a.get())); + ASSERT_TRUE(equalIgnoringASCIICase(b.get(), b.get())); + ASSERT_TRUE(equalIgnoringASCIICase(c.get(), c.get())); + ASSERT_TRUE(equalIgnoringASCIICase(a.get(), d)); + ASSERT_TRUE(equalIgnoringASCIICase(b.get(), d)); + ASSERT_TRUE(equalIgnoringASCIICase(c.get(), d)); + + // Transitivity. + ASSERT_TRUE(equalIgnoringASCIICase(a.get(), b.get())); + ASSERT_TRUE(equalIgnoringASCIICase(b.get(), c.get())); + ASSERT_TRUE(equalIgnoringASCIICase(a.get(), c.get())); + + // Negative cases. + ASSERT_FALSE(equalIgnoringASCIICase(a.get(), empty.get())); + ASSERT_FALSE(equalIgnoringASCIICase(b.get(), empty.get())); + ASSERT_FALSE(equalIgnoringASCIICase(c.get(), empty.get())); + ASSERT_FALSE(equalIgnoringASCIICase(a.get(), shorter.get())); + ASSERT_FALSE(equalIgnoringASCIICase(b.get(), shorter.get())); + ASSERT_FALSE(equalIgnoringASCIICase(c.get(), shorter.get())); + ASSERT_FALSE(equalIgnoringASCIICase(a.get(), different.get())); + ASSERT_FALSE(equalIgnoringASCIICase(b.get(), different.get())); + ASSERT_FALSE(equalIgnoringASCIICase(c.get(), different.get())); + ASSERT_FALSE(equalIgnoringASCIICase(empty.get(), d)); + ASSERT_FALSE(equalIgnoringASCIICase(shorter.get(), d)); + ASSERT_FALSE(equalIgnoringASCIICase(different.get(), d)); +} + +TEST(WTF, StringImplEqualIgnoringASCIICaseWithNull) +{ + RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG"); + StringImpl* nullStringImpl = nullptr; + ASSERT_FALSE(equalIgnoringASCIICase(nullStringImpl, reference.get())); + ASSERT_FALSE(equalIgnoringASCIICase(reference.get(), nullStringImpl)); + ASSERT_TRUE(equalIgnoringASCIICase(nullStringImpl, nullStringImpl)); +} + +TEST(WTF, StringImplEqualIgnoringASCIICaseWithEmpty) +{ + RefPtr<StringImpl> a = StringImpl::create(reinterpret_cast<const LChar*>("")); + RefPtr<StringImpl> b = StringImpl::create(reinterpret_cast<const LChar*>("")); + ASSERT_TRUE(equalIgnoringASCIICase(a.get(), b.get())); + ASSERT_TRUE(equalIgnoringASCIICase(b.get(), a.get())); +} + +static RefPtr<StringImpl> stringFromUTF8(const char* characters) +{ + return String::fromUTF8(characters).impl(); +} + +TEST(WTF, StringImplEqualIgnoringASCIICaseWithLatin1Characters) +{ + RefPtr<StringImpl> a = stringFromUTF8("aBcéeFG"); + RefPtr<StringImpl> b = stringFromUTF8("ABCÉEFG"); + RefPtr<StringImpl> c = stringFromUTF8("ABCéEFG"); + RefPtr<StringImpl> d = stringFromUTF8("abcéefg"); + const char e[] = "aBcéeFG"; + + // Identity. + ASSERT_TRUE(equalIgnoringASCIICase(a.get(), a.get())); + ASSERT_TRUE(equalIgnoringASCIICase(b.get(), b.get())); + ASSERT_TRUE(equalIgnoringASCIICase(c.get(), c.get())); + ASSERT_TRUE(equalIgnoringASCIICase(d.get(), d.get())); + + // All combination. + ASSERT_FALSE(equalIgnoringASCIICase(a.get(), b.get())); + ASSERT_TRUE(equalIgnoringASCIICase(a.get(), c.get())); + ASSERT_TRUE(equalIgnoringASCIICase(a.get(), d.get())); + ASSERT_FALSE(equalIgnoringASCIICase(b.get(), c.get())); + ASSERT_FALSE(equalIgnoringASCIICase(b.get(), d.get())); + ASSERT_TRUE(equalIgnoringASCIICase(c.get(), d.get())); + ASSERT_FALSE(equalIgnoringASCIICase(a.get(), e)); + ASSERT_FALSE(equalIgnoringASCIICase(b.get(), e)); + ASSERT_FALSE(equalIgnoringASCIICase(c.get(), e)); + ASSERT_FALSE(equalIgnoringASCIICase(d.get(), e)); +} + +TEST(WTF, StringImplFindIgnoringASCIICaseBasic) +{ + RefPtr<StringImpl> referenceA = stringFromUTF8("aBcéeFG"); + RefPtr<StringImpl> referenceB = stringFromUTF8("ABCÉEFG"); + + // Search the exact string. + EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(referenceA.get())); + EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(referenceB.get())); + + // A and B are distinct by the non-ascii character é/É. + EXPECT_EQ(static_cast<size_t>(notFound), referenceA->findIgnoringASCIICase(referenceB.get())); + EXPECT_EQ(static_cast<size_t>(notFound), referenceB->findIgnoringASCIICase(referenceA.get())); + + // Find the prefix. + EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("a").get())); + EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(stringFromUTF8("abcé").get())); + EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("A").get())); + EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(stringFromUTF8("ABCé").get())); + EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("a").get())); + EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(stringFromUTF8("abcÉ").get())); + EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("A").get())); + EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get())); + + // Not a prefix. + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("x").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("accé").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("abcÉ").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("X").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("ABDé").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("y").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("accÉ").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("abcé").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("Y").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("ABdÉ").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("ABCé").get())); + + // Find the infix. + EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("cée").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("ée").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("cé").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("c").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("é").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("Cée").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("éE").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("Cé").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("C").get())); + + EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("cÉe").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("Ée").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("cÉ").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("c").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("É").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("CÉe").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("ÉE").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("CÉ").get())); + EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("C").get())); + + // Not an infix. + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("céd").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("Ée").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("bé").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("x").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("É").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("CÉe").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("éd").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("CÉ").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("Y").get())); + + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("cée").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("Éc").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("cé").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("W").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("é").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("bÉe").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("éE").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("BÉ").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("z").get())); + + // Find the suffix. + EXPECT_EQ(static_cast<size_t>(6), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("g").get())); + EXPECT_EQ(static_cast<size_t>(4), referenceA->findIgnoringASCIICase(stringFromUTF8("efg").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("éefg").get())); + EXPECT_EQ(static_cast<size_t>(6), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("G").get())); + EXPECT_EQ(static_cast<size_t>(4), referenceA->findIgnoringASCIICase(stringFromUTF8("EFG").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("éEFG").get())); + + EXPECT_EQ(static_cast<size_t>(6), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("g").get())); + EXPECT_EQ(static_cast<size_t>(4), referenceB->findIgnoringASCIICase(stringFromUTF8("efg").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("Éefg").get())); + EXPECT_EQ(static_cast<size_t>(6), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("G").get())); + EXPECT_EQ(static_cast<size_t>(4), referenceB->findIgnoringASCIICase(stringFromUTF8("EFG").get())); + EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("ÉEFG").get())); + + // Not a suffix. + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("X").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("edg").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("Éefg").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("w").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("dFG").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("ÉEFG").get())); + + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("Z").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("ffg").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("éefg").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("r").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("EgG").get())); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("éEFG").get())); +} + +TEST(WTF, StringImplFindIgnoringASCIICaseWithValidOffset) +{ + RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFGaBcéeFG"); + EXPECT_EQ(static_cast<size_t>(0), reference->findIgnoringASCIICase(stringFromUTF8("ABC").get(), 0)); + EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(stringFromUTF8("ABC").get(), 1)); + EXPECT_EQ(static_cast<size_t>(0), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), 0)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), 1)); + EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(stringFromUTF8("ABCé").get(), 0)); + EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(stringFromUTF8("ABCé").get(), 1)); +} + +TEST(WTF, StringImplFindIgnoringASCIICaseWithInvalidOffset) +{ + RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFGaBcéeFG"); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABC").get(), 15)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABC").get(), 16)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), 17)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), 42)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), std::numeric_limits<unsigned>::max())); +} + +TEST(WTF, StringImplFindIgnoringASCIICaseOnNull) +{ + RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFG"); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 0)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 3)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 7)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 8)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 42)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, std::numeric_limits<unsigned>::max())); +} + +TEST(WTF, StringImplFindIgnoringASCIICaseOnEmpty) +{ + RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFG"); + RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>("")); + EXPECT_EQ(static_cast<size_t>(0), reference->findIgnoringASCIICase(empty.get())); + EXPECT_EQ(static_cast<size_t>(0), reference->findIgnoringASCIICase(empty.get(), 0)); + EXPECT_EQ(static_cast<size_t>(3), reference->findIgnoringASCIICase(empty.get(), 3)); + EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(empty.get(), 7)); + EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(empty.get(), 8)); + EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(empty.get(), 42)); + EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(empty.get(), std::numeric_limits<unsigned>::max())); +} + +TEST(WTF, StringImplFindIgnoringASCIICaseWithPatternLongerThanReference) +{ + RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFG"); + RefPtr<StringImpl> pattern = stringFromUTF8("XABCÉEFG"); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(pattern.get())); + EXPECT_EQ(static_cast<size_t>(1), pattern->findIgnoringASCIICase(reference.get())); +} + +TEST(WTF, StringImplStartsWithIgnoringASCIICaseBasic) +{ + RefPtr<StringImpl> reference = stringFromUTF8("aBcéX"); + RefPtr<StringImpl> referenceEquivalent = stringFromUTF8("AbCéx"); + + // Identity. + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(reference.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*reference.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(referenceEquivalent.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*referenceEquivalent.get())); + ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(reference.get())); + ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(*reference.get())); + ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(referenceEquivalent.get())); + ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(*referenceEquivalent.get())); + + // Proper prefixes. + RefPtr<StringImpl> aLower = StringImpl::createFromLiteral("a"); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(aLower.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*aLower.get())); + RefPtr<StringImpl> aUpper = StringImpl::createFromLiteral("A"); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(aUpper.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*aUpper.get())); + + RefPtr<StringImpl> abcLower = StringImpl::createFromLiteral("abc"); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcLower.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcLower.get())); + RefPtr<StringImpl> abcUpper = StringImpl::createFromLiteral("ABC"); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcUpper.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcUpper.get())); + + RefPtr<StringImpl> abcAccentLower = stringFromUTF8("abcé"); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcAccentLower.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcAccentLower.get())); + RefPtr<StringImpl> abcAccentUpper = stringFromUTF8("ABCé"); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcAccentUpper.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcAccentUpper.get())); + + // Negative cases. + RefPtr<StringImpl> differentFirstChar = stringFromUTF8("bBcéX"); + RefPtr<StringImpl> differentFirstCharProperPrefix = stringFromUTF8("CBcé"); + ASSERT_FALSE(reference->startsWithIgnoringASCIICase(differentFirstChar.get())); + ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*differentFirstChar.get())); + ASSERT_FALSE(reference->startsWithIgnoringASCIICase(differentFirstCharProperPrefix.get())); + ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*differentFirstCharProperPrefix.get())); + + RefPtr<StringImpl> uppercaseAccent = stringFromUTF8("aBcÉX"); + RefPtr<StringImpl> uppercaseAccentProperPrefix = stringFromUTF8("aBcÉX"); + ASSERT_FALSE(reference->startsWithIgnoringASCIICase(uppercaseAccent.get())); + ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*uppercaseAccent.get())); + ASSERT_FALSE(reference->startsWithIgnoringASCIICase(uppercaseAccentProperPrefix.get())); + ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*uppercaseAccentProperPrefix.get())); +} + +TEST(WTF, StringImplStartsWithIgnoringASCIICaseWithNull) +{ + RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG"); + ASSERT_FALSE(reference->startsWithIgnoringASCIICase(nullptr)); + + RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>("")); + ASSERT_FALSE(empty->startsWithIgnoringASCIICase(nullptr)); +} + +TEST(WTF, StringImplStartsWithIgnoringASCIICaseWithEmpty) +{ + RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG"); + RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>("")); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(empty.get())); + ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*empty.get())); + ASSERT_TRUE(empty->startsWithIgnoringASCIICase(empty.get())); + ASSERT_TRUE(empty->startsWithIgnoringASCIICase(*empty.get())); + ASSERT_FALSE(empty->startsWithIgnoringASCIICase(reference.get())); + ASSERT_FALSE(empty->startsWithIgnoringASCIICase(*reference.get())); +} + +TEST(WTF, StringImplEndsWithIgnoringASCIICaseBasic) +{ + RefPtr<StringImpl> reference = stringFromUTF8("XÉCbA"); + RefPtr<StringImpl> referenceEquivalent = stringFromUTF8("xÉcBa"); + + // Identity. + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(reference.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*reference.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(referenceEquivalent.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*referenceEquivalent.get())); + ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(reference.get())); + ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(*reference.get())); + ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(referenceEquivalent.get())); + ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(*referenceEquivalent.get())); + + // Proper suffixes. + RefPtr<StringImpl> aLower = StringImpl::createFromLiteral("a"); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(aLower.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*aLower.get())); + RefPtr<StringImpl> aUpper = StringImpl::createFromLiteral("a"); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(aUpper.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*aUpper.get())); + + RefPtr<StringImpl> abcLower = StringImpl::createFromLiteral("cba"); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcLower.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcLower.get())); + RefPtr<StringImpl> abcUpper = StringImpl::createFromLiteral("CBA"); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcUpper.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcUpper.get())); + + RefPtr<StringImpl> abcAccentLower = stringFromUTF8("Écba"); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcAccentLower.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcAccentLower.get())); + RefPtr<StringImpl> abcAccentUpper = stringFromUTF8("ÉCBA"); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcAccentUpper.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcAccentUpper.get())); + + // Negative cases. + RefPtr<StringImpl> differentLastChar = stringFromUTF8("XÉCbB"); + RefPtr<StringImpl> differentLastCharProperSuffix = stringFromUTF8("ÉCbb"); + ASSERT_FALSE(reference->endsWithIgnoringASCIICase(differentLastChar.get())); + ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*differentLastChar.get())); + ASSERT_FALSE(reference->endsWithIgnoringASCIICase(differentLastCharProperSuffix.get())); + ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*differentLastCharProperSuffix.get())); + + RefPtr<StringImpl> lowercaseAccent = stringFromUTF8("aBcéX"); + RefPtr<StringImpl> loweraseAccentProperSuffix = stringFromUTF8("aBcéX"); + ASSERT_FALSE(reference->endsWithIgnoringASCIICase(lowercaseAccent.get())); + ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*lowercaseAccent.get())); + ASSERT_FALSE(reference->endsWithIgnoringASCIICase(loweraseAccentProperSuffix.get())); + ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*loweraseAccentProperSuffix.get())); +} + +TEST(WTF, StringImplEndsWithIgnoringASCIICaseWithNull) +{ + RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG"); + ASSERT_FALSE(reference->endsWithIgnoringASCIICase(nullptr)); + + RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>("")); + ASSERT_FALSE(empty->endsWithIgnoringASCIICase(nullptr)); +} + +TEST(WTF, StringImplEndsWithIgnoringASCIICaseWithEmpty) +{ + RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG"); + RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>("")); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(empty.get())); + ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*empty.get())); + ASSERT_TRUE(empty->endsWithIgnoringASCIICase(empty.get())); + ASSERT_TRUE(empty->endsWithIgnoringASCIICase(*empty.get())); + ASSERT_FALSE(empty->endsWithIgnoringASCIICase(reference.get())); + ASSERT_FALSE(empty->endsWithIgnoringASCIICase(*reference.get())); +} + +TEST(WTF, StringImplCreateSymbolEmpty) +{ + RefPtr<StringImpl> reference = StringImpl::createSymbolEmpty(); + ASSERT_TRUE(reference->isSymbol()); + ASSERT_FALSE(reference->isAtomic()); + ASSERT_EQ(0u, reference->length()); + ASSERT_TRUE(equal(reference.get(), "")); +} + +TEST(WTF, StringImplCreateSymbol) +{ + RefPtr<StringImpl> original = stringFromUTF8("original"); + RefPtr<StringImpl> reference = StringImpl::createSymbol(original); + ASSERT_TRUE(reference->isSymbol()); + ASSERT_FALSE(reference->isAtomic()); + ASSERT_FALSE(original->isSymbol()); + ASSERT_FALSE(original->isAtomic()); + ASSERT_EQ(original->length(), reference->length()); + ASSERT_TRUE(equal(reference.get(), "original")); +} + +TEST(WTF, StringImplSymbolToAtomicString) +{ + RefPtr<StringImpl> original = stringFromUTF8("original"); + RefPtr<StringImpl> reference = StringImpl::createSymbol(original); + ASSERT_TRUE(reference->isSymbol()); + ASSERT_FALSE(reference->isAtomic()); + + RefPtr<StringImpl> atomic = AtomicStringImpl::add(reference.get()); + ASSERT_TRUE(atomic->isAtomic()); + ASSERT_FALSE(atomic->isSymbol()); + ASSERT_TRUE(reference->isSymbol()); + ASSERT_FALSE(reference->isAtomic()); +} + +TEST(WTF, StringImplSymbolEmptyToAtomicString) +{ + RefPtr<StringImpl> reference = StringImpl::createSymbolEmpty(); + ASSERT_TRUE(reference->isSymbol()); + ASSERT_FALSE(reference->isAtomic()); + + RefPtr<StringImpl> atomic = AtomicStringImpl::add(reference.get()); + ASSERT_TRUE(atomic->isAtomic()); + ASSERT_FALSE(atomic->isSymbol()); + ASSERT_TRUE(reference->isSymbol()); + ASSERT_FALSE(reference->isAtomic()); +} + } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/StringOperators.cpp b/Tools/TestWebKitAPI/Tests/WTF/StringOperators.cpp index 149b85b21..7a1d9297f 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/StringOperators.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/StringOperators.cpp @@ -184,4 +184,20 @@ TEST(WTF, StringOperators) #endif } +TEST(WTF, ConcatenateCharacterArrayAndEmptyString) +{ + String emptyString; + EXPECT_EQ(static_cast<unsigned>(0), emptyString.length()); + + UChar ucharArray[] = { 't', 'e', 's', 't', '\0' }; + String concatenation16 = ucharArray + emptyString; + ASSERT_EQ(static_cast<unsigned>(4), concatenation16.length()); + ASSERT_TRUE(concatenation16 == String(ucharArray)); + + LChar lcharArray[] = { 't', 'e', 's', 't', '\0' }; + String concatenation8 = lcharArray + emptyString; + ASSERT_EQ(static_cast<unsigned>(4), concatenation8.length()); + ASSERT_TRUE(concatenation8 == String(lcharArray)); +} + } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/StringView.cpp b/Tools/TestWebKitAPI/Tests/WTF/StringView.cpp new file mode 100644 index 000000000..408cc642e --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/StringView.cpp @@ -0,0 +1,736 @@ +/* + * Copyright (C) 2014 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/text/StringBuilder.h> +#include <wtf/text/StringView.h> + +namespace TestWebKitAPI { + +TEST(WTF, StringViewEmptyVsNull) +{ + StringView nullView; + EXPECT_TRUE(nullView.isNull()); + EXPECT_TRUE(nullView.isEmpty()); + + // Test in a boolean context to test operator bool(). + if (nullView) + FAIL(); + else + SUCCEED(); + + if (!nullView) + SUCCEED(); + else + FAIL(); + + StringView emptyView = StringView::empty(); + EXPECT_FALSE(emptyView.isNull()); + EXPECT_TRUE(emptyView.isEmpty()); + + // Test in a boolean context to test operator bool(). + if (emptyView) + SUCCEED(); + else + FAIL(); + + if (!emptyView) + FAIL(); + else + SUCCEED(); + + StringView viewWithCharacters(String("hello")); + EXPECT_FALSE(viewWithCharacters.isNull()); + EXPECT_FALSE(viewWithCharacters.isEmpty()); + + // Test in a boolean context to test operator bool(). + if (viewWithCharacters) + SUCCEED(); + else + FAIL(); + + if (!viewWithCharacters) + FAIL(); + else + SUCCEED(); +} + +bool compareLoopIterations(StringView::CodePoints codePoints, std::vector<UChar32> expected) +{ + std::vector<UChar32> actual; + for (auto codePoint : codePoints) + actual.push_back(codePoint); + return actual == expected; +} + +static bool compareLoopIterations(StringView::CodeUnits codeUnits, std::vector<UChar> expected) +{ + std::vector<UChar> actual; + for (auto codeUnit : codeUnits) + actual.push_back(codeUnit); + return actual == expected; +} + +static void build(StringBuilder& builder, std::vector<UChar> input) +{ + builder.clear(); + for (auto codeUnit : input) + builder.append(codeUnit); +} + +TEST(WTF, StringViewIterators) +{ + compareLoopIterations(StringView().codePoints(), { }); + compareLoopIterations(StringView().codeUnits(), { }); + + compareLoopIterations(StringView::empty().codePoints(), { }); + compareLoopIterations(StringView::empty().codeUnits(), { }); + + compareLoopIterations(StringView(String("hello")).codePoints(), {'h', 'e', 'l', 'l', 'o'}); + compareLoopIterations(StringView(String("hello")).codeUnits(), {'h', 'e', 'l', 'l', 'o'}); + + StringBuilder b; + build(b, {0xD800, 0xDD55}); // Surrogates for unicode code point U+10155 + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x10155})); + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800, 0xDD55})); + + build(b, {0xD800}); // Leading surrogate only + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xD800})); + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800})); + + build(b, {0xD800, 0xD801}); // Two leading surrogates + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xD800, 0xD801})); + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800, 0xD801})); + + build(b, {0xDD55}); // Trailing surrogate only + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xDD55})); + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xDD55})); + + build(b, {0xD800, 'h'}); // Leading surrogate followed by non-surrogate + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xD800, 'h'})); + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800, 'h'})); + + build(b, {0x0306}); // "COMBINING BREVE" + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x0306})); + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0x0306})); + + build(b, {0x0306, 0xD800, 0xDD55, 'h', 'e', 'l', 'o'}); // Mix of single code unit and multi code unit code points + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x0306, 0x10155, 'h', 'e', 'l', 'o'})); + EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0x0306, 0xD800, 0xDD55, 'h', 'e', 'l', 'o'})); +} + +TEST(WTF, StringViewEqualIgnoringASCIICaseBasic) +{ + RefPtr<StringImpl> a = StringImpl::createFromLiteral("aBcDeFG"); + RefPtr<StringImpl> b = StringImpl::createFromLiteral("ABCDEFG"); + RefPtr<StringImpl> c = StringImpl::createFromLiteral("abcdefg"); + const char d[] = "aBcDeFG"; + RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>("")); + RefPtr<StringImpl> shorter = StringImpl::createFromLiteral("abcdef"); + RefPtr<StringImpl> different = StringImpl::createFromLiteral("abcrefg"); + + StringView stringViewA(*a.get()); + StringView stringViewB(*b.get()); + StringView stringViewC(*c.get()); + StringView emptyStringView(*empty.get()); + StringView shorterStringView(*shorter.get()); + StringView differentStringView(*different.get()); + + ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewB)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewC)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewC)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, d)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, d)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewC, d)); + + // Identity. + ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewA)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewB)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewC, stringViewC)); + + // Transitivity. + ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewB)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewC)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewC)); + + // Negative cases. + ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, emptyStringView)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, emptyStringView)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewC, emptyStringView)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, shorterStringView)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, shorterStringView)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewC, shorterStringView)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, differentStringView)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, differentStringView)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewC, differentStringView)); + ASSERT_FALSE(equalIgnoringASCIICase(emptyStringView, d)); + ASSERT_FALSE(equalIgnoringASCIICase(shorterStringView, d)); + ASSERT_FALSE(equalIgnoringASCIICase(differentStringView, d)); +} + +TEST(WTF, StringViewEqualIgnoringASCIICaseWithEmpty) +{ + RefPtr<StringImpl> a = StringImpl::create(reinterpret_cast<const LChar*>("")); + RefPtr<StringImpl> b = StringImpl::create(reinterpret_cast<const LChar*>("")); + StringView stringViewA(*a.get()); + StringView stringViewB(*b.get()); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewB)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewA)); +} + +TEST(WTF, StringViewEqualIgnoringASCIICaseWithLatin1Characters) +{ + RefPtr<StringImpl> a = StringImpl::create(reinterpret_cast<const LChar*>("aBcéeFG")); + RefPtr<StringImpl> b = StringImpl::create(reinterpret_cast<const LChar*>("ABCÉEFG")); + RefPtr<StringImpl> c = StringImpl::create(reinterpret_cast<const LChar*>("ABCéEFG")); + RefPtr<StringImpl> d = StringImpl::create(reinterpret_cast<const LChar*>("abcéefg")); + const char e[] = "aBcéeFG"; + StringView stringViewA(*a.get()); + StringView stringViewB(*b.get()); + StringView stringViewC(*c.get()); + StringView stringViewD(*d.get()); + + // Identity. + ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewA)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewB)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewC, stringViewC)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewD, stringViewD)); + + // All combination. + ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, stringViewB)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewC)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewD)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, stringViewC)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, stringViewD)); + ASSERT_TRUE(equalIgnoringASCIICase(stringViewC, stringViewD)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, e)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, e)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewC, e)); + ASSERT_FALSE(equalIgnoringASCIICase(stringViewD, e)); +} + +StringView stringViewFromLiteral(const char* characters) +{ + return StringView(reinterpret_cast<const LChar*>(characters), strlen(characters)); +} + +StringView stringViewFromUTF8(String &ref, const char* characters) +{ + ref = String::fromUTF8(characters); + return ref; +} + +TEST(WTF, StringViewFindIgnoringASCIICaseBasic) +{ + String referenceAHolder; + StringView referenceA = stringViewFromUTF8(referenceAHolder, "aBcéeFG"); + String referenceBHolder; + StringView referenceB = stringViewFromUTF8(referenceBHolder, "ABCÉEFG"); + + // Search the exact string. + EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(referenceA)); + EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(referenceB)); + + // A and B are distinct by the non-ascii character é/É. + EXPECT_EQ(static_cast<size_t>(notFound), referenceA.findIgnoringASCIICase(referenceB)); + EXPECT_EQ(static_cast<size_t>(notFound), referenceB.findIgnoringASCIICase(referenceA)); + + String tempStringHolder; + // Find the prefix. + EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(stringViewFromLiteral("a"))); + EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "abcé"))); + EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(stringViewFromLiteral("A"))); + EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCé"))); + EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(stringViewFromLiteral("a"))); + EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "abcÉ"))); + EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(stringViewFromLiteral("A"))); + EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ"))); + + // Not a prefix. + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromLiteral("x"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "accé"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "abcÉ"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromLiteral("X"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABDé"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromLiteral("y"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "accÉ"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "abcé"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromLiteral("Y"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABdÉ"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCé"))); + + // Find the infix. + EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cée"))); + EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ée"))); + EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cé"))); + EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "c"))); + EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "é"))); + EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Cée"))); + EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éE"))); + EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Cé"))); + EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "C"))); + + EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cÉe"))); + EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Ée"))); + EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cÉ"))); + EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "c"))); + EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "É"))); + EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "CÉe"))); + EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ÉE"))); + EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "CÉ"))); + EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "C"))); + + // Not an infix. + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "céd"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Ée"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "bé"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "x"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "É"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "CÉe"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éd"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "CÉ"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Y"))); + + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cée"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Éc"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cé"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "W"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "é"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "bÉe"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éE"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "BÉ"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "z"))); + + // Find the suffix. + EXPECT_EQ(static_cast<size_t>(6), referenceA.findIgnoringASCIICase(stringViewFromLiteral("g"))); + EXPECT_EQ(static_cast<size_t>(4), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "efg"))); + EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éefg"))); + EXPECT_EQ(static_cast<size_t>(6), referenceA.findIgnoringASCIICase(stringViewFromLiteral("G"))); + EXPECT_EQ(static_cast<size_t>(4), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "EFG"))); + EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éEFG"))); + + EXPECT_EQ(static_cast<size_t>(6), referenceB.findIgnoringASCIICase(stringViewFromLiteral("g"))); + EXPECT_EQ(static_cast<size_t>(4), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "efg"))); + EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Éefg"))); + EXPECT_EQ(static_cast<size_t>(6), referenceB.findIgnoringASCIICase(stringViewFromLiteral("G"))); + EXPECT_EQ(static_cast<size_t>(4), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "EFG"))); + EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ÉEFG"))); + + // Not a suffix. + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromLiteral("X"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "edg"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Éefg"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromLiteral("w"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "dFG"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ÉEFG"))); + + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromLiteral("Z"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ffg"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éefg"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromLiteral("r"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "EgG"))); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éEFG"))); +} + +TEST(WTF, StringViewFindIgnoringASCIICaseWithValidOffset) +{ + String referenceHolder; + StringView reference = stringViewFromUTF8(referenceHolder, "ABCÉEFGaBcéeFG"); + String tempStringHolder; + + EXPECT_EQ(static_cast<size_t>(0), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABC"), 0)); + EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABC"), 1)); + EXPECT_EQ(static_cast<size_t>(0), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ"), 0)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ"), 1)); + EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCé"), 0)); + EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCé"), 1)); +} + +TEST(WTF, StringViewFindIgnoringASCIICaseWithInvalidOffset) +{ + String referenceHolder; + StringView reference = stringViewFromUTF8(referenceHolder, "ABCÉEFGaBcéeFG"); + String tempStringHolder; + + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABC"), 15)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABC"), 16)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ"), 17)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ"), 42)); + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ"), std::numeric_limits<unsigned>::max())); +} + +TEST(WTF, StringViewFindIgnoringASCIICaseOnEmpty) +{ + String referenceHolder; + StringView reference = stringViewFromUTF8(referenceHolder, "ABCÉEFG"); + StringView empty = stringViewFromLiteral(""); + EXPECT_EQ(static_cast<size_t>(0), reference.findIgnoringASCIICase(empty)); + EXPECT_EQ(static_cast<size_t>(0), reference.findIgnoringASCIICase(empty, 0)); + EXPECT_EQ(static_cast<size_t>(3), reference.findIgnoringASCIICase(empty, 3)); + EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(empty, 7)); + EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(empty, 8)); + EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(empty, 42)); + EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(empty, std::numeric_limits<unsigned>::max())); +} + +TEST(WTF, StringViewFindIgnoringASCIICaseWithPatternLongerThanReference) +{ + String referenceHolder; + StringView reference = stringViewFromUTF8(referenceHolder, "ABCÉEFG"); + String patternHolder; + StringView pattern = stringViewFromUTF8(patternHolder, "ABCÉEFGA"); + + EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(pattern)); + EXPECT_EQ(static_cast<size_t>(0), pattern.findIgnoringASCIICase(reference)); +} + +TEST(WTF, StringViewStartsWithBasic) +{ + StringView reference = stringViewFromLiteral("abcdefg"); + String referenceUTF8Ref; + StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "à îûèô"); + + StringView oneLetterPrefix = stringViewFromLiteral("a"); + StringView shortPrefix = stringViewFromLiteral("abc"); + StringView longPrefix = stringViewFromLiteral("abcdef"); + StringView upperCasePrefix = stringViewFromLiteral("ABC"); + StringView empty = stringViewFromLiteral(""); + StringView notPrefix = stringViewFromLiteral("bc"); + + String oneLetterPrefixUTF8Ref; + StringView oneLetterPrefixUTF8 = stringViewFromUTF8(oneLetterPrefixUTF8Ref, "à "); + String shortPrefixUTF8Ref; + StringView shortPrefixUTF8 = stringViewFromUTF8(shortPrefixUTF8Ref, "à î"); + String longPrefixUTF8Ref; + StringView longPrefixUTF8 = stringViewFromUTF8(longPrefixUTF8Ref, "à îûè"); + String upperCasePrefixUTF8Ref; + StringView upperCasePrefixUTF8 = stringViewFromUTF8(upperCasePrefixUTF8Ref, "ÀÎ"); + String notPrefixUTF8Ref; + StringView notPrefixUTF8 = stringViewFromUTF8(notPrefixUTF8Ref, "îû"); + + EXPECT_TRUE(reference.startsWith(reference)); + EXPECT_TRUE(reference.startsWith(oneLetterPrefix)); + EXPECT_TRUE(reference.startsWith(shortPrefix)); + EXPECT_TRUE(reference.startsWith(longPrefix)); + EXPECT_TRUE(reference.startsWith(empty)); + + EXPECT_TRUE(referenceUTF8.startsWith(referenceUTF8)); + EXPECT_TRUE(referenceUTF8.startsWith(oneLetterPrefixUTF8)); + EXPECT_TRUE(referenceUTF8.startsWith(shortPrefixUTF8)); + EXPECT_TRUE(referenceUTF8.startsWith(longPrefixUTF8)); + EXPECT_TRUE(referenceUTF8.startsWith(empty)); + + EXPECT_FALSE(reference.startsWith(notPrefix)); + EXPECT_FALSE(reference.startsWith(upperCasePrefix)); + EXPECT_FALSE(reference.startsWith(notPrefixUTF8)); + EXPECT_FALSE(reference.startsWith(upperCasePrefixUTF8)); + EXPECT_FALSE(referenceUTF8.startsWith(notPrefix)); + EXPECT_FALSE(referenceUTF8.startsWith(upperCasePrefix)); + EXPECT_FALSE(referenceUTF8.startsWith(notPrefixUTF8)); + EXPECT_FALSE(referenceUTF8.startsWith(upperCasePrefixUTF8)); +} + +TEST(WTF, StringViewStartsWithEmpty) +{ + StringView a = stringViewFromLiteral(""); + String refB; + StringView b = stringViewFromUTF8(refB, ""); + + EXPECT_TRUE(a.startsWith(a)); + EXPECT_TRUE(a.startsWith(b)); + EXPECT_TRUE(b.startsWith(a)); + EXPECT_TRUE(b.startsWith(b)); +} + +TEST(WTF, StringViewStartsWithIgnoringASCIICaseBasic) +{ + StringView reference = stringViewFromLiteral("abcdefg"); + + String referenceUTF8Ref; + StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "à îûèô"); + + StringView oneLetterPrefix = stringViewFromLiteral("a"); + StringView shortPrefix = stringViewFromLiteral("abc"); + StringView longPrefix = stringViewFromLiteral("abcdef"); + StringView upperCasePrefix = stringViewFromLiteral("ABC"); + StringView mixedCasePrefix = stringViewFromLiteral("aBcDe"); + StringView empty = stringViewFromLiteral(""); + StringView notPrefix = stringViewFromLiteral("bc"); + + String oneLetterPrefixUTF8Ref; + StringView oneLetterPrefixUTF8 = stringViewFromUTF8(oneLetterPrefixUTF8Ref, "à "); + String shortPrefixUTF8Ref; + StringView shortPrefixUTF8 = stringViewFromUTF8(shortPrefixUTF8Ref, "à î"); + String longPrefixUTF8Ref; + StringView longPrefixUTF8 = stringViewFromUTF8(longPrefixUTF8Ref, "à îûè"); + String upperCasePrefixUTF8Ref; + StringView upperCasePrefixUTF8 = stringViewFromUTF8(upperCasePrefixUTF8Ref, "ÀÎ"); + String notPrefixUTF8Ref; + StringView notPrefixUTF8 = stringViewFromUTF8(notPrefixUTF8Ref, "îû"); + + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(reference)); + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(oneLetterPrefix)); + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(shortPrefix)); + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(longPrefix)); + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(empty)); + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(upperCasePrefix)); + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(mixedCasePrefix)); + + EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(referenceUTF8)); + EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(oneLetterPrefixUTF8)); + EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(shortPrefixUTF8)); + EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(longPrefixUTF8)); + EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(empty)); + + EXPECT_FALSE(reference.startsWithIgnoringASCIICase(notPrefix)); + EXPECT_FALSE(reference.startsWithIgnoringASCIICase(notPrefixUTF8)); + EXPECT_FALSE(reference.startsWithIgnoringASCIICase(upperCasePrefixUTF8)); + EXPECT_FALSE(referenceUTF8.startsWithIgnoringASCIICase(notPrefix)); + EXPECT_FALSE(referenceUTF8.startsWithIgnoringASCIICase(notPrefixUTF8)); + EXPECT_FALSE(referenceUTF8.startsWithIgnoringASCIICase(upperCasePrefix)); + EXPECT_FALSE(referenceUTF8.startsWithIgnoringASCIICase(upperCasePrefixUTF8)); +} + + +TEST(WTF, StringViewStartsWithIgnoringASCIICaseEmpty) +{ + StringView a = stringViewFromLiteral(""); + String refB; + StringView b = stringViewFromUTF8(refB, ""); + + EXPECT_TRUE(a.startsWithIgnoringASCIICase(a)); + EXPECT_TRUE(a.startsWithIgnoringASCIICase(b)); + EXPECT_TRUE(b.startsWithIgnoringASCIICase(a)); + EXPECT_TRUE(b.startsWithIgnoringASCIICase(b)); +} + +TEST(WTF, StringViewStartsWithIgnoringASCIICaseWithLatin1Characters) +{ + StringView reference = stringViewFromLiteral("aBcéeFG"); + String referenceUTF8Ref; + StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "aBcéeFG"); + + StringView a = stringViewFromLiteral("aBcéeF"); + StringView b = stringViewFromLiteral("ABCéEF"); + StringView c = stringViewFromLiteral("abcéef"); + StringView d = stringViewFromLiteral("Abcéef"); + + String refE; + StringView e = stringViewFromUTF8(refE, "aBcéeF"); + String refF; + StringView f = stringViewFromUTF8(refF, "ABCéEF"); + String refG; + StringView g = stringViewFromUTF8(refG, "abcéef"); + String refH; + StringView h = stringViewFromUTF8(refH, "Abcéef"); + + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(a)); + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(b)); + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(c)); + EXPECT_TRUE(reference.startsWithIgnoringASCIICase(d)); + + EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(e)); + EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(f)); + EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(g)); + EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(h)); + + EXPECT_FALSE(reference.endsWithIgnoringASCIICase(referenceUTF8)); + EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(reference)); +} + +TEST(WTF, StringViewEndsWithBasic) +{ + StringView reference = stringViewFromLiteral("abcdefg"); + String referenceUTF8Ref; + StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "à îûèô"); + + StringView oneLetterSuffix = stringViewFromLiteral("g"); + StringView shortSuffix = stringViewFromLiteral("efg"); + StringView longSuffix = stringViewFromLiteral("cdefg"); + StringView upperCaseSuffix = stringViewFromLiteral("EFG"); + StringView empty = stringViewFromLiteral(""); + StringView notSuffix = stringViewFromLiteral("bc"); + + String oneLetterSuffixUTF8Ref; + StringView oneLetterSuffixUTF8 = stringViewFromUTF8(oneLetterSuffixUTF8Ref, "ô"); + String shortSuffixUTF8Ref; + StringView shortSuffixUTF8 = stringViewFromUTF8(shortSuffixUTF8Ref, "èô"); + String longSuffixUTF8Ref; + StringView longSuffixUTF8 = stringViewFromUTF8(longSuffixUTF8Ref, "îûèô"); + String upperCaseSuffixUTF8Ref; + StringView upperCaseSuffixUTF8 = stringViewFromUTF8(upperCaseSuffixUTF8Ref, "ÈÔ"); + String notSuffixUTF8Ref; + StringView notSuffixUTF8 = stringViewFromUTF8(notSuffixUTF8Ref, "îû"); + + EXPECT_TRUE(reference.endsWith(reference)); + EXPECT_TRUE(reference.endsWith(oneLetterSuffix)); + EXPECT_TRUE(reference.endsWith(shortSuffix)); + EXPECT_TRUE(reference.endsWith(longSuffix)); + EXPECT_TRUE(reference.endsWith(empty)); + + EXPECT_TRUE(referenceUTF8.endsWith(referenceUTF8)); + EXPECT_TRUE(referenceUTF8.endsWith(oneLetterSuffixUTF8)); + EXPECT_TRUE(referenceUTF8.endsWith(shortSuffixUTF8)); + EXPECT_TRUE(referenceUTF8.endsWith(longSuffixUTF8)); + EXPECT_TRUE(referenceUTF8.endsWith(empty)); + + EXPECT_FALSE(reference.endsWith(notSuffix)); + EXPECT_FALSE(reference.endsWith(upperCaseSuffix)); + EXPECT_FALSE(reference.endsWith(notSuffixUTF8)); + EXPECT_FALSE(reference.endsWith(upperCaseSuffixUTF8)); + EXPECT_FALSE(referenceUTF8.endsWith(notSuffix)); + EXPECT_FALSE(referenceUTF8.endsWith(upperCaseSuffix)); + EXPECT_FALSE(referenceUTF8.endsWith(notSuffixUTF8)); + EXPECT_FALSE(referenceUTF8.endsWith(upperCaseSuffixUTF8)); +} + +TEST(WTF, StringViewEndsWithEmpty) +{ + StringView a = stringViewFromLiteral(""); + String refB; + StringView b = stringViewFromUTF8(refB, ""); + + EXPECT_TRUE(a.endsWith(a)); + EXPECT_TRUE(a.endsWith(b)); + EXPECT_TRUE(b.endsWith(a)); + EXPECT_TRUE(b.endsWith(b)); +} + +TEST(WTF, StringViewEndsWithIgnoringASCIICaseBasic) +{ + StringView reference = stringViewFromLiteral("abcdefg"); + String referenceUTF8Ref; + StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "à îûèô"); + + StringView oneLetterSuffix = stringViewFromLiteral("g"); + StringView shortSuffix = stringViewFromLiteral("efg"); + StringView longSuffix = stringViewFromLiteral("bcdefg"); + StringView upperCaseSuffix = stringViewFromLiteral("EFG"); + StringView mixedCaseSuffix = stringViewFromLiteral("bCdeFg"); + StringView empty = stringViewFromLiteral(""); + StringView notSuffix = stringViewFromLiteral("bc"); + + String oneLetterSuffixUTF8Ref; + StringView oneLetterSuffixUTF8 = stringViewFromUTF8(oneLetterSuffixUTF8Ref, "ô"); + String shortSuffixUTF8Ref; + StringView shortSuffixUTF8 = stringViewFromUTF8(shortSuffixUTF8Ref, "èô"); + String longSuffixUTF8Ref; + StringView longSuffixUTF8 = stringViewFromUTF8(longSuffixUTF8Ref, "îûèô"); + String upperCaseSuffixUTF8Ref; + StringView upperCaseSuffixUTF8 = stringViewFromUTF8(upperCaseSuffixUTF8Ref, "ÈÔ"); + String notSuffixUTF8Ref; + StringView notSuffixUTF8 = stringViewFromUTF8(notSuffixUTF8Ref, "îû"); + + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(reference)); + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(oneLetterSuffix)); + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(shortSuffix)); + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(longSuffix)); + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(empty)); + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(upperCaseSuffix)); + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(mixedCaseSuffix)); + + EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(referenceUTF8)); + EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(oneLetterSuffixUTF8)); + EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(shortSuffixUTF8)); + EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(longSuffixUTF8)); + EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(empty)); + + EXPECT_FALSE(reference.endsWithIgnoringASCIICase(notSuffix)); + EXPECT_FALSE(reference.endsWithIgnoringASCIICase(notSuffixUTF8)); + EXPECT_FALSE(reference.endsWithIgnoringASCIICase(upperCaseSuffixUTF8)); + EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(notSuffix)); + EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(notSuffixUTF8)); + EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(upperCaseSuffix)); + EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(upperCaseSuffixUTF8)); +} + +TEST(WTF, StringViewEndsWithIgnoringASCIICaseEmpty) +{ + StringView a = stringViewFromLiteral(""); + String refB; + StringView b = stringViewFromUTF8(refB, ""); + + EXPECT_TRUE(a.endsWithIgnoringASCIICase(a)); + EXPECT_TRUE(a.endsWithIgnoringASCIICase(b)); + EXPECT_TRUE(b.endsWithIgnoringASCIICase(a)); + EXPECT_TRUE(b.endsWithIgnoringASCIICase(b)); +} + +TEST(WTF, StringViewEndsWithIgnoringASCIICaseWithLatin1Characters) +{ + StringView reference = stringViewFromLiteral("aBcéeFG"); + String referenceUTF8Ref; + StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "aBcéeFG"); + + StringView a = stringViewFromLiteral("BcéeFG"); + StringView b = stringViewFromLiteral("BCéEFG"); + StringView c = stringViewFromLiteral("bcéefG"); + StringView d = stringViewFromLiteral("bcéefg"); + + String refE; + StringView e = stringViewFromUTF8(refE, "bcéefG"); + String refF; + StringView f = stringViewFromUTF8(refF, "BCéEFG"); + String refG; + StringView g = stringViewFromUTF8(refG, "bcéefG"); + String refH; + StringView h = stringViewFromUTF8(refH, "bcéefg"); + + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(a)); + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(b)); + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(c)); + EXPECT_TRUE(reference.endsWithIgnoringASCIICase(d)); + + EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(e)); + EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(f)); + EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(g)); + EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(h)); + + EXPECT_FALSE(reference.endsWithIgnoringASCIICase(referenceUTF8)); + EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(reference)); +} + +TEST(WTF, StringView8Bit) +{ + StringView nullView; + StringView emptyView = StringView::empty(); + EXPECT_TRUE(StringView().is8Bit()); + EXPECT_TRUE(StringView::empty().is8Bit()); + + LChar* lcharPtr = nullptr; + UChar* ucharPtr = nullptr; + EXPECT_TRUE(StringView(lcharPtr, 0).is8Bit()); + EXPECT_FALSE(StringView(ucharPtr, 0).is8Bit()); + + EXPECT_TRUE(StringView(String(lcharPtr, 0)).is8Bit()); + EXPECT_TRUE(StringView(String(ucharPtr, 0)).is8Bit()); + + EXPECT_TRUE(StringView(String().impl()).is8Bit()); + EXPECT_TRUE(StringView(emptyString().impl()).is8Bit()); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/Vector.cpp b/Tools/TestWebKitAPI/Tests/WTF/Vector.cpp index 9ffb0b2e8..6567ac559 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/Vector.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/Vector.cpp @@ -24,10 +24,21 @@ */ #include "config.h" + +#include "MoveOnly.h" #include <wtf/Vector.h> +#include <wtf/text/CString.h> namespace TestWebKitAPI { +TEST(WTF_Vector, Basic) +{ + Vector<int> intVector; + EXPECT_TRUE(intVector.isEmpty()); + EXPECT_EQ(0U, intVector.size()); + EXPECT_EQ(0U, intVector.capacity()); +} + TEST(WTF_Vector, Iterator) { Vector<int> intVector; @@ -52,6 +63,159 @@ TEST(WTF_Vector, Iterator) EXPECT_TRUE(end == it); } +TEST(WTF_Vector, OverloadedOperatorAmpersand) +{ + struct Test { + private: + Test* operator&(); + }; + + Vector<Test> vector; + vector.append(Test()); +} + +TEST(WTF_Vector, AppendLast) +{ + Vector<unsigned> vector; + vector.append(0); + + // FIXME: This test needs to be run with GuardMalloc to show the bug. + for (size_t i = 0; i < 100; ++i) + vector.append(const_cast<const unsigned&>(vector.last())); +} + +TEST(WTF_Vector, InitializerList) +{ + Vector<int> vector = { 1, 2, 3, 4 }; + EXPECT_EQ(4U, vector.size()); + + EXPECT_EQ(1, vector[0]); + EXPECT_EQ(2, vector[1]); + EXPECT_EQ(3, vector[2]); + EXPECT_EQ(4, vector[3]); +} + +TEST(WTF_Vector, InitializeFromOtherInitialCapacity) +{ + Vector<int, 3> vector = { 1, 3, 2, 4 }; + Vector<int, 5> vectorCopy(vector); + EXPECT_EQ(4U, vector.size()); + EXPECT_EQ(4U, vectorCopy.size()); + EXPECT_EQ(5U, vectorCopy.capacity()); + + EXPECT_EQ(1, vectorCopy[0]); + EXPECT_EQ(3, vectorCopy[1]); + EXPECT_EQ(2, vectorCopy[2]); + EXPECT_EQ(4, vectorCopy[3]); +} + +TEST(WTF_Vector, CopyFromOtherInitialCapacity) +{ + Vector<int, 3> vector = { 1, 3, 2, 4 }; + Vector<int, 5> vectorCopy { 0 }; + EXPECT_EQ(4U, vector.size()); + EXPECT_EQ(1U, vectorCopy.size()); + + vectorCopy = vector; + + EXPECT_EQ(4U, vector.size()); + EXPECT_EQ(4U, vectorCopy.size()); + EXPECT_EQ(5U, vectorCopy.capacity()); + + EXPECT_EQ(1, vectorCopy[0]); + EXPECT_EQ(3, vectorCopy[1]); + EXPECT_EQ(2, vectorCopy[2]); + EXPECT_EQ(4, vectorCopy[3]); +} + +TEST(WTF_Vector, InitializeFromOtherOverflowBehavior) +{ + Vector<int, 7, WTF::CrashOnOverflow> vector = { 4, 3, 2, 1 }; + Vector<int, 7, UnsafeVectorOverflow> vectorCopy(vector); + EXPECT_EQ(4U, vector.size()); + EXPECT_EQ(4U, vectorCopy.size()); + + EXPECT_EQ(4, vectorCopy[0]); + EXPECT_EQ(3, vectorCopy[1]); + EXPECT_EQ(2, vectorCopy[2]); + EXPECT_EQ(1, vectorCopy[3]); +} + +TEST(WTF_Vector, CopyFromOtherOverflowBehavior) +{ + Vector<int, 7, WTF::CrashOnOverflow> vector = { 4, 3, 2, 1 }; + Vector<int, 7, UnsafeVectorOverflow> vectorCopy = { 0, 0, 0 }; + + EXPECT_EQ(4U, vector.size()); + EXPECT_EQ(3U, vectorCopy.size()); + + vectorCopy = vector; + + EXPECT_EQ(4U, vector.size()); + EXPECT_EQ(4U, vectorCopy.size()); + + EXPECT_EQ(4, vectorCopy[0]); + EXPECT_EQ(3, vectorCopy[1]); + EXPECT_EQ(2, vectorCopy[2]); + EXPECT_EQ(1, vectorCopy[3]); +} + +TEST(WTF_Vector, InitializeFromOtherMinCapacity) +{ + Vector<int, 7, WTF::CrashOnOverflow, 1> vector = { 3, 4, 2, 1 }; + Vector<int, 7, WTF::CrashOnOverflow, 50> vectorCopy(vector); + EXPECT_EQ(4U, vector.size()); + EXPECT_EQ(4U, vectorCopy.size()); + + EXPECT_EQ(3, vectorCopy[0]); + EXPECT_EQ(4, vectorCopy[1]); + EXPECT_EQ(2, vectorCopy[2]); + EXPECT_EQ(1, vectorCopy[3]); +} + +TEST(WTF_Vector, CopyFromOtherMinCapacity) +{ + Vector<int, 7, WTF::CrashOnOverflow, 1> vector = { 3, 4, 2, 1 }; + Vector<int, 7, WTF::CrashOnOverflow, 50> vectorCopy; + + EXPECT_EQ(4U, vector.size()); + EXPECT_EQ(0U, vectorCopy.size()); + + vectorCopy = vector; + + EXPECT_EQ(4U, vector.size()); + EXPECT_EQ(4U, vectorCopy.size()); + + EXPECT_EQ(3, vectorCopy[0]); + EXPECT_EQ(4, vectorCopy[1]); + EXPECT_EQ(2, vectorCopy[2]); + EXPECT_EQ(1, vectorCopy[3]); +} + +TEST(WTF_Vector, Reverse) +{ + Vector<int> intVector; + intVector.append(10); + intVector.append(11); + intVector.append(12); + intVector.append(13); + intVector.reverse(); + + EXPECT_EQ(13, intVector[0]); + EXPECT_EQ(12, intVector[1]); + EXPECT_EQ(11, intVector[2]); + EXPECT_EQ(10, intVector[3]); + + intVector.append(9); + intVector.reverse(); + + EXPECT_EQ(9, intVector[0]); + EXPECT_EQ(10, intVector[1]); + EXPECT_EQ(11, intVector[2]); + EXPECT_EQ(12, intVector[3]); + EXPECT_EQ(13, intVector[4]); +} + TEST(WTF_Vector, ReverseIterator) { Vector<int> intVector; @@ -76,4 +240,378 @@ TEST(WTF_Vector, ReverseIterator) EXPECT_TRUE(end == it); } +TEST(WTF_Vector, MoveOnly_UncheckedAppend) +{ + Vector<MoveOnly> vector; + + vector.reserveInitialCapacity(100); + for (size_t i = 0; i < 100; ++i) { + MoveOnly moveOnly(i); + vector.uncheckedAppend(WTFMove(moveOnly)); + EXPECT_EQ(0U, moveOnly.value()); + } + + for (size_t i = 0; i < 100; ++i) + EXPECT_EQ(i, vector[i].value()); +} + +TEST(WTF_Vector, MoveOnly_Append) +{ + Vector<MoveOnly> vector; + + for (size_t i = 0; i < 100; ++i) { + MoveOnly moveOnly(i); + vector.append(WTFMove(moveOnly)); + EXPECT_EQ(0U, moveOnly.value()); + } + + for (size_t i = 0; i < 100; ++i) + EXPECT_EQ(i, vector[i].value()); + + for (size_t i = 0; i < 16; ++i) { + Vector<MoveOnly> vector; + + vector.append(i); + + for (size_t j = 0; j < i; ++j) + vector.append(j); + vector.append(WTFMove(vector[0])); + + EXPECT_EQ(0U, vector[0].value()); + + for (size_t j = 0; j < i; ++j) + EXPECT_EQ(j, vector[j + 1].value()); + EXPECT_EQ(i, vector.last().value()); + } +} + +TEST(WTF_Vector, MoveOnly_Insert) +{ + Vector<MoveOnly> vector; + + for (size_t i = 0; i < 100; ++i) { + MoveOnly moveOnly(i); + vector.insert(0, WTFMove(moveOnly)); + EXPECT_EQ(0U, moveOnly.value()); + } + + EXPECT_EQ(vector.size(), 100U); + for (size_t i = 0; i < 100; ++i) + EXPECT_EQ(99 - i, vector[i].value()); + + for (size_t i = 0; i < 200; i += 2) { + MoveOnly moveOnly(1000 + i); + vector.insert(i, WTFMove(moveOnly)); + EXPECT_EQ(0U, moveOnly.value()); + } + + EXPECT_EQ(200U, vector.size()); + for (size_t i = 0; i < 200; ++i) { + if (i % 2) + EXPECT_EQ(99 - i / 2, vector[i].value()); + else + EXPECT_EQ(1000 + i, vector[i].value()); + } +} + +TEST(WTF_Vector, MoveOnly_TakeLast) +{ + Vector<MoveOnly> vector; + + for (size_t i = 0; i < 100; ++i) { + MoveOnly moveOnly(i); + vector.append(WTFMove(moveOnly)); + EXPECT_EQ(0U, moveOnly.value()); + } + + EXPECT_EQ(100U, vector.size()); + for (size_t i = 0; i < 100; ++i) + EXPECT_EQ(99 - i, vector.takeLast().value()); + + EXPECT_EQ(0U, vector.size()); +} + +TEST(WTF_Vector, VectorOfVectorsOfVectorsInlineCapacitySwap) +{ + Vector<Vector<Vector<int, 1>, 1>, 1> a; + Vector<Vector<Vector<int, 1>, 1>, 1> b; + Vector<Vector<Vector<int, 1>, 1>, 1> c; + + EXPECT_EQ(0U, a.size()); + EXPECT_EQ(0U, b.size()); + EXPECT_EQ(0U, c.size()); + + Vector<int, 1> x; + x.append(42); + + EXPECT_EQ(1U, x.size()); + EXPECT_EQ(42, x[0]); + + Vector<Vector<int, 1>, 1> y; + y.append(x); + + EXPECT_EQ(1U, x.size()); + EXPECT_EQ(42, x[0]); + EXPECT_EQ(1U, y.size()); + EXPECT_EQ(1U, y[0].size()); + EXPECT_EQ(42, y[0][0]); + + a.append(y); + + EXPECT_EQ(1U, x.size()); + EXPECT_EQ(42, x[0]); + EXPECT_EQ(1U, y.size()); + EXPECT_EQ(1U, y[0].size()); + EXPECT_EQ(42, y[0][0]); + EXPECT_EQ(1U, a.size()); + EXPECT_EQ(1U, a[0].size()); + EXPECT_EQ(1U, a[0][0].size()); + EXPECT_EQ(42, a[0][0][0]); + + a.swap(b); + + EXPECT_EQ(0U, a.size()); + EXPECT_EQ(1U, x.size()); + EXPECT_EQ(42, x[0]); + EXPECT_EQ(1U, y.size()); + EXPECT_EQ(1U, y[0].size()); + EXPECT_EQ(42, y[0][0]); + EXPECT_EQ(1U, b.size()); + EXPECT_EQ(1U, b[0].size()); + EXPECT_EQ(1U, b[0][0].size()); + EXPECT_EQ(42, b[0][0][0]); + + b.swap(c); + + EXPECT_EQ(0U, a.size()); + EXPECT_EQ(0U, b.size()); + EXPECT_EQ(1U, x.size()); + EXPECT_EQ(42, x[0]); + EXPECT_EQ(1U, y.size()); + EXPECT_EQ(1U, y[0].size()); + EXPECT_EQ(42, y[0][0]); + EXPECT_EQ(1U, c.size()); + EXPECT_EQ(1U, c[0].size()); + EXPECT_EQ(1U, c[0][0].size()); + EXPECT_EQ(42, c[0][0][0]); + + y[0][0] = 24; + + EXPECT_EQ(1U, x.size()); + EXPECT_EQ(42, x[0]); + EXPECT_EQ(1U, y.size()); + EXPECT_EQ(1U, y[0].size()); + EXPECT_EQ(24, y[0][0]); + + a.append(y); + + EXPECT_EQ(1U, x.size()); + EXPECT_EQ(42, x[0]); + EXPECT_EQ(1U, y.size()); + EXPECT_EQ(1U, y[0].size()); + EXPECT_EQ(24, y[0][0]); + EXPECT_EQ(1U, a.size()); + EXPECT_EQ(1U, a[0].size()); + EXPECT_EQ(1U, a[0][0].size()); + EXPECT_EQ(24, a[0][0][0]); + EXPECT_EQ(1U, c.size()); + EXPECT_EQ(1U, c[0].size()); + EXPECT_EQ(1U, c[0][0].size()); + EXPECT_EQ(42, c[0][0][0]); + EXPECT_EQ(0U, b.size()); +} + +TEST(WTF_Vector, RemoveFirst) +{ + Vector<int> v; + EXPECT_TRUE(v.isEmpty()); + EXPECT_FALSE(v.removeFirst(1)); + EXPECT_FALSE(v.removeFirst(-1)); + EXPECT_TRUE(v.isEmpty()); + + v.fill(2, 10); + EXPECT_EQ(10U, v.size()); + EXPECT_FALSE(v.removeFirst(1)); + EXPECT_EQ(10U, v.size()); + v.clear(); + + v.fill(1, 10); + EXPECT_EQ(10U, v.size()); + EXPECT_TRUE(v.removeFirst(1)); + EXPECT_TRUE(v == Vector<int>({1, 1, 1, 1, 1, 1, 1, 1, 1})); + EXPECT_EQ(9U, v.size()); + EXPECT_FALSE(v.removeFirst(2)); + EXPECT_EQ(9U, v.size()); + EXPECT_TRUE(v == Vector<int>({1, 1, 1, 1, 1, 1, 1, 1, 1})); + + unsigned removed = 0; + while (v.removeFirst(1)) + ++removed; + EXPECT_EQ(9U, removed); + EXPECT_TRUE(v.isEmpty()); + + v.resize(1); + EXPECT_EQ(1U, v.size()); + EXPECT_TRUE(v.removeFirst(1)); + EXPECT_EQ(0U, v.size()); + EXPECT_TRUE(v.isEmpty()); +} + +TEST(WTF_Vector, RemoveAll) +{ + // Using a memcpy-able type. + static_assert(VectorTraits<int>::canMoveWithMemcpy, "Should use a memcpy-able type"); + Vector<int> v; + EXPECT_TRUE(v.isEmpty()); + EXPECT_FALSE(v.removeAll(1)); + EXPECT_FALSE(v.removeAll(-1)); + EXPECT_TRUE(v.isEmpty()); + + v.fill(1, 10); + EXPECT_EQ(10U, v.size()); + EXPECT_EQ(10U, v.removeAll(1)); + EXPECT_TRUE(v.isEmpty()); + + v.fill(2, 10); + EXPECT_EQ(10U, v.size()); + EXPECT_EQ(0U, v.removeAll(1)); + EXPECT_EQ(10U, v.size()); + + v = {1, 2, 1, 2, 1, 2, 2, 1, 1, 1}; + EXPECT_EQ(10U, v.size()); + EXPECT_EQ(6U, v.removeAll(1)); + EXPECT_EQ(4U, v.size()); + EXPECT_TRUE(v == Vector<int>({2, 2, 2, 2})); + EXPECT_TRUE(v.find(1) == notFound); + EXPECT_EQ(4U, v.removeAll(2)); + EXPECT_TRUE(v.isEmpty()); + + v = {3, 1, 2, 1, 2, 1, 2, 2, 1, 1, 1, 3}; + EXPECT_EQ(12U, v.size()); + EXPECT_EQ(6U, v.removeAll(1)); + EXPECT_EQ(6U, v.size()); + EXPECT_TRUE(v.find(1) == notFound); + EXPECT_TRUE(v == Vector<int>({3, 2, 2, 2, 2, 3})); + + EXPECT_EQ(4U, v.removeAll(2)); + EXPECT_EQ(2U, v.size()); + EXPECT_TRUE(v.find(2) == notFound); + EXPECT_TRUE(v == Vector<int>({3, 3})); + + EXPECT_EQ(2U, v.removeAll(3)); + EXPECT_TRUE(v.isEmpty()); + + v = {1, 1, 1, 3, 2, 4, 2, 2, 2, 4, 4, 3}; + EXPECT_EQ(12U, v.size()); + EXPECT_EQ(3U, v.removeAll(1)); + EXPECT_EQ(9U, v.size()); + EXPECT_TRUE(v.find(1) == notFound); + EXPECT_TRUE(v == Vector<int>({3, 2, 4, 2, 2, 2, 4, 4, 3})); + + // Using a non memcpy-able type. + static_assert(!VectorTraits<CString>::canMoveWithMemcpy, "Should use a non memcpy-able type"); + Vector<CString> vExpected; + Vector<CString> v2; + EXPECT_TRUE(v2.isEmpty()); + EXPECT_FALSE(v2.removeAll("1")); + EXPECT_TRUE(v2.isEmpty()); + + v2.fill("1", 10); + EXPECT_EQ(10U, v2.size()); + EXPECT_EQ(10U, v2.removeAll("1")); + EXPECT_TRUE(v2.isEmpty()); + + v2.fill("2", 10); + EXPECT_EQ(10U, v2.size()); + EXPECT_EQ(0U, v2.removeAll("1")); + EXPECT_EQ(10U, v2.size()); + + v2 = {"1", "2", "1", "2", "1", "2", "2", "1", "1", "1"}; + EXPECT_EQ(10U, v2.size()); + EXPECT_EQ(6U, v2.removeAll("1")); + EXPECT_EQ(4U, v2.size()); + EXPECT_TRUE(v2.find("1") == notFound); + EXPECT_EQ(4U, v2.removeAll("2")); + EXPECT_TRUE(v2.isEmpty()); + + v2 = {"3", "1", "2", "1", "2", "1", "2", "2", "1", "1", "1", "3"}; + EXPECT_EQ(12U, v2.size()); + EXPECT_EQ(6U, v2.removeAll("1")); + EXPECT_EQ(6U, v2.size()); + EXPECT_TRUE(v2.find("1") == notFound); + vExpected = {"3", "2", "2", "2", "2", "3"}; + EXPECT_TRUE(v2 == vExpected); + + EXPECT_EQ(4U, v2.removeAll("2")); + EXPECT_EQ(2U, v2.size()); + EXPECT_TRUE(v2.find("2") == notFound); + vExpected = {"3", "3"}; + EXPECT_TRUE(v2 == vExpected); + + EXPECT_EQ(2U, v2.removeAll("3")); + EXPECT_TRUE(v2.isEmpty()); + + v2 = {"1", "1", "1", "3", "2", "4", "2", "2", "2", "4", "4", "3"}; + EXPECT_EQ(12U, v2.size()); + EXPECT_EQ(3U, v2.removeAll("1")); + EXPECT_EQ(9U, v2.size()); + EXPECT_TRUE(v2.find("1") == notFound); + vExpected = {"3", "2", "4", "2", "2", "2", "4", "4", "3"}; + EXPECT_TRUE(v2 == vExpected); +} + +TEST(WTF_Vector, RemoveFirstMatching) +{ + Vector<int> v; + EXPECT_TRUE(v.isEmpty()); + EXPECT_FALSE(v.removeFirstMatching([] (int value) { return value > 0; })); + EXPECT_FALSE(v.removeFirstMatching([] (int) { return true; })); + EXPECT_FALSE(v.removeFirstMatching([] (int) { return false; })); + + v = {3, 1, 2, 1, 2, 1, 2, 2, 1, 1, 1, 3}; + EXPECT_EQ(12U, v.size()); + EXPECT_FALSE(v.removeFirstMatching([] (int) { return false; })); + EXPECT_EQ(12U, v.size()); + EXPECT_FALSE(v.removeFirstMatching([] (int value) { return value < 0; })); + EXPECT_EQ(12U, v.size()); + EXPECT_TRUE(v.removeFirstMatching([] (int value) { return value < 3; })); + EXPECT_EQ(11U, v.size()); + EXPECT_TRUE(v == Vector<int>({3, 2, 1, 2, 1, 2, 2, 1, 1, 1, 3})); + EXPECT_TRUE(v.removeFirstMatching([] (int value) { return value > 2; })); + EXPECT_EQ(10U, v.size()); + EXPECT_TRUE(v == Vector<int>({2, 1, 2, 1, 2, 2, 1, 1, 1, 3})); + EXPECT_TRUE(v.removeFirstMatching([] (int value) { return value > 2; })); + EXPECT_EQ(9U, v.size()); + EXPECT_TRUE(v == Vector<int>({2, 1, 2, 1, 2, 2, 1, 1, 1})); +} + +TEST(WTF_Vector, RemoveAllMatching) +{ + Vector<int> v; + EXPECT_TRUE(v.isEmpty()); + EXPECT_FALSE(v.removeAllMatching([] (int value) { return value > 0; })); + EXPECT_FALSE(v.removeAllMatching([] (int) { return true; })); + EXPECT_FALSE(v.removeAllMatching([] (int) { return false; })); + + v = {3, 1, 2, 1, 2, 1, 2, 2, 1, 1, 1, 3}; + EXPECT_EQ(12U, v.size()); + EXPECT_EQ(0U, v.removeAllMatching([] (int) { return false; })); + EXPECT_EQ(12U, v.size()); + EXPECT_EQ(0U, v.removeAllMatching([] (int value) { return value < 0; })); + EXPECT_EQ(12U, v.size()); + EXPECT_EQ(12U, v.removeAllMatching([] (int value) { return value > 0; })); + EXPECT_TRUE(v.isEmpty()); + + v = {3, 1, 2, 1, 2, 1, 3, 2, 2, 1, 1, 1, 3}; + EXPECT_EQ(13U, v.size()); + EXPECT_EQ(3U, v.removeAllMatching([] (int value) { return value > 2; })); + EXPECT_EQ(10U, v.size()); + EXPECT_TRUE(v == Vector<int>({1, 2, 1, 2, 1, 2, 2, 1, 1, 1})); + EXPECT_EQ(6U, v.removeAllMatching([] (int value) { return value != 2; })); + EXPECT_EQ(4U, v.size()); + EXPECT_TRUE(v == Vector<int>({2, 2, 2, 2})); + EXPECT_EQ(4U, v.removeAllMatching([] (int value) { return value == 2; })); + EXPECT_TRUE(v.isEmpty()); +} + } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/VectorBasic.cpp b/Tools/TestWebKitAPI/Tests/WTF/VectorBasic.cpp deleted file mode 100644 index 211ef8841..000000000 --- a/Tools/TestWebKitAPI/Tests/WTF/VectorBasic.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2010 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/Vector.h> - -namespace TestWebKitAPI { - -TEST(WTF, VectorBasic) -{ - Vector<int> intVector; - EXPECT_TRUE(intVector.isEmpty()); - EXPECT_EQ(0ul, intVector.size()); - EXPECT_EQ(0ul, intVector.capacity()); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/VectorReverse.cpp b/Tools/TestWebKitAPI/Tests/WTF/VectorReverse.cpp deleted file mode 100644 index 6d4a00f0f..000000000 --- a/Tools/TestWebKitAPI/Tests/WTF/VectorReverse.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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/Vector.h> - -namespace TestWebKitAPI { - -TEST(WTF, VectorReverse) -{ - Vector<int> intVector; - intVector.append(10); - intVector.append(11); - intVector.append(12); - intVector.append(13); - intVector.reverse(); - - EXPECT_EQ(13, intVector[0]); - EXPECT_EQ(12, intVector[1]); - EXPECT_EQ(11, intVector[2]); - EXPECT_EQ(10, intVector[3]); - - intVector.append(9); - intVector.reverse(); - - EXPECT_EQ(9, intVector[0]); - EXPECT_EQ(10, intVector[1]); - EXPECT_EQ(11, intVector[2]); - EXPECT_EQ(12, intVector[3]); - EXPECT_EQ(13, intVector[4]); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/WTF.pro b/Tools/TestWebKitAPI/Tests/WTF/WTF.pro deleted file mode 100644 index 8b3658ffd..000000000 --- a/Tools/TestWebKitAPI/Tests/WTF/WTF.pro +++ /dev/null @@ -1,32 +0,0 @@ -TEMPLATE = app -TARGET = tst_wtf - -SOURCES += \ - AtomicString.cpp \ - CheckedArithmeticOperations.cpp \ - CString.cpp \ - Functional.cpp \ - HashMap.cpp \ - HashSet.cpp \ - IntegerToStringConversion.cpp \ - ListHashSet.cpp \ - MD5.cpp \ - MathExtras.cpp \ - MediaTime.cpp \ - RedBlackTree.cpp \ - SHA1.cpp \ - SaturatedArithmeticOperations.cpp \ - StringBuilder.cpp \ - StringHasher.cpp \ - StringImpl.cpp \ - StringOperators.cpp \ - TemporaryChange.cpp \ - Vector.cpp \ - VectorBasic.cpp \ - VectorReverse.cpp \ - WTFString.cpp - -include(../../TestWebKitAPI.pri) - -DEFINES += APITEST_SOURCE_DIR=\\\"$$PWD\\\" - diff --git a/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp b/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp index 4a92cd4e8..e809ddac4 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/WTFString.cpp @@ -38,14 +38,12 @@ TEST(WTF, StringCreationFromLiteral) ASSERT_EQ(strlen("Explicit construction syntax"), stringFromLiteral.length()); ASSERT_TRUE(stringFromLiteral == "Explicit construction syntax"); ASSERT_TRUE(stringFromLiteral.is8Bit()); - ASSERT_TRUE(stringFromLiteral.impl()->hasTerminatingNullCharacter()); ASSERT_TRUE(String("Explicit construction syntax") == stringFromLiteral); String stringWithTemplate("Template Literal", String::ConstructFromLiteral); ASSERT_EQ(strlen("Template Literal"), stringWithTemplate.length()); ASSERT_TRUE(stringWithTemplate == "Template Literal"); ASSERT_TRUE(stringWithTemplate.is8Bit()); - ASSERT_TRUE(stringWithTemplate.impl()->hasTerminatingNullCharacter()); ASSERT_TRUE(String("Template Literal") == stringWithTemplate); } @@ -155,5 +153,143 @@ TEST(WTF, StringReplaceWithLiteral) ASSERT_STREQ("résumé", testString.utf8().data()); } +TEST(WTF, StringIsolatedCopy) +{ + String original = "1234"; + auto copy = WTFMove(original).isolatedCopy(); + ASSERT_FALSE(original.impl() == copy.impl()); +} + +TEST(WTF, StringToInt) +{ + bool ok; + + EXPECT_EQ(0, String().toInt()); + EXPECT_EQ(0, String().toInt(&ok)); + EXPECT_FALSE(ok); + + EXPECT_EQ(0, emptyString().toInt()); + EXPECT_EQ(0, emptyString().toInt(&ok)); + EXPECT_FALSE(ok); + + EXPECT_EQ(0, String("0").toInt()); + EXPECT_EQ(0, String("0").toInt(&ok)); + EXPECT_TRUE(ok); + + EXPECT_EQ(1, String("1").toInt()); + EXPECT_EQ(1, String("1").toInt(&ok)); + EXPECT_TRUE(ok); + + EXPECT_EQ(2147483647, String("2147483647").toInt()); + EXPECT_EQ(2147483647, String("2147483647").toInt(&ok)); + EXPECT_TRUE(ok); + + EXPECT_EQ(0, String("2147483648").toInt()); + EXPECT_EQ(0, String("2147483648").toInt(&ok)); + EXPECT_FALSE(ok); + + EXPECT_EQ(-2147483648, String("-2147483648").toInt()); + EXPECT_EQ(-2147483648, String("-2147483648").toInt(&ok)); + EXPECT_TRUE(ok); + + EXPECT_EQ(0, String("-2147483649").toInt()); + EXPECT_EQ(0, String("-2147483649").toInt(&ok)); + EXPECT_FALSE(ok); + + // fail if we see leading junk + EXPECT_EQ(0, String("x1").toInt()); + EXPECT_EQ(0, String("x1").toInt(&ok)); + EXPECT_FALSE(ok); + + // succeed if we see leading spaces + EXPECT_EQ(1, String(" 1").toInt()); + EXPECT_EQ(1, String(" 1").toInt(&ok)); + EXPECT_TRUE(ok); + + // silently ignore trailing junk + EXPECT_EQ(1, String("1x").toInt()); + EXPECT_EQ(1, String("1x").toInt(&ok)); + EXPECT_TRUE(ok); +} + +TEST(WTF, StringToDouble) +{ + bool ok; + + EXPECT_EQ(0.0, String().toDouble()); + EXPECT_EQ(0.0, String().toDouble(&ok)); + EXPECT_FALSE(ok); + + EXPECT_EQ(0.0, emptyString().toDouble()); + EXPECT_EQ(0.0, emptyString().toDouble(&ok)); + EXPECT_FALSE(ok); + + EXPECT_EQ(0.0, String("0").toDouble()); + EXPECT_EQ(0.0, String("0").toDouble(&ok)); + EXPECT_TRUE(ok); + + EXPECT_EQ(1.0, String("1").toDouble()); + EXPECT_EQ(1.0, String("1").toDouble(&ok)); + EXPECT_TRUE(ok); + + // fail if we see leading junk + EXPECT_EQ(0.0, String("x1").toDouble()); + EXPECT_EQ(0.0, String("x1").toDouble(&ok)); + EXPECT_FALSE(ok); + + // succeed if we see leading spaces + EXPECT_EQ(1.0, String(" 1").toDouble()); + EXPECT_EQ(1.0, String(" 1").toDouble(&ok)); + EXPECT_TRUE(ok); + + // ignore trailing junk, but return false for "ok" + // FIXME: This is an inconsistency with toInt, which always guarantees + // it will return 0 if it's also going to return false for ok. + EXPECT_EQ(1.0, String("1x").toDouble()); + EXPECT_EQ(1.0, String("1x").toDouble(&ok)); + EXPECT_FALSE(ok); + + // parse only numbers, not special values such as "infinity" + EXPECT_EQ(0.0, String("infinity").toDouble()); + EXPECT_EQ(0.0, String("infinity").toDouble(&ok)); + EXPECT_FALSE(ok); + + // parse only numbers, not special values such as "nan" + EXPECT_EQ(0.0, String("nan").toDouble()); + EXPECT_EQ(0.0, String("nan").toDouble(&ok)); + EXPECT_FALSE(ok); +} + +TEST(WTF, StringhasInfixStartingAt) +{ + EXPECT_TRUE(String("Test").is8Bit()); + EXPECT_TRUE(String("Te").is8Bit()); + EXPECT_TRUE(String("st").is8Bit()); + EXPECT_TRUE(String("Test").hasInfixStartingAt(String("Te"), 0)); + EXPECT_FALSE(String("Test").hasInfixStartingAt(String("Te"), 2)); + EXPECT_TRUE(String("Test").hasInfixStartingAt(String("st"), 2)); + EXPECT_FALSE(String("Test").hasInfixStartingAt(String("ST"), 2)); + + EXPECT_FALSE(String::fromUTF8("ä¸å›½").is8Bit()); + EXPECT_FALSE(String::fromUTF8("ä¸").is8Bit()); + EXPECT_FALSE(String::fromUTF8("国").is8Bit()); + EXPECT_TRUE(String::fromUTF8("ä¸å›½").hasInfixStartingAt(String::fromUTF8("ä¸"), 0)); + EXPECT_FALSE(String::fromUTF8("ä¸å›½").hasInfixStartingAt(String::fromUTF8("ä¸"), 1)); + EXPECT_TRUE(String::fromUTF8("ä¸å›½").hasInfixStartingAt(String::fromUTF8("国"), 1)); + + EXPECT_FALSE(String::fromUTF8("ä¸å›½").hasInfixStartingAt(String("Te"), 0)); + EXPECT_FALSE(String("Test").hasInfixStartingAt(String::fromUTF8("ä¸"), 2)); +} + +TEST(WTF, StringExistingHash) +{ + String string1("Template Literal"); + ASSERT_FALSE(string1.isNull()); + ASSERT_FALSE(string1.impl()->hasHash()); + string1.impl()->hash(); + ASSERT_EQ(string1.existingHash(), string1.impl()->existingHash()); + String string2; + ASSERT_EQ(string2.existingHash(), 0u); +} } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp b/Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp new file mode 100644 index 000000000..5b900007a --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/WeakPtr.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2015 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 "test.h" + +#include <wtf/WeakPtr.h> + +namespace TestWebKitAPI { + +TEST(WTF_WeakPtr, Basic) +{ + int dummy = 5; + WeakPtrFactory<int>* factory = new WeakPtrFactory<int>(&dummy); + WeakPtr<int> weakPtr1 = factory->createWeakPtr(); + WeakPtr<int> weakPtr2 = factory->createWeakPtr(); + WeakPtr<int> weakPtr3 = factory->createWeakPtr(); + EXPECT_EQ(weakPtr1.get(), &dummy); + EXPECT_EQ(weakPtr2.get(), &dummy); + EXPECT_EQ(weakPtr3.get(), &dummy); + EXPECT_TRUE(weakPtr1); + EXPECT_TRUE(weakPtr2); + EXPECT_TRUE(weakPtr3); + delete factory; + EXPECT_NULL(weakPtr1.get()); + EXPECT_NULL(weakPtr2.get()); + EXPECT_NULL(weakPtr3.get()); + EXPECT_FALSE(weakPtr1); + EXPECT_FALSE(weakPtr2); + EXPECT_FALSE(weakPtr3); +} + +TEST(WTF_WeakPtr, Assignment) +{ + int dummy = 5; + WeakPtr<int> weakPtr; + { + WeakPtrFactory<int> factory(&dummy); + EXPECT_NULL(weakPtr.get()); + weakPtr = factory.createWeakPtr(); + EXPECT_EQ(weakPtr.get(), &dummy); + } + EXPECT_NULL(weakPtr.get()); +} + +TEST(WTF_WeakPtr, MultipleFactories) +{ + int dummy1 = 5; + int dummy2 = 7; + WeakPtrFactory<int>* factory1 = new WeakPtrFactory<int>(&dummy1); + WeakPtrFactory<int>* factory2 = new WeakPtrFactory<int>(&dummy2); + WeakPtr<int> weakPtr1 = factory1->createWeakPtr(); + WeakPtr<int> weakPtr2 = factory2->createWeakPtr(); + EXPECT_EQ(weakPtr1.get(), &dummy1); + EXPECT_EQ(weakPtr2.get(), &dummy2); + delete factory1; + EXPECT_NULL(weakPtr1.get()); + EXPECT_EQ(weakPtr2.get(), &dummy2); + delete factory2; + EXPECT_NULL(weakPtr2.get()); +} + +TEST(WTF_WeakPtr, RevokeAll) +{ + int dummy = 5; + WeakPtrFactory<int> factory(&dummy); + WeakPtr<int> weakPtr1 = factory.createWeakPtr(); + WeakPtr<int> weakPtr2 = factory.createWeakPtr(); + WeakPtr<int> weakPtr3 = factory.createWeakPtr(); + EXPECT_EQ(weakPtr1.get(), &dummy); + EXPECT_EQ(weakPtr2.get(), &dummy); + EXPECT_EQ(weakPtr3.get(), &dummy); + factory.revokeAll(); + EXPECT_NULL(weakPtr1.get()); + EXPECT_NULL(weakPtr2.get()); + EXPECT_NULL(weakPtr3.get()); +} + +TEST(WTF_WeakPtr, NullFactory) +{ + WeakPtrFactory<int> factory(nullptr); + WeakPtr<int> weakPtr = factory.createWeakPtr(); + EXPECT_NULL(weakPtr.get()); + factory.revokeAll(); + EXPECT_NULL(weakPtr.get()); +} + +struct Foo { + void bar() { }; +}; + +TEST(WTF_WeakPtr, Dereference) +{ + Foo f; + WeakPtrFactory<Foo> factory(&f); + WeakPtr<Foo> weakPtr = factory.createWeakPtr(); + weakPtr->bar(); +} + +TEST(WTF_WeakPtr, Forget) +{ + int dummy = 5; + int dummy2 = 7; + + WeakPtrFactory<int> outerFactory(&dummy2); + WeakPtr<int> weakPtr1, weakPtr2, weakPtr3, weakPtr4; + { + WeakPtrFactory<int> innerFactory(&dummy); + weakPtr1 = innerFactory.createWeakPtr(); + weakPtr2 = innerFactory.createWeakPtr(); + weakPtr3 = innerFactory.createWeakPtr(); + EXPECT_EQ(weakPtr1.get(), &dummy); + EXPECT_EQ(weakPtr2.get(), &dummy); + EXPECT_EQ(weakPtr3.get(), &dummy); + weakPtr1.clear(); + weakPtr3 = nullptr; + EXPECT_NULL(weakPtr1.get()); + EXPECT_EQ(weakPtr2.get(), &dummy); + EXPECT_NULL(weakPtr3.get()); + weakPtr1.clear(); + weakPtr3.clear(); + EXPECT_NULL(weakPtr1.get()); + EXPECT_EQ(weakPtr2.get(), &dummy); + EXPECT_NULL(weakPtr3.get()); + weakPtr3 = nullptr; + EXPECT_NULL(weakPtr1.get()); + EXPECT_EQ(weakPtr2.get(), &dummy); + EXPECT_NULL(weakPtr3.get()); + + weakPtr4 = weakPtr2; + EXPECT_EQ(weakPtr2.get(), &dummy); + EXPECT_EQ(weakPtr4.get(), &dummy); + + WeakPtr<int> weakPtr5 = weakPtr2; + EXPECT_EQ(weakPtr2.get(), &dummy); + EXPECT_EQ(weakPtr5.get(), &dummy); + weakPtr5.clear(); + EXPECT_NULL(weakPtr5.get()); + EXPECT_EQ(weakPtr2.get(), &dummy); + + weakPtr4 = outerFactory.createWeakPtr(); + EXPECT_EQ(weakPtr2.get(), &dummy); + EXPECT_EQ(weakPtr4.get(), &dummy2); + } + + EXPECT_NULL(weakPtr1.get()); + EXPECT_NULL(weakPtr2.get()); + EXPECT_EQ(weakPtr4.get(), &dummy2); + + WeakPtr<int> weakPtr5 = weakPtr4; + EXPECT_EQ(weakPtr4.get(), &dummy2); + EXPECT_EQ(weakPtr5.get(), &dummy2); + weakPtr5.clear(); + EXPECT_NULL(weakPtr5.get()); + WeakPtr<int> weakPtr6 = weakPtr5; + EXPECT_NULL(weakPtr6.get()); + EXPECT_EQ(weakPtr5.get(), weakPtr6.get()); + + WeakPtr<int> weakPtr7 = outerFactory.createWeakPtr(); + EXPECT_EQ(weakPtr7.get(), &dummy2); + weakPtr7 = nullptr; + EXPECT_NULL(weakPtr7.get()); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/WorkQueue.cpp b/Tools/TestWebKitAPI/Tests/WTF/WorkQueue.cpp new file mode 100644 index 000000000..74f5dc294 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/WorkQueue.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2015 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 "Test.h" +#include <wtf/Condition.h> +#include <wtf/Lock.h> +#include <wtf/Vector.h> +#include <wtf/WorkQueue.h> +#include <string> +#include <thread> + +namespace TestWebKitAPI { + +static const char* simpleTestLabel = "simpleTest"; +static const char* longTestLabel = "longTest"; +static const char* thirdTestLabel = "thirdTest"; +static const char* dispatchAfterLabel = "dispatchAfter"; + +TEST(WTF_WorkQueue, Simple) +{ + Lock m_lock; + Condition m_testCompleted; + Vector<std::string> m_functionCallOrder; + + bool calledSimpleTest = false; + bool calledLongTest = false; + bool calledThirdTest = false; + + static const char* simpleTestLabel = "simpleTest"; + static const char* longTestLabel = "longTest"; + static const char* thirdTestLabel = "thirdTest"; + + auto queue = WorkQueue::create("com.apple.WebKit.Test.simple"); + int initialRefCount = queue->refCount(); + EXPECT_EQ(1, initialRefCount); + + LockHolder locker(m_lock); + queue->dispatch([&](void) { + m_functionCallOrder.append(simpleTestLabel); + calledSimpleTest = true; + }); + + queue->dispatch([&](void) { + m_functionCallOrder.append(longTestLabel); + std::this_thread::sleep_for(std::chrono::nanoseconds(100)); + calledLongTest = true; + }); + + queue->dispatch([&](void) { + LockHolder locker(m_lock); + m_functionCallOrder.append(thirdTestLabel); + calledThirdTest = true; + + EXPECT_TRUE(calledSimpleTest); + EXPECT_TRUE(calledLongTest); + EXPECT_TRUE(calledThirdTest); + + m_testCompleted.notifyOne(); + }); + + EXPECT_GT(queue->refCount(), 1); + + m_testCompleted.wait(m_lock); + + EXPECT_TRUE(calledSimpleTest); + EXPECT_TRUE(calledLongTest); + EXPECT_TRUE(calledThirdTest); + + EXPECT_EQ(static_cast<size_t>(3), m_functionCallOrder.size()); + EXPECT_STREQ(simpleTestLabel, m_functionCallOrder[0].c_str()); + EXPECT_STREQ(longTestLabel, m_functionCallOrder[1].c_str()); + EXPECT_STREQ(thirdTestLabel, m_functionCallOrder[2].c_str()); +} + +TEST(WTF_WorkQueue, TwoQueues) +{ + Lock m_lock; + Condition m_testQueue1Completed, m_testQueue2Completed; + Vector<std::string> m_functionCallOrder; + + bool calledSimpleTest = false; + bool calledLongTest = false; + bool calledThirdTest = false; + + auto queue1 = WorkQueue::create("com.apple.WebKit.Test.twoQueues1"); + auto queue2 = WorkQueue::create("com.apple.WebKit.Test.twoQueues2"); + + EXPECT_EQ(1, queue1->refCount()); + EXPECT_EQ(1, queue2->refCount()); + + LockHolder locker(m_lock); + + queue1->dispatch([&](void) { + m_functionCallOrder.append(simpleTestLabel); + calledSimpleTest = true; + }); + + queue2->dispatch([&](void) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + + LockHolder locker(m_lock); + + // Will fail if queue2 took the mutex before queue1. + EXPECT_TRUE(calledThirdTest); + + m_functionCallOrder.append(longTestLabel); + calledLongTest = true; + m_testQueue2Completed.notifyOne(); + }); + + queue1->dispatch([&](void) { + LockHolder locker(m_lock); + m_functionCallOrder.append(thirdTestLabel); + calledThirdTest = true; + + m_testQueue1Completed.notifyOne(); + }); + + m_testQueue1Completed.wait(m_lock); + + EXPECT_TRUE(calledSimpleTest); + EXPECT_FALSE(calledLongTest); + EXPECT_TRUE(calledThirdTest); + + m_testQueue2Completed.wait(m_lock); + + EXPECT_TRUE(calledSimpleTest); + EXPECT_TRUE(calledLongTest); + EXPECT_TRUE(calledThirdTest); + + EXPECT_EQ(static_cast<size_t>(3), m_functionCallOrder.size()); + EXPECT_STREQ(simpleTestLabel, m_functionCallOrder[0].c_str()); + EXPECT_STREQ(thirdTestLabel, m_functionCallOrder[1].c_str()); + EXPECT_STREQ(longTestLabel, m_functionCallOrder[2].c_str()); +} + +TEST(WTF_WorkQueue, DispatchAfter) +{ + Lock m_lock; + Condition m_testCompleted, m_dispatchAfterTestCompleted; + Vector<std::string> m_functionCallOrder; + + bool calledSimpleTest = false; + bool calledDispatchAfterTest = false; + + auto queue = WorkQueue::create("com.apple.WebKit.Test.dispatchAfter"); + + LockHolder locker(m_lock); + + queue->dispatch([&](void) { + LockHolder locker(m_lock); + m_functionCallOrder.append(simpleTestLabel); + calledSimpleTest = true; + m_testCompleted.notifyOne(); + }); + + queue->dispatchAfter(std::chrono::milliseconds(500), [&](void) { + LockHolder locker(m_lock); + m_functionCallOrder.append(dispatchAfterLabel); + calledDispatchAfterTest = true; + m_dispatchAfterTestCompleted.notifyOne(); + }); + + m_testCompleted.wait(m_lock); + + EXPECT_TRUE(calledSimpleTest); + EXPECT_FALSE(calledDispatchAfterTest); + + m_dispatchAfterTestCompleted.wait(m_lock); + + EXPECT_TRUE(calledSimpleTest); + EXPECT_TRUE(calledDispatchAfterTest); + + EXPECT_EQ(static_cast<size_t>(2), m_functionCallOrder.size()); + EXPECT_STREQ(simpleTestLabel, m_functionCallOrder[0].c_str()); + EXPECT_STREQ(dispatchAfterLabel, m_functionCallOrder[1].c_str()); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/cf/RetainPtr.cpp b/Tools/TestWebKitAPI/Tests/WTF/cf/RetainPtr.cpp deleted file mode 100644 index 0ca174cea..000000000 --- a/Tools/TestWebKitAPI/Tests/WTF/cf/RetainPtr.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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/RetainPtr.h> - -namespace TestWebKitAPI { - -TEST(RetainPtr, AdoptCF) -{ - RetainPtr<CFStringRef> foo = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, "foo", kCFStringEncodingUTF8)); - - EXPECT_EQ(1, CFGetRetainCount(foo.get())); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/cf/RetainPtrHashing.cpp b/Tools/TestWebKitAPI/Tests/WTF/cf/RetainPtrHashing.cpp deleted file mode 100644 index 6dd7b6a56..000000000 --- a/Tools/TestWebKitAPI/Tests/WTF/cf/RetainPtrHashing.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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/HashSet.h> -#include <wtf/HashMap.h> -#include <wtf/RetainPtr.h> - -namespace TestWebKitAPI { - -TEST(RetainPtrHashing, HashSet) -{ - HashSet<RetainPtr<CFStringRef> > set; - - RetainPtr<CFStringRef> foo = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, "foo", kCFStringEncodingUTF8)); - - EXPECT_FALSE(set.contains(foo)); - set.add(foo); - EXPECT_TRUE(set.contains(foo)); - - RetainPtr<CFStringRef> foo2 = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, "foo", kCFStringEncodingUTF8)); - EXPECT_FALSE(set.contains(foo2)); - set.add(foo2); - EXPECT_TRUE(set.contains(foo2)); - - set.remove(foo); - EXPECT_FALSE(set.contains(foo)); -} - -TEST(RetainPtrHashing, HashMapKey) -{ - HashMap<RetainPtr<CFStringRef>, int> map; - - RetainPtr<CFStringRef> foo = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, "foo", kCFStringEncodingUTF8)); - - EXPECT_FALSE(map.contains(foo)); - map.add(foo, 1); - EXPECT_EQ(1, map.get(foo)); - - RetainPtr<CFStringRef> foo2 = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, "foo", kCFStringEncodingUTF8)); - EXPECT_FALSE(map.contains(foo2)); - map.add(foo2, 2); - EXPECT_EQ(2, map.get(foo2)); - - map.remove(foo); - EXPECT_FALSE(map.contains(foo)); -} - -TEST(RetainPtrHashing, HashMapValue) -{ - HashMap<int, RetainPtr<CFStringRef> > map; - - RetainPtr<CFStringRef> foo = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, "foo", kCFStringEncodingUTF8)); - - EXPECT_FALSE(map.contains(1)); - map.add(1, foo); - EXPECT_EQ(foo, map.get(1)); - - RetainPtr<CFStringRef> foo2 = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, "foo", kCFStringEncodingUTF8)); - EXPECT_FALSE(map.contains(2)); - map.add(2, foo2); - EXPECT_EQ(foo2, map.get(2)); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/efl/PlatformUtilities.cpp b/Tools/TestWebKitAPI/Tests/WTF/darwin/OSObjectPtr.cpp index 65c54e1a7..5389dcbc8 100644 --- a/Tools/TestWebKitAPI/efl/PlatformUtilities.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/darwin/OSObjectPtr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,51 +24,43 @@ */ #include "config.h" -#include "PlatformUtilities.h" -#include <Ecore.h> -#include <stdio.h> -#include <unistd.h> +#include <wtf/OSObjectPtr.h> -namespace TestWebKitAPI { +#include <dispatch/dispatch.h> +#include <CoreFoundation/CoreFoundation.h> -namespace Util { +namespace TestWebKitAPI { -void run(bool* done) +TEST(OSObjectPtr, AdoptOSObject) { - while (!*done) - ecore_main_loop_iterate(); -} + OSObjectPtr<dispatch_queue_t> foo = adoptOSObject(dispatch_queue_create(0, DISPATCH_QUEUE_SERIAL)); -void sleep(double seconds) -{ - usleep(seconds * 1000000); + EXPECT_EQ(1, CFGetRetainCount(foo.get())); } -WKURLRef createURLForResource(const char* resource, const char* extension) +TEST(OSObjectPtr, RetainRelease) { - char url[PATH_MAX]; + dispatch_queue_t foo = dispatch_queue_create(0, DISPATCH_QUEUE_SERIAL); + EXPECT_EQ(1, CFGetRetainCount(foo)); - snprintf(url, sizeof(url), "file://%s/%s.%s", TEST_WEBKIT2_RESOURCES_DIR, resource, extension); + WTF::retainOSObject(foo); + EXPECT_EQ(2, CFGetRetainCount(foo)); - return WKURLCreateWithUTF8CString(url); + WTF::releaseOSObject(foo); + EXPECT_EQ(1, CFGetRetainCount(foo)); } -WKStringRef createInjectedBundlePath() +TEST(OSObjectPtr, LeakRef) { - return WKStringCreateWithUTF8CString(TEST_INJECTED_BUNDLE_PATH); -} + OSObjectPtr<dispatch_queue_t> foo = adoptOSObject(dispatch_queue_create(0, DISPATCH_QUEUE_SERIAL)); + EXPECT_EQ(1, CFGetRetainCount(foo.get())); -WKURLRef URLForNonExistentResource() -{ - return WKURLCreateWithUTF8CString("file:///does-not-exist.html"); -} + dispatch_queue_t queue = foo.leakRef(); + EXPECT_EQ(nullptr, foo.get()); + EXPECT_EQ(1, CFGetRetainCount(queue)); -WKRetainPtr<WKStringRef> MIMETypeForWKURLResponse(WKURLResponseRef wkResponse) -{ - return adoptWK(WKURLResponseCopyMIMEType(wkResponse)); + WTF::releaseOSObject(queue); } -} // namespace Util - } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/glib/GUniquePtr.cpp b/Tools/TestWebKitAPI/Tests/WTF/glib/GUniquePtr.cpp new file mode 100644 index 000000000..11f02c7b0 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/glib/GUniquePtr.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * 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 <gio/gio.h> + +inline std::ostringstream& log() +{ + static std::ostringstream log; + return log; +} + +inline std::string takeLogStr() +{ + std::string string = log().str(); + log().str(""); + return string; +} + +static void (* _g_free)(void*) = g_free; +#define g_free(x) \ + log() << "g_free(" << ptr << ");"; \ + _g_free(x); + +static void (* _g_error_free)(GError*) = g_error_free; +#define g_error_free(x) \ + log() << "g_error_free(" << ptr << ");"; \ + _g_error_free(x); + +static void (* _g_list_free)(GList*) = g_list_free; +#define g_list_free(x) \ + log() << "g_list_free(" << ptr << ");"; \ + _g_list_free(x); + +static void (* _g_slist_free)(GSList*) = g_slist_free; +#define g_slist_free(x) \ + log() << "g_slist_free(" << ptr << ");"; \ + _g_slist_free(x); + +static void (* _g_pattern_spec_free)(GPatternSpec*) = g_pattern_spec_free; +#define g_pattern_spec_free(x) \ + log() << "g_pattern_spec_free(" << ptr << ");"; \ + _g_pattern_spec_free(x); + +static void (* _g_dir_close)(GDir*) = g_dir_close; +#define g_dir_close(x) \ + log() << "g_dir_close(" << ptr << ");"; \ + _g_dir_close(x); + +static void (* _g_timer_destroy)(GTimer*) = g_timer_destroy; +#define g_timer_destroy(x) \ + log() << "g_timer_destroy(" << ptr << ");"; \ + _g_timer_destroy(x); + +static void (* _g_key_file_free)(GKeyFile*) = g_key_file_free; +#define g_key_file_free(x) \ + log() << "g_key_file_free(" << ptr << ");"; \ + _g_key_file_free(x); + +#include <wtf/glib/GUniquePtr.h> + +namespace TestWebKitAPI { + +TEST(WTF_GUniquePtr, Basic) +{ + std::ostringstream actual; + + { + GUniquePtr<char> a(g_strdup("a")); + actual << "g_free(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniquePtr<GError> a(g_error_new_literal(G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "a")); + actual << "g_error_free(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniquePtr<GList> a(g_list_prepend(nullptr, g_strdup("a"))); + actual << "g_list_free(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniquePtr<GSList> a(g_slist_prepend(nullptr, g_strdup("a"))); + actual << "g_slist_free(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniquePtr<GPatternSpec> a(g_pattern_spec_new("a")); + actual << "g_pattern_spec_free(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniquePtr<GDir> a(g_dir_open("/tmp", 0, nullptr)); + actual << "g_dir_close(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniquePtr<GTimer> a(g_timer_new()); + actual << "g_timer_destroy(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniquePtr<GKeyFile> a(g_key_file_new()); + actual << "g_key_file_free(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); +} + +static void returnOutChar(char** outChar) +{ + *outChar = g_strdup("a"); +} + +TEST(WTF_GUniquePtr, OutPtr) +{ + std::ostringstream actual; + + { + GUniqueOutPtr<char> a; + ASSERT_EQ(nullptr, a.get()); + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniqueOutPtr<char> a; + returnOutChar(&a.outPtr()); + actual << "g_free(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniqueOutPtr<char> a; + returnOutChar(&a.outPtr()); + actual << "g_free(" << a.get() << ");"; + returnOutChar(&a.outPtr()); + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + actual << "g_free(" << a.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); + + { + GUniqueOutPtr<char> a; + returnOutChar(&a.outPtr()); + GUniquePtr<char> b = a.release(); + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual << "g_free(" << b.get() << ");"; + } + ASSERT_STREQ(actual.str().c_str(), takeLogStr().c_str()); + actual.str(""); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp b/Tools/TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp new file mode 100644 index 000000000..9923d6580 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WTF/glib/WorkQueueGLib.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * 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 "Test.h" +#include <gio/gio.h> +#include <thread> +#include <wtf/Condition.h> +#include <wtf/Lock.h> +#include <wtf/WorkQueue.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> + +namespace TestWebKitAPI { + +TEST(WTF_WorkQueue, AsyncIO) +{ + struct TestingContext { + Lock m_lock; + Condition m_testCompleted; + GMainContext* m_mainContext; + } context; + + auto queue = WorkQueue::create("com.apple.WebKit.Test.AsyncIO"); + context.m_mainContext = g_main_context_default(); + EXPECT_FALSE(g_main_context_get_thread_default()); + + GUniquePtr<char> currentDirectory(g_get_current_dir()); + GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(currentDirectory.get())); + + LockHolder locker(context.m_lock); + queue->dispatch([&](void) { + EXPECT_TRUE(g_main_context_get_thread_default()); + EXPECT_TRUE(g_main_context_get_thread_default() != context.m_mainContext); + context.m_mainContext = g_main_context_get_thread_default(); + g_file_query_info_async(file.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, nullptr, + [](GObject*, GAsyncResult*, gpointer userData) { + TestingContext* context = static_cast<TestingContext*>(userData); + LockHolder locker(context->m_lock); + EXPECT_EQ(g_main_context_get_thread_default(), context->m_mainContext); + context->m_testCompleted.notifyOne(); + }, &context); + }); + + context.m_testCompleted.wait(context.m_lock); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WTF/ns/RetainPtr.mm b/Tools/TestWebKitAPI/Tests/WTF/ns/RetainPtr.mm deleted file mode 100644 index a03971c57..000000000 --- a/Tools/TestWebKitAPI/Tests/WTF/ns/RetainPtr.mm +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE 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 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/RetainPtr.h> - -namespace TestWebKitAPI { - -TEST(RetainPtr, AdoptNS) -{ - RetainPtr<NSObject> foo = adoptNS([[NSObject alloc] init]); - - EXPECT_EQ(1, CFGetRetainCount(foo.get())); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebCore/CSSParser.cpp b/Tools/TestWebKitAPI/Tests/WebCore/CSSParser.cpp new file mode 100644 index 000000000..25c450933 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebCore/CSSParser.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Igalia, S.L. 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 <WebCore/CSSParser.h> +#include <WebCore/CSSValueList.h> +#include <WebCore/StyleProperties.h> + +namespace TestWebKitAPI { + +using namespace WebCore; + +#if ENABLE(CSS_GRID_LAYOUT) +static unsigned computeNumberOfTracks(CSSValueList& valueList) +{ + unsigned numberOfTracks = 0; + for (const auto& value : valueList) { + if (value->isGridLineNamesValue()) + continue; + ++numberOfTracks; + } + return numberOfTracks; +} +#endif + +TEST(CSSPropertyParserTest, GridTrackLimits) +{ +#if ENABLE(CSS_GRID_LAYOUT) + struct { + const CSSPropertyID propertyID; + const char* input; + const size_t output; + } testCases[] = { + {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(999999, 20px);", 999999}, + {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(999999, 20px);", 999999}, + {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(1000000, 10%);", 1000000}, + {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(1000000, 10%);", 1000000}, + {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(1000000, [first] -webkit-min-content [last]);", 1000000}, + {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(1000000, [first] -webkit-min-content [last]);", 1000000}, + {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(1000001, auto);", 1000000}, + {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(1000001, auto);", 1000000}, + {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(400000, 2em minmax(10px, -webkit-max-content) 0.5fr);", 999999}, + {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(400000, 2em minmax(10px, -webkit-max-content) 0.5fr);", 999999}, + {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(600000, [first] 3vh 10% 2fr [nav] 10px auto 1fr 6em [last]);", 999999}, + {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(600000, [first] 3vh 10% 2fr [nav] 10px auto 1fr 6em [last]);", 999999}, + {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(100000000000000000000, 10% 1fr);", 1000000}, + {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(100000000000000000000, 10% 1fr);", 1000000}, + {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(100000000000000000000, 10% 5em 1fr auto auto 15px -webkit-min-content);", 999999}, + {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(100000000000000000000, 10% 5em 1fr auto auto 15px -webkit-min-content);", 999999}, + }; + + CSSParser parser(strictCSSParserContext()); + RefPtr<MutableStyleProperties> properties = MutableStyleProperties::create(); + + for (auto& testCase : testCases) { + ASSERT_TRUE(parser.parseDeclaration(properties.get(), testCase.input, nullptr, nullptr)); + RefPtr<CSSValue> value = properties->getPropertyCSSValue(testCase.propertyID); + + ASSERT_TRUE(value->isValueList()); + EXPECT_EQ(computeNumberOfTracks(*downcast<CSSValueList>(value.get())), testCase.output); + } +#endif // ENABLE(CSS_GRID_LAYOUT) +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebCore/CalculationValue.cpp b/Tools/TestWebKitAPI/Tests/WebCore/CalculationValue.cpp new file mode 100644 index 000000000..286f30fd0 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebCore/CalculationValue.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2014 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 <WebCore/CalculationValue.h> + +namespace TestWebKitAPI { + +static unsigned deletionCount; + +class CalculationDeletionTestNode : public WebCore::CalcExpressionNode { +public: + virtual ~CalculationDeletionTestNode() + { + ++deletionCount; + } + + virtual float evaluate(float) const override { return 0; } + bool operator==(const CalcExpressionNode&) const override { ASSERT_NOT_REACHED(); return false; } +}; + +static Ref<WebCore::CalculationValue> createTestValue() +{ + auto node = std::make_unique<CalculationDeletionTestNode>(); + return WebCore::CalculationValue::create(WTFMove(node), WebCore::CalculationRangeAll); +} + +TEST(CalculationValue, LengthConstruction) +{ + RefPtr<WebCore::CalculationValue> value = createTestValue(); + + EXPECT_EQ(1U, value->refCount()); + + { + WebCore::Length length(*value); + EXPECT_EQ(2U, value->refCount()); + } + + EXPECT_EQ(1U, value->refCount()); + + { + WebCore::Length lengthA(*value); + EXPECT_EQ(2U, value->refCount()); + WebCore::Length lengthB(lengthA); + EXPECT_EQ(2U, value->refCount()); + } + + EXPECT_EQ(1U, value->refCount()); + + { + WebCore::Length lengthC(*value); + EXPECT_EQ(2U, value->refCount()); + WebCore::Length lengthD(WTFMove(lengthC)); + EXPECT_EQ(2U, value->refCount()); + } + + EXPECT_EQ(1U, value->refCount()); + + EXPECT_EQ(0U, deletionCount); + value = nullptr; + EXPECT_EQ(1U, deletionCount); + deletionCount = 0; +} + +TEST(CalculationValue, LengthConstructionReleasedValue) +{ + RefPtr<WebCore::CalculationValue> value = createTestValue(); + + EXPECT_EQ(1U, value->refCount()); + + { + auto* rawValue = value.get(); + WebCore::Length length(value.releaseNonNull()); + EXPECT_EQ(1U, rawValue->refCount()); + + EXPECT_EQ(0U, deletionCount); + } + + EXPECT_EQ(1U, deletionCount); + deletionCount = 0; + + value = createTestValue(); + + { + auto* rawValue = value.get(); + WebCore::Length lengthA(value.releaseNonNull()); + EXPECT_EQ(1U, rawValue->refCount()); + WebCore::Length lengthB(lengthA); + EXPECT_EQ(1U, rawValue->refCount()); + + EXPECT_EQ(0U, deletionCount); + } + + EXPECT_EQ(1U, deletionCount); + deletionCount = 0; + + value = createTestValue(); + + { + auto* rawValue = value.get(); + WebCore::Length lengthC(value.releaseNonNull()); + EXPECT_EQ(1U, rawValue->refCount()); + WebCore::Length lengthD(WTFMove(lengthC)); + EXPECT_EQ(1U, rawValue->refCount()); + + EXPECT_EQ(0U, deletionCount); + } + + EXPECT_EQ(1U, deletionCount); + deletionCount = 0; +} + +TEST(CalculationValue, LengthAssignment) +{ + RefPtr<WebCore::CalculationValue> value = createTestValue(); + + EXPECT_EQ(1U, value->refCount()); + + { + WebCore::Length lengthA(*value); + EXPECT_EQ(2U, value->refCount()); + WebCore::Length lengthB; + lengthB = lengthA; + EXPECT_EQ(2U, value->refCount()); + } + + EXPECT_EQ(1U, value->refCount()); + + { + WebCore::Length lengthC(*value); + EXPECT_EQ(2U, value->refCount()); + WebCore::Length lengthD; + lengthD = WTFMove(lengthC); + EXPECT_EQ(2U, value->refCount()); + } + + EXPECT_EQ(1U, value->refCount()); + + EXPECT_EQ(0U, deletionCount); + value = nullptr; + EXPECT_EQ(1U, deletionCount); + deletionCount = 0; + + value = createTestValue(); + RefPtr<WebCore::CalculationValue> value2 = createTestValue(); + + EXPECT_EQ(1U, value->refCount()); + EXPECT_EQ(1U, value2->refCount()); + + { + WebCore::Length lengthE(*value); + EXPECT_EQ(2U, value->refCount()); + WebCore::Length lengthF(*value2); + EXPECT_EQ(2U, value2->refCount()); + lengthE = lengthF; + EXPECT_EQ(1U, value->refCount()); + EXPECT_EQ(2U, value2->refCount()); + } + + EXPECT_EQ(1U, value->refCount()); + EXPECT_EQ(1U, value2->refCount()); + + { + WebCore::Length lengthG(*value); + EXPECT_EQ(2U, value->refCount()); + WebCore::Length lengthH(*value2); + EXPECT_EQ(2U, value2->refCount()); + lengthG = WTFMove(lengthH); + EXPECT_EQ(1U, value->refCount()); + EXPECT_EQ(2U, value2->refCount()); + } + + EXPECT_EQ(0U, deletionCount); + value = nullptr; + EXPECT_EQ(1U, deletionCount); + value2 = nullptr; + EXPECT_EQ(2U, deletionCount); + deletionCount = 0; +} + +TEST(CalculationValue, LengthAssignmentReleasedValue) +{ + RefPtr<WebCore::CalculationValue> value = createTestValue(); + + { + auto* rawValue = value.get(); + WebCore::Length lengthA(value.releaseNonNull()); + EXPECT_EQ(1U, rawValue->refCount()); + WebCore::Length lengthB; + lengthB = lengthA; + EXPECT_EQ(1U, rawValue->refCount()); + + EXPECT_EQ(0U, deletionCount); + } + + EXPECT_EQ(1U, deletionCount); + deletionCount = 0; + + value = createTestValue(); + + { + auto* rawValue = value.get(); + WebCore::Length lengthC(value.releaseNonNull()); + EXPECT_EQ(1U, rawValue->refCount()); + WebCore::Length lengthD; + lengthD = WTFMove(lengthC); + EXPECT_EQ(1U, rawValue->refCount()); + + EXPECT_EQ(0U, deletionCount); + } + + EXPECT_EQ(1U, deletionCount); + deletionCount = 0; + + value = createTestValue(); + RefPtr<WebCore::CalculationValue> value2 = createTestValue(); + + EXPECT_EQ(1U, value->refCount()); + EXPECT_EQ(1U, value2->refCount()); + + { + auto* rawValue = value.get(); + WebCore::Length lengthE(value.releaseNonNull()); + EXPECT_EQ(1U, rawValue->refCount()); + auto* rawValue2 = value2.get(); + WebCore::Length lengthF(value2.releaseNonNull()); + EXPECT_EQ(1U, rawValue2->refCount()); + + lengthE = lengthF; + EXPECT_EQ(1U, deletionCount); + EXPECT_EQ(1U, rawValue2->refCount()); + } + + EXPECT_EQ(2U, deletionCount); + deletionCount = 0; + + value = createTestValue(); + value2 = createTestValue(); + + EXPECT_EQ(1U, value->refCount()); + EXPECT_EQ(1U, value2->refCount()); + + { + auto* rawValue = value.get(); + WebCore::Length lengthG(value.releaseNonNull()); + EXPECT_EQ(1U, rawValue->refCount()); + auto* rawValue2 = value2.get(); + WebCore::Length lengthH(value2.releaseNonNull()); + EXPECT_EQ(1U, rawValue2->refCount()); + + lengthG = WTFMove(lengthH); + EXPECT_EQ(1U, deletionCount); + EXPECT_EQ(1U, rawValue2->refCount()); + } + + EXPECT_EQ(2U, deletionCount); + deletionCount = 0; +} + +} diff --git a/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp b/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp new file mode 100644 index 000000000..d3c10afc7 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp @@ -0,0 +1,2795 @@ +/* + * Copyright (C) 2015 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 "PlatformUtilities.h" +#include <JavaScriptCore/InitializeThreading.h> +#include <WebCore/CombinedURLFilters.h> +#include <WebCore/ContentExtensionCompiler.h> +#include <WebCore/ContentExtensionError.h> +#include <WebCore/ContentExtensionsBackend.h> +#include <WebCore/DFA.h> +#include <WebCore/DFABytecodeCompiler.h> +#include <WebCore/DFABytecodeInterpreter.h> +#include <WebCore/NFA.h> +#include <WebCore/NFAToDFA.h> +#include <WebCore/ResourceLoadInfo.h> +#include <WebCore/URL.h> +#include <WebCore/URLFilterParser.h> +#include <wtf/MainThread.h> +#include <wtf/RunLoop.h> +#include <wtf/text/CString.h> +#include <wtf/text/StringBuilder.h> + +namespace WebCore { +namespace ContentExtensions { +inline std::ostream& operator<<(std::ostream& os, const ActionType& action) +{ + switch (action) { + case ActionType::BlockLoad: + return os << "ActionType::BlockLoad"; + case ActionType::BlockCookies: + return os << "ActionType::BlockCookies"; + case ActionType::CSSDisplayNoneSelector: + return os << "ActionType::CSSDisplayNone"; + case ActionType::CSSDisplayNoneStyleSheet: + return os << "ActionType::CSSDisplayNoneStyleSheet"; + case ActionType::IgnorePreviousRules: + return os << "ActionType::IgnorePreviousRules"; + case ActionType::MakeHTTPS: + return os << "ActionType::MakeHTTPS"; + case ActionType::InvalidAction: + return os << "ActionType::InvalidAction"; + } +} +} +} + +using namespace WebCore; + +namespace TestWebKitAPI { + +class ContentExtensionTest : public testing::Test { +public: + virtual void SetUp() + { + WTF::initializeMainThread(); + JSC::initializeThreading(); + RunLoop::initializeMainRunLoop(); + } +}; + +struct CompiledContentExtensionData { + Vector<ContentExtensions::SerializedActionByte> actions; + Vector<ContentExtensions::DFABytecode> filtersWithoutDomains; + Vector<ContentExtensions::DFABytecode> filtersWithDomains; + Vector<ContentExtensions::DFABytecode> domainFilters; +}; + +class InMemoryContentExtensionCompilationClient final : public ContentExtensions::ContentExtensionCompilationClient { +public: + InMemoryContentExtensionCompilationClient(CompiledContentExtensionData& data) + : m_data(data) + { + EXPECT_EQ(data.actions.size(), 0ull); + EXPECT_EQ(data.filtersWithoutDomains.size(), 0ull); + EXPECT_EQ(data.filtersWithDomains.size(), 0ull); + EXPECT_EQ(data.domainFilters.size(), 0ull); + } + + virtual void writeActions(Vector<ContentExtensions::SerializedActionByte>&& actions) override + { + EXPECT_FALSE(finalized); + EXPECT_EQ(m_data.actions.size(), 0ull); + EXPECT_EQ(m_data.filtersWithoutDomains.size(), 0ull); + EXPECT_EQ(m_data.filtersWithDomains.size(), 0ull); + EXPECT_EQ(m_data.domainFilters.size(), 0ull); + m_data.actions.appendVector(actions); + } + + virtual void writeFiltersWithoutDomainsBytecode(Vector<ContentExtensions::DFABytecode>&& bytecode) override + { + EXPECT_FALSE(finalized); + EXPECT_EQ(m_data.filtersWithDomains.size(), 0ull); + EXPECT_EQ(m_data.domainFilters.size(), 0ull); + m_data.filtersWithoutDomains.appendVector(bytecode); + } + + virtual void writeFiltersWithDomainsBytecode(Vector<ContentExtensions::DFABytecode>&& bytecode) override + { + EXPECT_FALSE(finalized); + EXPECT_EQ(m_data.domainFilters.size(), 0ull); + m_data.filtersWithDomains.appendVector(bytecode); + } + + virtual void writeDomainFiltersBytecode(Vector<ContentExtensions::DFABytecode>&& bytecode) override + { + EXPECT_FALSE(finalized); + m_data.domainFilters.appendVector(bytecode); + } + + virtual void finalize() override + { + finalized = true; + } + +private: + CompiledContentExtensionData& m_data; + bool finalized { false }; +}; + +class InMemoryCompiledContentExtension : public ContentExtensions::CompiledContentExtension { +public: + static RefPtr<InMemoryCompiledContentExtension> createFromFilter(String&& filter) + { + CompiledContentExtensionData extensionData; + InMemoryContentExtensionCompilationClient client(extensionData); + auto compilerError = ContentExtensions::compileRuleList(client, WTFMove(filter)); + if (compilerError) { + // Compiling should always succeed here. We have other tests for compile failures. + EXPECT_TRUE(false); + return nullptr; + } + + return InMemoryCompiledContentExtension::create(WTFMove(extensionData)); + } + + static RefPtr<InMemoryCompiledContentExtension> create(CompiledContentExtensionData&& data) + { + return adoptRef(new InMemoryCompiledContentExtension(WTFMove(data))); + } + + virtual ~InMemoryCompiledContentExtension() + { + } + + virtual const ContentExtensions::SerializedActionByte* actions() const override { return m_data.actions.data(); } + virtual unsigned actionsLength() const override { return m_data.actions.size(); } + virtual const ContentExtensions::DFABytecode* filtersWithoutDomainsBytecode() const override { return m_data.filtersWithoutDomains.data(); } + virtual unsigned filtersWithoutDomainsBytecodeLength() const override { return m_data.filtersWithoutDomains.size(); } + virtual const ContentExtensions::DFABytecode* filtersWithDomainsBytecode() const override { return m_data.filtersWithDomains.data(); } + virtual unsigned filtersWithDomainsBytecodeLength() const override { return m_data.filtersWithDomains.size(); } + virtual const ContentExtensions::DFABytecode* domainFiltersBytecode() const override { return m_data.domainFilters.data(); } + virtual unsigned domainFiltersBytecodeLength() const override { return m_data.domainFilters.size(); } + +private: + InMemoryCompiledContentExtension(CompiledContentExtensionData&& data) + : m_data(WTFMove(data)) + { + } + + CompiledContentExtensionData m_data; +}; + +void static testRequest(ContentExtensions::ContentExtensionsBackend contentExtensionsBackend, const ResourceLoadInfo& resourceLoadInfo, Vector<ContentExtensions::ActionType> expectedActions, bool ignorePreviousRules = false) +{ + auto actions = contentExtensionsBackend.actionsForResourceLoad(resourceLoadInfo); + unsigned expectedSize = actions.size(); + if (!ignorePreviousRules) + expectedSize--; // The last action is applying the compiled stylesheet. + + EXPECT_EQ(expectedActions.size(), expectedSize); + if (expectedActions.size() != expectedSize) + return; + + for (unsigned i = 0; i < expectedActions.size(); ++i) + EXPECT_EQ(expectedActions[i], actions[i].type()); + if (!ignorePreviousRules) + EXPECT_EQ(actions[actions.size() - 1].type(), ContentExtensions::ActionType::CSSDisplayNoneStyleSheet); +} + +static ResourceLoadInfo mainDocumentRequest(const char* url, ResourceType resourceType = ResourceType::Document) +{ + return { URL(URL(), url), URL(URL(), url), resourceType }; +} + +static ResourceLoadInfo subResourceRequest(const char* url, const char* mainDocumentURL, ResourceType resourceType = ResourceType::Document) +{ + return { URL(URL(), url), URL(URL(), mainDocumentURL), resourceType }; +} + +ContentExtensions::ContentExtensionsBackend makeBackend(const char* json) +{ + auto extension = InMemoryCompiledContentExtension::createFromFilter(json); + ContentExtensions::ContentExtensionsBackend backend; + backend.addContentExtension("testFilter", extension); + return backend; +} + +static Vector<ContentExtensions::NFA> createNFAs(ContentExtensions::CombinedURLFilters& combinedURLFilters) +{ + Vector<ContentExtensions::NFA> nfas; + + combinedURLFilters.processNFAs(std::numeric_limits<size_t>::max(), [&](ContentExtensions::NFA&& nfa) { + nfas.append(WTFMove(nfa)); + }); + + return nfas; +} + +TEST_F(ContentExtensionTest, Basic) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); +} + +TEST_F(ContentExtensionTest, SingleCharacter) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^z\"}}]"); + testRequest(matchBackend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("zttp://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"y\"}}]"); + testRequest(searchBackend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(searchBackend, mainDocumentRequest("http://webkit.org/ywebkit"), { ContentExtensions::ActionType::BlockLoad }); +} + +TEST_F(ContentExtensionTest, SingleCharacterDisjunction) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^z\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^c\"}}]"); + testRequest(matchBackend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("bttp://webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("cttp://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("dttp://webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("zttp://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"x\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"y\"}}]"); + testRequest(searchBackend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(searchBackend, mainDocumentRequest("http://webkit.org/dwebkit"), { }); + testRequest(searchBackend, mainDocumentRequest("http://webkit.org/xwebkit"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("http://webkit.org/ywebkit"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("http://webkit.org/zwebkit"), { }); +} + +TEST_F(ContentExtensionTest, RangeBasic) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"w[0-9]c\", \"url-filter-is-case-sensitive\":true}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"[A-H][a-z]cko\", \"url-filter-is-case-sensitive\":true}}]"); + + testRequest(backend, mainDocumentRequest("http://w3c.org"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("w2c://whatwg.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/w0c"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/wac"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/wAc"), { }); + + // Note: URL parsing and canonicalization lowercase the scheme and hostname. + testRequest(backend, mainDocumentRequest("Aacko://webkit.org"), { }); + testRequest(backend, mainDocumentRequest("aacko://webkit.org"), { }); + testRequest(backend, mainDocumentRequest("http://gCcko.org/"), { }); + testRequest(backend, mainDocumentRequest("http://gccko.org/"), { }); + + testRequest(backend, mainDocumentRequest("http://webkit.org/Gecko"), { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://webkit.org/gecko"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/GEcko"), { }); +} + +TEST_F(ContentExtensionTest, RangeExclusionGeneratingUniversalTransition) +{ + // Transition of the type ([^X]X) effictively transition on every input. + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[^a]+afoobar\"}}]"); + + testRequest(backend, mainDocumentRequest("http://w3c.org"), { }); + + testRequest(backend, mainDocumentRequest("http://w3c.org/foobafoobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://w3c.org/foobarfoobar"), { }); + testRequest(backend, mainDocumentRequest("http://w3c.org/FOOBAFOOBAR"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://w3c.org/FOOBARFOOBAR"), { }); + + // The character before the "a" prefix cannot be another "a". + testRequest(backend, mainDocumentRequest("http://w3c.org/aafoobar"), { }); + testRequest(backend, mainDocumentRequest("http://w3c.org/Aafoobar"), { }); + testRequest(backend, mainDocumentRequest("http://w3c.org/aAfoobar"), { }); + testRequest(backend, mainDocumentRequest("http://w3c.org/AAfoobar"), { }); +} + +TEST_F(ContentExtensionTest, PatternStartingWithGroup) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(http://whatwg\\\\.org/)?webkit\134\134.org\"}}]"); + + testRequest(backend, mainDocumentRequest("http://whatwg.org/webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://whatwg.org/webkit.org"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("http://whatwg.org/"), { }); + testRequest(backend, mainDocumentRequest("http://whatwg.org"), { }); +} + +TEST_F(ContentExtensionTest, PatternNestedGroups) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://webkit\\\\.org/(foo(bar)*)+\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/foo"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobarbar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foofoobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobarfoobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foob"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foor"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/bar"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/fobar"), { }); +} + +TEST_F(ContentExtensionTest, EmptyGroups) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://webkit\\\\.org/foo()bar\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://webkit\\\\.org/((me)()(too))\"}}]"); + testRequest(backend, mainDocumentRequest("http://webkit.org/foo"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/bar"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/me"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/too"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/metoo"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foome"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foomebar"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/mefoo"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/mefootoo"), { }); +} + +TEST_F(ContentExtensionTest, QuantifiedEmptyGroups) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://webkit\\\\.org/foo()+bar\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://webkit\\\\.org/(()*()?(target)()+)\"}}]"); + testRequest(backend, mainDocumentRequest("http://webkit.org/foo"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/bar"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/me"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/too"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/target"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foome"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foomebar"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/mefoo"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/mefootoo"), { }); +} + +TEST_F(ContentExtensionTest, MatchPastEndOfString) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".+\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foo"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobarbar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foofoobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobarfoobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foob"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foor"), { ContentExtensions::ActionType::BlockLoad }); +} + +TEST_F(ContentExtensionTest, StartOfLineAssertion) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^foobar\"}}]"); + + testRequest(backend, mainDocumentRequest("foobar://webkit.org/foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("foobars:///foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("foobarfoobar:///foobarfoobarfoobar"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("http://webkit.org/foobarfoo"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobarf"), { }); + testRequest(backend, mainDocumentRequest("http://foobar.org/"), { }); + testRequest(backend, mainDocumentRequest("http://foobar.org/"), { }); +} + +TEST_F(ContentExtensionTest, EndOfLineAssertion) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"foobar$\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("file:///foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("file:///foobarfoobarfoobar"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("http://webkit.org/foobarfoo"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobarf"), { }); +} + +TEST_F(ContentExtensionTest, EndOfLineAssertionWithInvertedCharacterSet) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[^y]$\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/a"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/Ya"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/yFoobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/y"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/Y"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobary"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/foobarY"), { }); +} + +TEST_F(ContentExtensionTest, DotDoesNotIncludeEndOfLine) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"https://webkit\\\\.org/.\"}}]"); + + testRequest(backend, mainDocumentRequest("https://webkit.org/foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("https://webkit.org/A"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/z"), { ContentExtensions::ActionType::BlockLoad }); +} + +TEST_F(ContentExtensionTest, PrefixInfixSuffixExactMatch) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"infix\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^prefix\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"suffix$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://exact\\\\.org/$\"}}]"); + + testRequest(backend, mainDocumentRequest("infix://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://infix.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/infix"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("prefix://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://prefix.org/"), { }); + testRequest(backend, mainDocumentRequest("https://webkit.org/prefix"), { }); + + testRequest(backend, mainDocumentRequest("https://webkit.org/suffix"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://suffix.org/"), { }); + testRequest(backend, mainDocumentRequest("suffix://webkit.org/"), { }); + + testRequest(backend, mainDocumentRequest("http://exact.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://exact.org/oops"), { }); +} + +TEST_F(ContentExtensionTest, DuplicatedMatchAllTermsInVariousFormat) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".*.*(.)*(.*)(.+)*(.?)*infix\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"pre(.?)+(.+)?post\"}}]"); + + testRequest(backend, mainDocumentRequest("infix://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://infix.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/infix"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("pre://webkit.org/post"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://prepost.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://pre.org/posttail"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://pre.pre/posttail"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://pre.org/posttailpost"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("https://post.org/pre"), { }); + testRequest(backend, mainDocumentRequest("https://pre.org/pre"), { }); + testRequest(backend, mainDocumentRequest("https://post.org/post"), { }); +} + +TEST_F(ContentExtensionTest, UndistinguishableActionInsidePrefixTree) +{ + // In this case, the two actions are undistinguishable. The actions of "prefix" appear inside the prefixtree + // ending at "suffix". + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"prefix\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"prefixsuffix\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("http://prefix.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/prefix"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/aaaprefixaaa"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://prefixsuffix.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/prefixsuffix"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/bbbprefixsuffixbbb"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("http://suffix.org/"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/suffix"), { }); +} + +TEST_F(ContentExtensionTest, DistinguishableActionInsidePrefixTree) +{ + // In this case, the two actions are distinguishable. + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"prefix\"}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"prefixsuffix\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("http://prefix.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/prefix"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/aaaprefixaaa"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://prefixsuffix.org/"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/prefixsuffix"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/bbbprefixsuffixbbb"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("http://suffix.org/"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/suffix"), { }); +} + +TEST_F(ContentExtensionTest, DistinguishablePrefixAreNotMerged) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"foo\\\\.org\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"bar\\\\.org\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("http://foo.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://bar.org/"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("http://foor.org/"), { }); + testRequest(backend, mainDocumentRequest("http://fooar.org/"), { }); + testRequest(backend, mainDocumentRequest("http://fooba.org/"), { }); + testRequest(backend, mainDocumentRequest("http://foob.org/"), { }); + testRequest(backend, mainDocumentRequest("http://foor.org/"), { }); + testRequest(backend, mainDocumentRequest("http://foar.org/"), { }); + testRequest(backend, mainDocumentRequest("http://foba.org/"), { }); + testRequest(backend, mainDocumentRequest("http://fob.org/"), { }); + testRequest(backend, mainDocumentRequest("http://barf.org/"), { }); + testRequest(backend, mainDocumentRequest("http://barfo.org/"), { }); + testRequest(backend, mainDocumentRequest("http://baroo.org/"), { }); + testRequest(backend, mainDocumentRequest("http://baro.org/"), { }); + testRequest(backend, mainDocumentRequest("http://baf.org/"), { }); + testRequest(backend, mainDocumentRequest("http://bafo.org/"), { }); + testRequest(backend, mainDocumentRequest("http://baoo.org/"), { }); + testRequest(backend, mainDocumentRequest("http://bao.org/"), { }); + + testRequest(backend, mainDocumentRequest("http://foo.orgbar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://oo.orgbar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://o.orgbar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://.orgbar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://rgbar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://gbar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://foo.orgar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://foo.orgr.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://foo.org.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://foo.orgorg/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://foo.orgrg/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://foo.orgg/"), { ContentExtensions::ActionType::BlockLoad }); +} + +static void compareContents(const ContentExtensions::DFABytecodeInterpreter::Actions& a, const Vector<uint64_t>& b) +{ + EXPECT_EQ(a.size(), b.size()); + for (unsigned i = 0; i < b.size(); ++i) + EXPECT_TRUE(a.contains(b[i])); +} + +TEST_F(ContentExtensionTest, SearchSuffixesWithIdenticalActionAreMerged) +{ + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("foo\\.org", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("ba\\.org", false, 0)); + + Vector<ContentExtensions::NFA> nfas = createNFAs(combinedURLFilters); + EXPECT_EQ(1ul, nfas.size()); + EXPECT_EQ(12ul, nfas.first().nodes.size()); + + ContentExtensions::DFA dfa = ContentExtensions::NFAToDFA::convert(nfas.first()); + Vector<ContentExtensions::DFABytecode> bytecode; + ContentExtensions::DFABytecodeCompiler compiler(dfa, bytecode); + compiler.compile(); + ContentExtensions::DFABytecodeInterpreter interpreter(bytecode.data(), bytecode.size()); + compareContents(interpreter.interpret("foo.org", 0), { 0 }); + compareContents(interpreter.interpret("ba.org", 0), { 0 }); + compareContents(interpreter.interpret("bar.org", 0), { }); + + compareContents(interpreter.interpret("paddingfoo.org", 0), { 0 }); + compareContents(interpreter.interpret("paddingba.org", 0), { 0 }); + compareContents(interpreter.interpret("paddingbar.org", 0), { }); +} + +TEST_F(ContentExtensionTest, SearchSuffixesWithDistinguishableActionAreNotMerged) +{ + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("foo\\.org", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("ba\\.org", false, 1)); + + Vector<ContentExtensions::NFA> nfas = createNFAs(combinedURLFilters); + + EXPECT_EQ(1ul, nfas.size()); + EXPECT_EQ(17ul, nfas.first().nodes.size()); + + ContentExtensions::DFA dfa = ContentExtensions::NFAToDFA::convert(nfas.first()); + Vector<ContentExtensions::DFABytecode> bytecode; + ContentExtensions::DFABytecodeCompiler compiler(dfa, bytecode); + compiler.compile(); + ContentExtensions::DFABytecodeInterpreter interpreter(bytecode.data(), bytecode.size()); + compareContents(interpreter.interpret("foo.org", 0), { 0 }); + compareContents(interpreter.interpret("ba.org", 0), { 1 }); + compareContents(interpreter.interpret("bar.org", 0), { }); + + compareContents(interpreter.interpret("paddingfoo.org", 0), { 0 }); + compareContents(interpreter.interpret("paddingba.org", 0), { 1 }); + compareContents(interpreter.interpret("paddingba.orgfoo.org", 0), { 1, 0 }); + compareContents(interpreter.interpret("paddingbar.org", 0), { }); +} + +TEST_F(ContentExtensionTest, DomainTriggers) +{ + auto ifDomainBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"webkit.org\"]}}]"); + testRequest(ifDomainBackend, mainDocumentRequest("http://webkit.org/test.htm"), { }); + testRequest(ifDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.htm"), { }); + testRequest(ifDomainBackend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(ifDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { }); + testRequest(ifDomainBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { }); + testRequest(ifDomainBackend, mainDocumentRequest("http://not_webkit.org/test.htm"), { }); + testRequest(ifDomainBackend, mainDocumentRequest("http://webkit.organization/test.htm"), { }); + testRequest(ifDomainBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { }); + testRequest(ifDomainBackend, mainDocumentRequest("http://webkit.organization/test.html"), { }); + + auto unlessDomainBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"unless-domain\":[\"webkit.org\"]}}]"); + testRequest(unlessDomainBackend, mainDocumentRequest("http://webkit.org/test.htm"), { }); + testRequest(unlessDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.htm"), { }); + testRequest(unlessDomainBackend, mainDocumentRequest("http://webkit.org/test.html"), { }); + testRequest(unlessDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(unlessDomainBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(unlessDomainBackend, mainDocumentRequest("http://not_webkit.org/test.htm"), { }); + testRequest(unlessDomainBackend, mainDocumentRequest("http://webkit.organization/test.htm"), { }); + testRequest(unlessDomainBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(unlessDomainBackend, mainDocumentRequest("http://webkit.organization/test.html"), { ContentExtensions::ActionType::BlockLoad }); + + auto ifDomainStarBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"*webkit.org\"]}}]"); + testRequest(ifDomainStarBackend, mainDocumentRequest("http://webkit.org/test.htm"), { }); + testRequest(ifDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.htm"), { }); + testRequest(ifDomainStarBackend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(ifDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(ifDomainStarBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(ifDomainStarBackend, mainDocumentRequest("http://not_webkit.org/test.htm"), { }); + testRequest(ifDomainStarBackend, mainDocumentRequest("http://webkit.organization/test.htm"), { }); + testRequest(ifDomainStarBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { }); + testRequest(ifDomainStarBackend, mainDocumentRequest("http://webkit.organization/test.html"), { }); + + auto unlessDomainStarBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"unless-domain\":[\"*webkit.org\"]}}]"); + testRequest(unlessDomainStarBackend, mainDocumentRequest("http://webkit.org/test.htm"), { }); + testRequest(unlessDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.htm"), { }); + testRequest(unlessDomainStarBackend, mainDocumentRequest("http://webkit.org/test.html"), { }); + testRequest(unlessDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { }); + testRequest(unlessDomainStarBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { }); + testRequest(unlessDomainStarBackend, mainDocumentRequest("http://not_webkit.org/test.htm"), { }); + testRequest(unlessDomainStarBackend, mainDocumentRequest("http://webkit.organization/test.htm"), { }); + testRequest(unlessDomainStarBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(unlessDomainStarBackend, mainDocumentRequest("http://webkit.organization/test.html"), { ContentExtensions::ActionType::BlockLoad }); + + auto ifSubDomainBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"sub1.webkit.org\"]}}]"); + testRequest(ifSubDomainBackend, mainDocumentRequest("http://webkit.org/test.html"), { }); + testRequest(ifSubDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { }); + testRequest(ifSubDomainBackend, mainDocumentRequest("http://sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(ifSubDomainBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { }); + + auto ifSubDomainStarBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"*sub1.webkit.org\"]}}]"); + testRequest(ifSubDomainStarBackend, mainDocumentRequest("http://webkit.org/test.html"), { }); + testRequest(ifSubDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { }); + testRequest(ifSubDomainStarBackend, mainDocumentRequest("http://sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(ifSubDomainStarBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + + auto unlessSubDomainBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"unless-domain\":[\"sub1.webkit.org\"]}}]"); + testRequest(unlessSubDomainBackend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(unlessSubDomainBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(unlessSubDomainBackend, mainDocumentRequest("http://sub1.webkit.org/test.html"), { }); + testRequest(unlessSubDomainBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + + auto unlessSubDomainStarBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"unless-domain\":[\"*sub1.webkit.org\"]}}]"); + testRequest(unlessSubDomainStarBackend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(unlessSubDomainStarBackend, mainDocumentRequest("http://bugs.webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(unlessSubDomainStarBackend, mainDocumentRequest("http://sub1.webkit.org/test.html"), { }); + testRequest(unlessSubDomainStarBackend, mainDocumentRequest("http://sub2.sub1.webkit.org/test.html"), { }); + + auto combinedBackend1 = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test_block_load\", \"if-domain\":[\"webkit.org\"]}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"test_block_cookies\", \"unless-domain\":[\"webkit.org\"]}}]"); + testRequest(combinedBackend1, mainDocumentRequest("http://webkit.org"), { }); + testRequest(combinedBackend1, mainDocumentRequest("http://not_webkit.org"), { }); + testRequest(combinedBackend1, mainDocumentRequest("http://webkit.org/test_block_load.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(combinedBackend1, subResourceRequest("http://whatwg.org/test_block_load.html", "http://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(combinedBackend1, subResourceRequest("http://whatwg.org/shouldnt_match.html", "http://webkit.org/"), { }); + testRequest(combinedBackend1, subResourceRequest("http://whatwg.org/test_block_load.html", "http://not_webkit.org/"), { }); + testRequest(combinedBackend1, subResourceRequest("http://whatwg.org/shouldnt_match.html", "http://not_webkit.org/"), { }); + testRequest(combinedBackend1, mainDocumentRequest("http://webkit.org/test_block_cookies.html"), { }); + testRequest(combinedBackend1, subResourceRequest("http://whatwg.org/test_block_cookies.html", "http://webkit.org/"), { }); + testRequest(combinedBackend1, subResourceRequest("http://whatwg.org/shouldnt_match.html", "http://webkit.org/"), { }); + testRequest(combinedBackend1, subResourceRequest("http://whatwg.org/test_block_cookies.html", "http://not_webkit.org/path/to/main/document.html"), { ContentExtensions::ActionType::BlockCookies }); + testRequest(combinedBackend1, subResourceRequest("http://whatwg.org/shouldnt_match.html", "http://not_webkit.org/"), { }); + + auto combinedBackend2 = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test_block_load\\\\.html\", \"if-domain\":[\"webkit.org\"]}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"test_block_cookies\\\\.html\", \"unless-domain\":[\"w3c.org\"]}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"test_css\\\\.html\"}}]"); + testRequest(combinedBackend2, mainDocumentRequest("http://webkit.org/test_css.html"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(combinedBackend2, mainDocumentRequest("http://webkit.org/test_css.htm"), { }); + testRequest(combinedBackend2, mainDocumentRequest("http://webkit.org/test_block_load.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(combinedBackend2, mainDocumentRequest("http://not_webkit.org/test_block_load.html"), { }); + testRequest(combinedBackend2, mainDocumentRequest("http://not_webkit.org/test_css.html"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(combinedBackend2, mainDocumentRequest("http://webkit.org/TEST_CSS.hTmL/test_block_load.html"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad}); + testRequest(combinedBackend2, mainDocumentRequest("http://w3c.org/test_css.html"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(combinedBackend2, mainDocumentRequest("http://w3c.org/test_block_load.html"), { }); + testRequest(combinedBackend2, mainDocumentRequest("http://w3c.org/test_block_cookies.html"), { }); + testRequest(combinedBackend2, mainDocumentRequest("http://w3c.org/test_css.html/test_block_cookies.html"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(combinedBackend2, mainDocumentRequest("http://not_w3c.org/test_block_cookies.html"), { ContentExtensions::ActionType::BlockCookies }); + testRequest(combinedBackend2, mainDocumentRequest("http://not_w3c.org/test_css.html/test_block_cookies.html"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockCookies }); + + auto ifDomainWithFlagsBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\", \"if-domain\":[\"webkit.org\"],\"resource-type\":[\"image\"]}}]"); + testRequest(ifDomainWithFlagsBackend, mainDocumentRequest("http://webkit.org/test.html"), { }); + testRequest(ifDomainWithFlagsBackend, mainDocumentRequest("http://webkit.org/test.png", ResourceType::Image), { ContentExtensions::ActionType::BlockLoad }); + testRequest(ifDomainWithFlagsBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { }); + testRequest(ifDomainWithFlagsBackend, mainDocumentRequest("http://not_webkit.org/test.png", ResourceType::Image), { }); + + auto unlessDomainWithFlagsBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\", \"unless-domain\":[\"webkit.org\"],\"resource-type\":[\"image\"]}}]"); + testRequest(unlessDomainWithFlagsBackend, mainDocumentRequest("http://webkit.org/test.html"), { }); + testRequest(unlessDomainWithFlagsBackend, mainDocumentRequest("http://webkit.org/test.png", ResourceType::Image), { }); + testRequest(unlessDomainWithFlagsBackend, mainDocumentRequest("http://not_webkit.org/test.html"), { }); + testRequest(unlessDomainWithFlagsBackend, mainDocumentRequest("http://not_webkit.org/test.png", ResourceType::Image), { ContentExtensions::ActionType::BlockLoad }); + + // Domains should not be interepted as regular expressions. + auto domainRegexBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"we?bkit.org\"]}}]"); + testRequest(domainRegexBackend, mainDocumentRequest("http://webkit.org/test.html"), { }); + testRequest(domainRegexBackend, mainDocumentRequest("http://wbkit.org/test.html"), { }); + + auto multipleIfDomainsBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"webkit.org\", \"w3c.org\"]}}]"); + testRequest(multipleIfDomainsBackend, mainDocumentRequest("http://webkit.org/test.htm"), { }); + testRequest(multipleIfDomainsBackend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(multipleIfDomainsBackend, mainDocumentRequest("http://w3c.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(multipleIfDomainsBackend, mainDocumentRequest("http://whatwg.org/test.html"), { }); + + auto multipleUnlessDomainsBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"unless-domain\":[\"webkit.org\", \"w3c.org\"]}}]"); + testRequest(multipleUnlessDomainsBackend, mainDocumentRequest("http://webkit.org/test.htm"), { }); + testRequest(multipleUnlessDomainsBackend, mainDocumentRequest("http://webkit.org/test.html"), { }); + testRequest(multipleUnlessDomainsBackend, mainDocumentRequest("http://w3c.org/test.html"), { }); + testRequest(multipleUnlessDomainsBackend, mainDocumentRequest("http://whatwg.org/test.html"), { ContentExtensions::ActionType::BlockLoad }); + + // FIXME: Add and test domain-specific popup-only blocking (with layout tests). +} + +TEST_F(ContentExtensionTest, DomainTriggersAlongMergedActions) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"test\\\\.html\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"test\\\\.html\", \"if-domain\":[\"webkit.org\"]}}," + "{\"action\":{\"type\":\"css-display-none\", \"selector\": \"*\"},\"trigger\":{\"url-filter\":\"trigger-on-scripts\\\\.html\",\"resource-type\":[\"script\"]}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"ignore-previous\",\"resource-type\":[\"image\"]}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"except-this\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/test.htm"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/test.html"), { ContentExtensions::ActionType::BlockLoad, ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/test.html"), { ContentExtensions::ActionType::BlockCookies }); + + testRequest(backend, mainDocumentRequest("http://notwebkit.org/trigger-on-scripts.html"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/trigger-on-scripts.html"), { }); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/trigger-on-scripts.html", ResourceType::Script), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(backend, mainDocumentRequest("http://webkit.org/trigger-on-scripts.html", ResourceType::Script), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/trigger-on-scripts.html.test.html", ResourceType::Script), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://webkit.org/trigger-on-scripts.html.test.html", ResourceType::Script), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad, ContentExtensions::ActionType::BlockCookies }); + + testRequest(backend, mainDocumentRequest("http://notwebkit.org/ignore-previous-trigger-on-scripts.html"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/ignore-previous-trigger-on-scripts.html"), { }); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/ignore-previous-trigger-on-scripts.html", ResourceType::Script), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(backend, mainDocumentRequest("http://webkit.org/ignore-previous-trigger-on-scripts.html", ResourceType::Script), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/ignore-previous-trigger-on-scripts.html.test.html", ResourceType::Script), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://webkit.org/ignore-previous-trigger-on-scripts.html.test.html", ResourceType::Script), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad, ContentExtensions::ActionType::BlockCookies }); + + testRequest(backend, mainDocumentRequest("http://notwebkit.org/ignore-previous-trigger-on-scripts.html", ResourceType::Image), { }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/ignore-previous-trigger-on-scripts.html", ResourceType::Image), { }, true); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/ignore-previous-trigger-on-scripts.html.test.html", ResourceType::Image), { }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/ignore-previous-trigger-on-scripts.html.test.html", ResourceType::Image), { }, true); + + testRequest(backend, mainDocumentRequest("http://notwebkit.org/except-this-ignore-previous-trigger-on-scripts.html"), { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://webkit.org/except-this-ignore-previous-trigger-on-scripts.html"), { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/except-this-ignore-previous-trigger-on-scripts.html.test.html"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://webkit.org/except-this-ignore-previous-trigger-on-scripts.html.test.html"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::BlockLoad, ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/except-this-ignore-previous-trigger-on-scripts.html", ResourceType::Image), { ContentExtensions::ActionType::BlockCookies }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/except-this-ignore-previous-trigger-on-scripts.html", ResourceType::Image), { ContentExtensions::ActionType::BlockCookies }, true); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/except-this-ignore-previous-trigger-on-scripts.html.test.html", ResourceType::Image), { ContentExtensions::ActionType::BlockCookies }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/except-this-ignore-previous-trigger-on-scripts.html.test.html", ResourceType::Image), { ContentExtensions::ActionType::BlockCookies }, true); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/except-this-ignore-previous-trigger-on-scripts.html", ResourceType::Script), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(backend, mainDocumentRequest("http://webkit.org/except-this-ignore-previous-trigger-on-scripts.html", ResourceType::Script), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(backend, mainDocumentRequest("http://notwebkit.org/except-this-ignore-previous-trigger-on-scripts.html.test.html", ResourceType::Script), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://webkit.org/except-this-ignore-previous-trigger-on-scripts.html.test.html", ResourceType::Script), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad, ContentExtensions::ActionType::BlockCookies }); + +} + +TEST_F(ContentExtensionTest, MultipleExtensions) +{ + auto extension1 = InMemoryCompiledContentExtension::createFromFilter("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block_load\"}}]"); + auto extension2 = InMemoryCompiledContentExtension::createFromFilter("[{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"block_cookies\"}}]"); + ContentExtensions::ContentExtensionsBackend backend; + backend.addContentExtension("testFilter1", extension1); + backend.addContentExtension("testFilter2", extension2); + + // These each have two display:none stylesheets. The second one is implied by using the default parameter ignorePreviousRules = false. + testRequest(backend, mainDocumentRequest("http://webkit.org"), { ContentExtensions::ActionType::CSSDisplayNoneStyleSheet }); + testRequest(backend, mainDocumentRequest("http://webkit.org/block_load.html"), { ContentExtensions::ActionType::CSSDisplayNoneStyleSheet, ContentExtensions::ActionType::BlockLoad}); + testRequest(backend, mainDocumentRequest("http://webkit.org/block_cookies.html"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::CSSDisplayNoneStyleSheet}); + testRequest(backend, mainDocumentRequest("http://webkit.org/block_load/block_cookies.html"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::CSSDisplayNoneStyleSheet, ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/block_cookies/block_load.html"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::CSSDisplayNoneStyleSheet, ContentExtensions::ActionType::BlockLoad }); + + auto ignoreExtension1 = InMemoryCompiledContentExtension::createFromFilter("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block_load\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"ignore1\"}}]"); + auto ignoreExtension2 = InMemoryCompiledContentExtension::createFromFilter("[{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"block_cookies\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"ignore2\"}}]"); + ContentExtensions::ContentExtensionsBackend backendWithIgnore; + backendWithIgnore.addContentExtension("testFilter1", ignoreExtension1); + backendWithIgnore.addContentExtension("testFilter2", ignoreExtension2); + + testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org"), { ContentExtensions::ActionType::CSSDisplayNoneStyleSheet, ContentExtensions::ActionType::CSSDisplayNoneStyleSheet }, true); + testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org/block_load/ignore1.html"), { ContentExtensions::ActionType::CSSDisplayNoneStyleSheet }, true); + testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org/block_cookies/ignore1.html"), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::CSSDisplayNoneStyleSheet}, true); + testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org/block_load/ignore2.html"), { ContentExtensions::ActionType::BlockLoad, ContentExtensions::ActionType::CSSDisplayNoneStyleSheet }, true); + testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org/block_cookies/ignore2.html"), { ContentExtensions::ActionType::CSSDisplayNoneStyleSheet}, true); + testRequest(backendWithIgnore, mainDocumentRequest("http://webkit.org/block_load/block_cookies/ignore1/ignore2.html"), { }, true); +} + +TEST_F(ContentExtensionTest, TermsKnownToMatchAnything) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre1.*post1$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre2(.*)post2$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre3(.*)?post3$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre4(.*)+post4$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre5(.*)*post5$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre6(.)*post6$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre7(.+)*post7$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre8(.?)*post8$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre9(.+)?post9$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^pre0(.?)+post0$\"}}]"); + + testRequest(backend, mainDocumentRequest("pre1://webkit.org/post1"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("pre2://webkit.org/post2"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("pre3://webkit.org/post3"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("pre4://webkit.org/post4"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("pre5://webkit.org/post5"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("pre6://webkit.org/post6"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("pre7://webkit.org/post7"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("pre8://webkit.org/post8"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("pre9://webkit.org/post9"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("pre0://webkit.org/post0"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("pre1://webkit.org/post2"), { }); + testRequest(backend, mainDocumentRequest("pre2://webkit.org/post3"), { }); + testRequest(backend, mainDocumentRequest("pre3://webkit.org/post4"), { }); + testRequest(backend, mainDocumentRequest("pre4://webkit.org/post5"), { }); + testRequest(backend, mainDocumentRequest("pre5://webkit.org/post6"), { }); + testRequest(backend, mainDocumentRequest("pre6://webkit.org/post7"), { }); + testRequest(backend, mainDocumentRequest("pre7://webkit.org/post8"), { }); + testRequest(backend, mainDocumentRequest("pre8://webkit.org/post9"), { }); + testRequest(backend, mainDocumentRequest("pre9://webkit.org/post0"), { }); + testRequest(backend, mainDocumentRequest("pre0://webkit.org/post1"), { }); + + testRequest(backend, mainDocumentRequest("pre0://webkit.org/post1"), { }); + testRequest(backend, mainDocumentRequest("pre1://webkit.org/post2"), { }); + testRequest(backend, mainDocumentRequest("pre2://webkit.org/post3"), { }); + testRequest(backend, mainDocumentRequest("pre3://webkit.org/post4"), { }); + testRequest(backend, mainDocumentRequest("pre4://webkit.org/post5"), { }); + testRequest(backend, mainDocumentRequest("pre5://webkit.org/post6"), { }); + testRequest(backend, mainDocumentRequest("pre6://webkit.org/post7"), { }); + testRequest(backend, mainDocumentRequest("pre7://webkit.org/post8"), { }); + testRequest(backend, mainDocumentRequest("pre8://webkit.org/post9"), { }); + testRequest(backend, mainDocumentRequest("pre9://webkit.org/post0"), { }); +} + +TEST_F(ContentExtensionTest, TrailingDotStar) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"foo.*$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"bar(.*)$\"}}]"); + + testRequest(backend, mainDocumentRequest("https://webkit.org/"), { }); + + testRequest(backend, mainDocumentRequest("foo://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://foo.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.foo/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/foo"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("bar://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://bar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.bar/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/bar"), { ContentExtensions::ActionType::BlockLoad }); +} + +TEST_F(ContentExtensionTest, TrailingTermsCarryingNoData) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"foob?a?r?\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"bazo(ok)?a?$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"cats*$\"}}]"); + + testRequest(backend, mainDocumentRequest("https://webkit.org/"), { }); + + // Anything is fine after foo. + testRequest(backend, mainDocumentRequest("https://webkit.org/foo"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/foob"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/fooc"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/fooba"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/foobar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/foobar-stuff"), { ContentExtensions::ActionType::BlockLoad }); + + // Bazooka has to be at the tail without any character not defined by the filter. + testRequest(backend, mainDocumentRequest("https://webkit.org/baz"), { }); + testRequest(backend, mainDocumentRequest("https://webkit.org/bazo"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/bazoa"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/bazob"), { }); + testRequest(backend, mainDocumentRequest("https://webkit.org/bazoo"), { }); + testRequest(backend, mainDocumentRequest("https://webkit.org/bazook"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/bazookb"), { }); + testRequest(backend, mainDocumentRequest("https://webkit.org/bazooka"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/bazookaa"), { }); + + // The pattern must finish with cat, with any number of 's' following it, but no other character. + testRequest(backend, mainDocumentRequest("https://cat.org/"), { }); + testRequest(backend, mainDocumentRequest("https://cats.org/"), { }); + testRequest(backend, mainDocumentRequest("https://webkit.org/cat"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/cats"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/catss"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/catsss"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/catso"), { }); +} + +TEST_F(ContentExtensionTest, UselessTermsMatchingEverythingAreEliminated) +{ + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern(".*web", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(.*)web", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(.)*web", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(.+)*web", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(.?)*web", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(.+)?web", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(.?)+web", false, 0)); + + Vector<ContentExtensions::NFA> nfas = createNFAs(combinedURLFilters); + EXPECT_EQ(1ul, nfas.size()); + EXPECT_EQ(7ul, nfas.first().nodes.size()); + + ContentExtensions::DFA dfa = ContentExtensions::NFAToDFA::convert(nfas.first()); + Vector<ContentExtensions::DFABytecode> bytecode; + ContentExtensions::DFABytecodeCompiler compiler(dfa, bytecode); + compiler.compile(); + ContentExtensions::DFABytecodeInterpreter interpreter(bytecode.data(), bytecode.size()); + compareContents(interpreter.interpret("eb", 0), { }); + compareContents(interpreter.interpret("we", 0), { }); + compareContents(interpreter.interpret("weeb", 0), { }); + compareContents(interpreter.interpret("web", 0), { 0 }); + compareContents(interpreter.interpret("wweb", 0), { 0 }); + compareContents(interpreter.interpret("wwebb", 0), { 0 }); + compareContents(interpreter.interpret("http://theweb.com/", 0), { 0 }); +} + +TEST_F(ContentExtensionTest, LoadType) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"load-type\":[\"third-party\"]}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"whatwg.org\",\"load-type\":[\"first-party\"]}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"alwaysblock.pdf\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org"), { }); + testRequest(backend, {URL(URL(), "http://webkit.org"), URL(URL(), "http://not_webkit.org"), ResourceType::Document}, { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("http://whatwg.org"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, {URL(URL(), "http://whatwg.org"), URL(URL(), "http://not_whatwg.org"), ResourceType::Document}, { }); + + testRequest(backend, mainDocumentRequest("http://foobar.org/alwaysblock.pdf"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, {URL(URL(), "http://foobar.org/alwaysblock.pdf"), URL(URL(), "http://not_foobar.org/alwaysblock.pdf"), ResourceType::Document}, { ContentExtensions::ActionType::BlockLoad }); +} + +TEST_F(ContentExtensionTest, ResourceType) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block_all_types.org\",\"resource-type\":[\"document\",\"image\",\"style-sheet\",\"script\",\"font\",\"raw\",\"svg-document\",\"media\",\"popup\"]}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"block_only_images\",\"resource-type\":[\"image\"]}}]"); + + testRequest(backend, mainDocumentRequest("http://block_all_types.org", ResourceType::Document), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_all_types.org", ResourceType::Image), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_all_types.org", ResourceType::StyleSheet), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_all_types.org", ResourceType::Script), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_all_types.org", ResourceType::Font), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_all_types.org", ResourceType::Raw), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_all_types.org", ResourceType::SVGDocument), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_all_types.org", ResourceType::Media), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_all_types.org", ResourceType::Popup), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_only_images.org", ResourceType::Image), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://block_only_images.org", ResourceType::Document), { }); +} + +TEST_F(ContentExtensionTest, ResourceAndLoadType) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"BlockOnlyIfThirdPartyAndScript\",\"resource-type\":[\"script\"],\"load-type\":[\"third-party\"]}}]"); + + testRequest(backend, subResourceRequest("http://webkit.org/BlockOnlyIfThirdPartyAndScript.js", "http://webkit.org", ResourceType::Script), { }); + testRequest(backend, subResourceRequest("http://webkit.org/BlockOnlyIfThirdPartyAndScript.png", "http://not_webkit.org", ResourceType::Image), { }); + testRequest(backend, subResourceRequest("http://webkit.org/BlockOnlyIfThirdPartyAndScript.js", "http://not_webkit.org", ResourceType::Script), { ContentExtensions::ActionType::BlockLoad }); +} + +TEST_F(ContentExtensionTest, ResourceOrLoadTypeMatchingEverything) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".*\",\"resource-type\":[\"image\"]}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\".*\",\"load-type\":[\"third-party\"]}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\".*\",\"load-type\":[\"first-party\"]}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org"), { }, true); + testRequest(backend, {URL(URL(), "http://webkit.org"), URL(URL(), "http://not_webkit.org"), ResourceType::Document}, { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, {URL(URL(), "http://webkit.org"), URL(URL(), "http://not_webkit.org"), ResourceType::Image}, { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::BlockLoad }); +} + +TEST_F(ContentExtensionTest, WideNFA) +{ + // Make an NFA with about 1400 nodes that won't be combined. + StringBuilder ruleList; + ruleList.append('['); + for (char c1 = 'A'; c1 <= 'Z'; ++c1) { + for (char c2 = 'A'; c2 <= 'C'; ++c2) { + for (char c3 = 'A'; c3 <= 'C'; ++c3) { + if (c1 != 'A' || c2 != 'A' || c3 != 'A') + ruleList.append(','); + ruleList.append("{\"action\":{\"type\":\""); + + // Make every other rule ignore-previous-rules to not combine actions. + if (!((c1 + c2 + c3) % 2)) + ruleList.append("ignore-previous-rules"); + else { + ruleList.append("css-display-none"); + ruleList.append("\",\"selector\":\""); + ruleList.append(c1); + ruleList.append(c2); + ruleList.append(c3); + } + ruleList.append("\"},\"trigger\":{\"url-filter\":\".*"); + ruleList.append(c1); + ruleList.append(c2); + ruleList.append(c3); + ruleList.append("\", \"url-filter-is-case-sensitive\":true}}"); + } + } + } + ruleList.append(']'); + + auto backend = makeBackend(ruleList.toString().utf8().data()); + + testRequest(backend, mainDocumentRequest("http://webkit.org/AAA"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(backend, mainDocumentRequest("http://webkit.org/YAA"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(backend, mainDocumentRequest("http://webkit.org/ZAA"), { }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/LAA/AAA"), { }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/LAA/MAA"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { }); +} + +#ifdef NDEBUG +static uint64_t expectedIndex(char c, unsigned position) +{ + uint64_t index = c - 'A'; + for (unsigned i = 1; i < position; ++i) + index *= (i == 1) ? ('C' - 'A' + 1) : ('Z' - 'A' + 1); + return index; +} +#endif + +TEST_F(ContentExtensionTest, LargeJumps) +{ +// A large test like this is necessary to test 24 and 32 bit jumps, but it's so large it times out in debug builds. +#ifdef NDEBUG + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + + uint64_t patternId = 0; + for (char c1 = 'A'; c1 <= 'Z'; ++c1) { + for (char c2 = 'A'; c2 <= 'Z'; ++c2) { + for (char c3 = 'A'; c3 <= 'Z'; ++c3) { + for (char c4 = 'A'; c4 <= 'C'; ++c4) { + StringBuilder pattern; + pattern.append(c1); + pattern.append(c2); + pattern.append(c3); + pattern.append(c4); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern(pattern.toString(), true, patternId++)); + } + } + } + } + + Vector<ContentExtensions::NFA> nfas; + combinedURLFilters.processNFAs(std::numeric_limits<size_t>::max(), [&](ContentExtensions::NFA&& nfa) { + nfas.append(WTFMove(nfa)); + }); + EXPECT_EQ(nfas.size(), 1ull); + + Vector<ContentExtensions::DFA> dfas; + for (auto& nfa : nfas) + dfas.append(ContentExtensions::NFAToDFA::convert(nfa)); + EXPECT_EQ(dfas.size(), 1ull); + + Vector<ContentExtensions::DFABytecode> combinedBytecode; + for (const auto& dfa : dfas) { + Vector<ContentExtensions::DFABytecode> bytecode; + ContentExtensions::DFABytecodeCompiler compiler(dfa, bytecode); + compiler.compile(); + combinedBytecode.appendVector(bytecode); + } + + ContentExtensions::DFABytecodeInterpreter interpreter(&combinedBytecode[0], combinedBytecode.size()); + + patternId = 0; + for (char c1 = 'A'; c1 <= 'Z'; ++c1) { + for (char c2 = 'A'; c2 <= 'Z'; ++c2) { + for (char c3 = 'A'; c3 <= 'Z'; ++c3) { + for (char c4 = 'A'; c4 <= 'C'; ++c4) { + StringBuilder pattern; + pattern.append(c1); + pattern.append(c2); + pattern.append(c3); + // Test different jumping patterns distributed throughout the DFA: + switch ((c1 + c2 + c3 + c4) % 4) { + case 0: + // This should not match. + pattern.append('x'); + pattern.append(c4); + break; + case 1: + // This should jump back to the root, then match. + pattern.append('x'); + pattern.append(c1); + pattern.append(c2); + pattern.append(c3); + pattern.append(c4); + break; + case 2: + // This should match at the end of the string. + pattern.append(c4); + break; + case 3: + // This should match then jump back to the root. + pattern.append(c4); + pattern.append('x'); + break; + } + auto matches = interpreter.interpret(pattern.toString().utf8(), 0); + switch ((c1 + c2 + c3 + c4) % 4) { + case 0: + compareContents(matches, { }); + break; + case 1: + case 2: + case 3: + compareContents(matches, {patternId}); + break; + } + patternId++; + } + } + } + } + + compareContents(interpreter.interpret("CAAAAx", 0), {expectedIndex('C', 4), expectedIndex('A', 1)}); + compareContents(interpreter.interpret("KAAAAx", 0), {expectedIndex('K', 4), expectedIndex('A', 1)}); + compareContents(interpreter.interpret("AKAAAx", 0), {expectedIndex('K', 3), expectedIndex('K', 4)}); + compareContents(interpreter.interpret("AKxAAAAx", 0), {expectedIndex('A', 1)}); + compareContents(interpreter.interpret("AKAxAAAAx", 0), {expectedIndex('A', 1)}); + compareContents(interpreter.interpret("AKAxZKAxZKZxAAAAx", 0), {expectedIndex('A', 1)}); + compareContents(interpreter.interpret("ZAAAA", 0), {expectedIndex('Z', 4), expectedIndex('A', 1)}); + compareContents(interpreter.interpret("ZZxZAAAB", 0), {expectedIndex('Z', 4), expectedIndex('B', 1)}); +#endif +} + +TEST_F(ContentExtensionTest, DeepNFA) +{ + const unsigned size = 100000; + + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + + // FIXME: DFAToNFA::convert takes way too long on these deep NFAs. We should optimize for that case. + + StringBuilder lotsOfAs; + for (unsigned i = 0; i < size; ++i) + lotsOfAs.append('A'); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern(lotsOfAs.toString().utf8().data(), false, 0)); + + // FIXME: Yarr ought to be able to handle 2MB regular expressions. + StringBuilder tooManyAs; + for (unsigned i = 0; i < size * 20; ++i) + tooManyAs.append('A'); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::YarrError, parser.addPattern(tooManyAs.toString().utf8().data(), false, 0)); + + StringBuilder nestedGroups; + for (unsigned i = 0; i < size; ++i) + nestedGroups.append('('); + for (unsigned i = 0; i < size; ++i) + nestedGroups.append("B)"); + // FIXME: Add nestedGroups. Right now it also takes too long. It should be optimized. + + // This should not crash and not timeout. + EXPECT_EQ(1ul, createNFAs(combinedURLFilters).size()); +} + +void checkCompilerError(const char* json, std::error_code expectedError) +{ + CompiledContentExtensionData extensionData; + InMemoryContentExtensionCompilationClient client(extensionData); + std::error_code compilerError = ContentExtensions::compileRuleList(client, json); + EXPECT_EQ(compilerError.value(), expectedError.value()); + if (compilerError.value()) + EXPECT_STREQ(compilerError.category().name(), expectedError.category().name()); +} + +TEST_F(ContentExtensionTest, MatchesEverything) +{ + // Only css-display-none rules with triggers that match everything, no domain rules, and no flags + // should go in the global display:none stylesheet. css-display-none rules with domain rules or flags + // are applied separately on pages where they apply. + auto backend1 = makeBackend("[{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\".*\"}}]"); + EXPECT_TRUE(nullptr != backend1.globalDisplayNoneStyleSheet(ASCIILiteral("testFilter"))); + testRequest(backend1, mainDocumentRequest("http://webkit.org"), { }); // Selector is in global stylesheet. + + auto backend2 = makeBackend("[{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\".*\",\"if-domain\":[\"webkit.org\"]}}]"); + EXPECT_EQ(nullptr, backend2.globalDisplayNoneStyleSheet(ASCIILiteral("testFilter"))); + testRequest(backend2, mainDocumentRequest("http://webkit.org"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(backend2, mainDocumentRequest("http://w3c.org"), { }); + + auto backend3 = makeBackend("[{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\".*\",\"unless-domain\":[\"webkit.org\"]}}]"); + EXPECT_EQ(nullptr, backend3.globalDisplayNoneStyleSheet(ASCIILiteral("testFilter"))); + testRequest(backend3, mainDocumentRequest("http://webkit.org"), { }); + testRequest(backend3, mainDocumentRequest("http://w3c.org"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + + auto backend4 = makeBackend("[{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\".*\",\"load-type\":[\"third-party\"]}}]"); + EXPECT_EQ(nullptr, backend4.globalDisplayNoneStyleSheet(ASCIILiteral("testFilter"))); + testRequest(backend4, mainDocumentRequest("http://webkit.org"), { }); + testRequest(backend4, subResourceRequest("http://not_webkit.org", "http://webkit.org"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + + // css-display-none rules after ignore-previous-rules should not be put in the default stylesheet. + auto backend5 = makeBackend("[{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\".*\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\".*\"}}]"); + EXPECT_EQ(nullptr, backend5.globalDisplayNoneStyleSheet(ASCIILiteral("testFilter"))); + testRequest(backend5, mainDocumentRequest("http://webkit.org"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }, true); + + auto backend6 = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".*\",\"if-domain\":[\"webkit.org\",\"*w3c.org\"],\"resource-type\":[\"document\",\"script\"]}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"ignore\",\"if-domain\":[\"*webkit.org\",\"w3c.org\"]}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\".*\",\"unless-domain\":[\"webkit.org\",\"whatwg.org\"],\"resource-type\":[\"script\",\"image\"],\"load-type\":[\"third-party\"]}}]"); + EXPECT_EQ(nullptr, backend6.globalDisplayNoneStyleSheet(ASCIILiteral("testFilter"))); + testRequest(backend6, mainDocumentRequest("http://webkit.org"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend6, mainDocumentRequest("http://w3c.org"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend6, mainDocumentRequest("http://whatwg.org"), { }); + testRequest(backend6, mainDocumentRequest("http://sub.webkit.org"), { }); + testRequest(backend6, mainDocumentRequest("http://sub.w3c.org"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend6, mainDocumentRequest("http://sub.whatwg.org"), { }); + testRequest(backend6, mainDocumentRequest("http://webkit.org/ignore"), { }, true); + testRequest(backend6, mainDocumentRequest("http://w3c.org/ignore"), { }, true); + testRequest(backend6, mainDocumentRequest("http://whatwg.org/ignore"), { }); + testRequest(backend6, mainDocumentRequest("http://sub.webkit.org/ignore"), { }, true); + testRequest(backend6, mainDocumentRequest("http://sub.w3c.org/ignore"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend6, mainDocumentRequest("http://sub.whatwg.org/ignore"), { }); + testRequest(backend6, subResourceRequest("http://example.com/image.png", "http://webkit.org/", ResourceType::Image), { }); + testRequest(backend6, subResourceRequest("http://example.com/image.png", "http://w3c.org/", ResourceType::Image), { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend6, subResourceRequest("http://example.com/doc.html", "http://webkit.org/", ResourceType::Document), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend6, subResourceRequest("http://example.com/script.js", "http://webkit.org/", ResourceType::Script), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend6, subResourceRequest("http://example.com/script.js", "http://w3c.org/", ResourceType::Script), { ContentExtensions::ActionType::BlockCookies, ContentExtensions::ActionType::BlockLoad }); + testRequest(backend6, subResourceRequest("http://example.com/script.js", "http://example.com/", ResourceType::Script), { }); + testRequest(backend6, subResourceRequest("http://example.com/ignore/image.png", "http://webkit.org/", ResourceType::Image), { }, true); + testRequest(backend6, subResourceRequest("http://example.com/ignore/image.png", "http://example.com/", ResourceType::Image), { }); + testRequest(backend6, subResourceRequest("http://example.com/ignore/image.png", "http://example.org/", ResourceType::Image), { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend6, subResourceRequest("http://example.com/doc.html", "http://example.org/", ResourceType::Document), { }); + testRequest(backend6, subResourceRequest("http://example.com/", "http://example.com/", ResourceType::Font), { }); + testRequest(backend6, subResourceRequest("http://example.com/ignore", "http://webkit.org/", ResourceType::Image), { }, true); + testRequest(backend6, subResourceRequest("http://example.com/ignore", "http://webkit.org/", ResourceType::Font), { }, true); + testRequest(backend6, subResourceRequest("http://example.com/", "http://example.com/", ResourceType::Script), { }); + testRequest(backend6, subResourceRequest("http://example.com/ignore", "http://example.com/", ResourceType::Script), { }); +} + +TEST_F(ContentExtensionTest, InvalidJSON) +{ + checkCompilerError("[", ContentExtensions::ContentExtensionError::JSONInvalid); + checkCompilerError("123", ContentExtensions::ContentExtensionError::JSONTopLevelStructureNotAnObject); + checkCompilerError("{}", ContentExtensions::ContentExtensionError::JSONTopLevelStructureNotAnArray); + // FIXME: Add unit test for JSONInvalidRule if that is possible to hit. + checkCompilerError("[]", ContentExtensions::ContentExtensionError::JSONContainsNoRules); + + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":5}]", + ContentExtensions::ContentExtensionError::JSONInvalidTrigger); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"\"}}]", + ContentExtensions::ContentExtensionError::JSONInvalidURLFilterInTrigger); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":{}}}]", + ContentExtensions::ContentExtensionError::JSONInvalidURLFilterInTrigger); + + // FIXME: Add unit test for JSONInvalidObjectInTriggerFlagsArray if that is possible to hit. + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"load-type\":{}}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"load-type\":[\"invalid\"]}}]", + ContentExtensions::ContentExtensionError::JSONInvalidStringInTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"load-type\":[5]}}]", + ContentExtensions::ContentExtensionError::JSONInvalidStringInTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"load-type\":5}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"load-type\":\"first-party\"}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"load-type\":null}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"load-type\":false}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"resource-type\":{}}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"resource-type\":[\"invalid\"]}}]", + ContentExtensions::ContentExtensionError::JSONInvalidStringInTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"resource-type\":[5]}}]", + ContentExtensions::ContentExtensionError::JSONInvalidStringInTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"resource-type\":5}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"resource-type\":\"document\"}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"resource-type\":null}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"resource-type\":false}}]", + ContentExtensions::ContentExtensionError::JSONInvalidTriggerFlagsArray); + + StringBuilder rules; + rules.append("["); + for (unsigned i = 0; i < 49999; ++i) + rules.append("{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"a\"}},"); + String rules50000 = rules.toString(); + String rules50001 = rules.toString(); + rules50000.append("{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"a\"}}]"); + rules50001.append("{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"a\"}},{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"a\"}}]"); + checkCompilerError(rules50000.utf8().data(), { }); + checkCompilerError(rules50001.utf8().data(), ContentExtensions::ContentExtensionError::JSONTooManyRules); + + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":{}}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":[5]}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":[\"a\"]}}]", { }); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":\"a\"}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":false}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":null}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":{}}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":[5]}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":[\"\"]}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":\"a\"}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":null}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":false}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":[\"A\"]}}]", ContentExtensions::ContentExtensionError::JSONDomainNotLowerCaseASCII); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":[\"\\u00DC\"]}}]", ContentExtensions::ContentExtensionError::JSONDomainNotLowerCaseASCII); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":[\"0\"]}}]", { }); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":[\"a\"]}}]", { }); + + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":[],\"unless-domain\":[\"a\"]}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":[]}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":5}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"unless-domain\":5}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":5,\"unless-domain\":5}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":[]}}]", ContentExtensions::ContentExtensionError::JSONInvalidDomainList); + + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":[\"a\"],\"unless-domain\":[]}}]", ContentExtensions::ContentExtensionError::JSONUnlessAndIfDomain); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\",\"if-domain\":[\"a\"],\"unless-domain\":[\"a\"]}}]", ContentExtensions::ContentExtensionError::JSONUnlessAndIfDomain); + + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"webkit.org\", \"unexpected-identifier-should-be-ignored\":5}}]", { }); + + checkCompilerError("[{\"action\":5,\"trigger\":{\"url-filter\":\"webkit.org\"}}]", + ContentExtensions::ContentExtensionError::JSONInvalidAction); + checkCompilerError("[{\"action\":{\"type\":\"invalid\"},\"trigger\":{\"url-filter\":\"webkit.org\"}}]", + ContentExtensions::ContentExtensionError::JSONInvalidActionType); + checkCompilerError("[{\"action\":{\"type\":\"css-display-none\"},\"trigger\":{\"url-filter\":\"webkit.org\"}}]", + ContentExtensions::ContentExtensionError::JSONInvalidCSSDisplayNoneActionType); + + checkCompilerError("[{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"webkit.org\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\".*\"}}]", { }); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".*\",\"if-domain\":[\"a\"]}}]", { }); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\".*\",\"unless-domain\":[\"a\"]}}]", { }); + checkCompilerError("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[\"}}]", + ContentExtensions::ContentExtensionError::JSONInvalidRegex); +} + +TEST_F(ContentExtensionTest, StrictPrefixSeparatedMachines1) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^.*foo\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"bar$\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[ab]+bang\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/foo"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("foo://webkit.org/bar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/bar"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bar://webkit.org/bar"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("abang://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bbang://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("cbang://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/bang"), { }); + testRequest(backend, mainDocumentRequest("bang://webkit.org/"), { }); +} + +TEST_F(ContentExtensionTest, StrictPrefixSeparatedMachines1Partitioning) +{ + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + + // Those two share a prefix. + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("^.*foo", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("bar$", false, 1)); + + // Not this one. + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("^[ab]+bang", false, 0)); + + EXPECT_EQ(2ul, createNFAs(combinedURLFilters).size()); +} + +TEST_F(ContentExtensionTest, StrictPrefixSeparatedMachines2) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^foo\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^.*[a-c]+bar\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^webkit:\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[a-c]+b+oom\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("foo://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("webkit://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("http://bar.org/"), { }); + testRequest(backend, mainDocumentRequest("http://abar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://bbar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://cbar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://abcbar.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://dbar.org/"), { }); +} + +TEST_F(ContentExtensionTest, StrictPrefixSeparatedMachines2Partitioning) +{ + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("^foo", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("^.*[a-c]+bar", false, 1)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("^webkit:", false, 2)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("[a-c]+b+oom", false, 3)); + + // "^foo" and "^webkit:" can be grouped, the other two have a variable prefix. + EXPECT_EQ(3ul, createNFAs(combinedURLFilters).size()); +} + +TEST_F(ContentExtensionTest, StrictPrefixSeparatedMachines3) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"A*D\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"A*BA+\"}}," + "{\"action\":{\"type\":\"make-https\"},\"trigger\":{\"url-filter\":\"A*BC\"}}]"); + + testRequest(backend, mainDocumentRequest("http://webkit.org/D"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/AAD"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://webkit.org/AB"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/ABA"), { }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/ABAD"), { }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/BC"), { ContentExtensions::ActionType::MakeHTTPS }); + testRequest(backend, mainDocumentRequest("http://webkit.org/ABC"), { ContentExtensions::ActionType::MakeHTTPS }); + testRequest(backend, mainDocumentRequest("http://webkit.org/ABABC"), { ContentExtensions::ActionType::MakeHTTPS }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/ABABCAD"), { ContentExtensions::ActionType::MakeHTTPS }, true); + testRequest(backend, mainDocumentRequest("http://webkit.org/ABCAD"), { ContentExtensions::ActionType::MakeHTTPS, ContentExtensions::ActionType::BlockLoad }); +} + +TEST_F(ContentExtensionTest, StrictPrefixSeparatedMachines3Partitioning) +{ + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("A*D", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("A*BA+", false, 1)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("A*BC", false, 2)); + + // "A*A" and "A*BC" can be grouped, "A*BA+" should not. + EXPECT_EQ(2ul, createNFAs(combinedURLFilters).size()); +} + +TEST_F(ContentExtensionTest, SplittingLargeNFAs) +{ + const size_t expectedNFACounts[16] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1}; + + for (size_t i = 0; i < 16; i++) { + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("A+BBB", false, 1)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("A+CCC", false, 2)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("A+DDD", false, 2)); + + Vector<ContentExtensions::NFA> nfas; + combinedURLFilters.processNFAs(i, [&](ContentExtensions::NFA&& nfa) { + nfas.append(WTFMove(nfa)); + }); + EXPECT_EQ(nfas.size(), expectedNFACounts[i]); + + Vector<ContentExtensions::DFA> dfas; + for (auto& nfa : nfas) + dfas.append(ContentExtensions::NFAToDFA::convert(nfa)); + + Vector<ContentExtensions::DFABytecode> combinedBytecode; + for (const auto& dfa : dfas) { + Vector<ContentExtensions::DFABytecode> bytecode; + ContentExtensions::DFABytecodeCompiler compiler(dfa, bytecode); + compiler.compile(); + combinedBytecode.appendVector(bytecode); + } + + ContentExtensions::DFABytecodeInterpreter interpreter(&combinedBytecode[0], combinedBytecode.size()); + + EXPECT_EQ(interpreter.interpret("ABBBX", 0).size(), 1ull); + EXPECT_EQ(interpreter.interpret("ACCCX", 0).size(), 1ull); + EXPECT_EQ(interpreter.interpret("ADDDX", 0).size(), 1ull); + EXPECT_EQ(interpreter.interpret("XBBBX", 0).size(), 0ull); + EXPECT_EQ(interpreter.interpret("ABBX", 0).size(), 0ull); + EXPECT_EQ(interpreter.interpret("ACCX", 0).size(), 0ull); + EXPECT_EQ(interpreter.interpret("ADDX", 0).size(), 0ull); + } +} + +TEST_F(ContentExtensionTest, QuantifierInGroup) +{ + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(((A+)B)C)", false, 0)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(((A)B+)C)", false, 1)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(((A)B+)C)D", false, 2)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(((A)B)C+)", false, 3)); + EXPECT_EQ(ContentExtensions::URLFilterParser::ParseStatus::Ok, parser.addPattern("(((A)B)C)", false, 4)); + + // (((A)B+)C) and (((A)B+)C)D should be in the same NFA. + EXPECT_EQ(4ul, createNFAs(combinedURLFilters).size()); +} + +static void testPatternStatus(String pattern, ContentExtensions::URLFilterParser::ParseStatus status) +{ + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + EXPECT_EQ(status, parser.addPattern(pattern, false, 0)); +} + +TEST_F(ContentExtensionTest, ParsingFailures) +{ + testPatternStatus("a*b?.*.?[a-z]?[a-z]*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("a*b?.*.?[a-z]?[a-z]+", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("a*b?.*.?[a-z]?[a-z]", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus(".*?a", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus(".*a", ContentExtensions::URLFilterParser::ParseStatus::Ok); + + testPatternStatus("(?!)", ContentExtensions::URLFilterParser::ParseStatus::Group); + testPatternStatus("(?=)", ContentExtensions::URLFilterParser::ParseStatus::Group); + testPatternStatus("(?!a)", ContentExtensions::URLFilterParser::ParseStatus::Group); + testPatternStatus("(?=a)", ContentExtensions::URLFilterParser::ParseStatus::Group); + testPatternStatus("(regex)", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("(regex", ContentExtensions::URLFilterParser::ParseStatus::YarrError); + testPatternStatus("((regex)", ContentExtensions::URLFilterParser::ParseStatus::YarrError); + testPatternStatus("(?:regex)", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("(?:regex", ContentExtensions::URLFilterParser::ParseStatus::YarrError); + testPatternStatus("[^.]+", ContentExtensions::URLFilterParser::ParseStatus::Ok); + + testPatternStatus("a++", ContentExtensions::URLFilterParser::ParseStatus::YarrError); + testPatternStatus("[a]++", ContentExtensions::URLFilterParser::ParseStatus::YarrError); + testPatternStatus("+", ContentExtensions::URLFilterParser::ParseStatus::YarrError); + + testPatternStatus("[", ContentExtensions::URLFilterParser::ParseStatus::YarrError); + testPatternStatus("[a}", ContentExtensions::URLFilterParser::ParseStatus::YarrError); + + // FIXME: Look into why these do not cause YARR parsing errors. They probably should. + testPatternStatus("a]", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("{", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("{[a]", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("{0", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("{0,", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("{0,1", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("a{0,1", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("a{a,b}", ContentExtensions::URLFilterParser::ParseStatus::Ok); + + const char nonASCII[2] = {-1, '\0'}; + testPatternStatus(nonASCII, ContentExtensions::URLFilterParser::ParseStatus::NonASCII); + testPatternStatus("\\xff", ContentExtensions::URLFilterParser::ParseStatus::NonASCII); + + testPatternStatus("\\x\\r\\n", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("\\b", ContentExtensions::URLFilterParser::ParseStatus::WordBoundary); + testPatternStatus("[\\d]", ContentExtensions::URLFilterParser::ParseStatus::AtomCharacter); + testPatternStatus("\\d\\D\\w\\s\\v\\h\\i\\c", ContentExtensions::URLFilterParser::ParseStatus::UnsupportedCharacterClass); + + testPatternStatus("this|that", ContentExtensions::URLFilterParser::ParseStatus::Disjunction); + testPatternStatus("a{0,1}b", ContentExtensions::URLFilterParser::ParseStatus::Ok); + testPatternStatus("a{0,2}b", ContentExtensions::URLFilterParser::ParseStatus::InvalidQuantifier); + testPatternStatus("", ContentExtensions::URLFilterParser::ParseStatus::EmptyPattern); + testPatternStatus("$$", ContentExtensions::URLFilterParser::ParseStatus::MisplacedEndOfLine); + testPatternStatus("a^", ContentExtensions::URLFilterParser::ParseStatus::MisplacedStartOfLine); + testPatternStatus("(^)", ContentExtensions::URLFilterParser::ParseStatus::MisplacedStartOfLine); + + testPatternStatus("(a)\\1", ContentExtensions::URLFilterParser::ParseStatus::Ok); // This should be BackReference, right? +} + +TEST_F(ContentExtensionTest, PatternMatchingTheEmptyString) +{ + // Simple atoms. + testPatternStatus(".*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("a*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus(".?", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("a?", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + + // Character sets. + testPatternStatus("[a-z]*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("[a-z]?", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + + // Groups. + testPatternStatus("(foobar)*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(foobar)?", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(.*)", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(a*)", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(.?)", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(a?)", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("([a-z]*)", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("([a-z]?)", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + + testPatternStatus("(.)*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(.+)*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(.?)*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(.*)*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(.+)?", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + testPatternStatus("(.?)+", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); + + // Nested groups. + testPatternStatus("((foo)?((.)*)(bar)*)", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); +} + +TEST_F(ContentExtensionTest, MinimizingWithMoreFinalStatesThanNonFinalStates) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^h[a-z://]+\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://foo.com/\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://bar.com/\"}}]"); + + testRequest(backend, mainDocumentRequest("http://foo.com/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("http://bar.com/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("attp://foo.com/"), { }); + testRequest(backend, mainDocumentRequest("attp://bar.com/"), { }); + + testRequest(backend, mainDocumentRequest("http://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bttp://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bttps://webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("http://webkit.org/b"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://webkit.org/b"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("cttp://webkit.org/B"), { }); + testRequest(backend, mainDocumentRequest("cttps://webkit.org/B"), { }); +} + +TEST_F(ContentExtensionTest, StatesWithDifferentActionsAreNotUnified1) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://www.webkit.org/\"}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"^https://www.webkit.org/\"}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"^attps://www.webkit.org/\"}}]"); + + testRequest(backend, mainDocumentRequest("http://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://www.webkit.org/"), { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("attps://www.webkit.org/"), { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://www.webkit.org/a"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://www.webkit.org/B"), { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("attps://www.webkit.org/c"), { ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("http://www.whatwg.org/"), { }); + testRequest(backend, mainDocumentRequest("https://www.whatwg.org/"), { }); + testRequest(backend, mainDocumentRequest("attps://www.whatwg.org/"), { }); +} + +TEST_F(ContentExtensionTest, StatesWithDifferentActionsAreNotUnified2) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^http://www.webkit.org/\"}}," + "{\"action\":{\"type\":\"block-cookies\"},\"trigger\":{\"url-filter\":\"^https://www.webkit.org/\"}}," + "{\"action\":{\"type\":\"css-display-none\", \"selector\":\"#foo\"},\"trigger\":{\"url-filter\":\"^https://www.webkit.org/\"}}]"); + + testRequest(backend, mainDocumentRequest("http://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("https://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockCookies }); + testRequest(backend, mainDocumentRequest("https://www.whatwg.org/"), { }); + testRequest(backend, mainDocumentRequest("attps://www.whatwg.org/"), { }); +} + +// The order in which transitions from the root will be processed is unpredictable. +// To exercises the various options, this test exists in various version exchanging the transition to the final state. +TEST_F(ContentExtensionTest, FallbackTransitionsWithDifferentiatorDoNotMerge1) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^a.a\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^b.a\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^bac\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^bbc\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^BCC\"}}]"); + + testRequest(backend, mainDocumentRequest("aza://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bza://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bac://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bbc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bcc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("aac://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("abc://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("acc://www.webkit.org/"), { }); + + testRequest(backend, mainDocumentRequest("bzc://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bzc://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bzc://www.webkit.org/"), { }); +} +TEST_F(ContentExtensionTest, FallbackTransitionsWithDifferentiatorDoNotMerge2) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^bac\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^bbc\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^BCC\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^a.a\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^b.a\"}}]"); + + testRequest(backend, mainDocumentRequest("aza://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bza://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bac://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bbc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bcc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("aac://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("abc://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("acc://www.webkit.org/"), { }); + + testRequest(backend, mainDocumentRequest("bzc://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bzc://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bzc://www.webkit.org/"), { }); +} +TEST_F(ContentExtensionTest, FallbackTransitionsWithDifferentiatorDoNotMerge3) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^a.c\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^b.c\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^baa\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^bba\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^BCA\"}}]"); + + testRequest(backend, mainDocumentRequest("azc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bzc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("baa://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bba://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bca://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("aaa://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("aba://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("aca://www.webkit.org/"), { }); + + testRequest(backend, mainDocumentRequest("bza://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bza://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bza://www.webkit.org/"), { }); +} +TEST_F(ContentExtensionTest, FallbackTransitionsWithDifferentiatorDoNotMerge4) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^baa\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^bba\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^BCA\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^a.c\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^b.c\"}}]"); + + testRequest(backend, mainDocumentRequest("azc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bzc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("baa://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bba://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bca://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("aaa://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("aba://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("aca://www.webkit.org/"), { }); + + testRequest(backend, mainDocumentRequest("bza://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bza://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bza://www.webkit.org/"), { }); +} + +TEST_F(ContentExtensionTest, FallbackTransitionsToOtherNodeInSameGroupDoesNotDifferentiateGroup) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^aac\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^a.c\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^b.c\"}}]"); + + testRequest(backend, mainDocumentRequest("aac://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("abc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("bac://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("abc://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("aaa://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("aca://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("baa://www.webkit.org/"), { }); +} + +TEST_F(ContentExtensionTest, SimpleFallBackTransitionDifferentiator1) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^a.bc.de\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^a.bd.ef\"}}]"); + + testRequest(backend, mainDocumentRequest("abbccde://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("aabcdde://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("aabddef://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("aabddef://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("abcde://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("abdef://www.webkit.org/"), { }); +} + +TEST_F(ContentExtensionTest, SimpleFallBackTransitionDifferentiator2) +{ + auto backend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^cb.\"}}," + "{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^db.b\"}}]"); + + testRequest(backend, mainDocumentRequest("cba://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("cbb://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("dbab://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(backend, mainDocumentRequest("dbxb://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + + testRequest(backend, mainDocumentRequest("cca://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("dddd://www.webkit.org/"), { }); + testRequest(backend, mainDocumentRequest("bbbb://www.webkit.org/"), { }); +} + +// *** We have the following ranges intersections: *** +// Full overlap. +// 1) +// A: |-----| +// B: |---| +// 2) +// A: |-----| +// B: | +// 3) +// A: |---| +// B: |-----| +// 4) +// A: | +// B: |-----| +// One edge in common +// 5) +// A: |-| +// B: |-| +// 6) +// A: | +// B: |-| +// 7) +// A: |-| +// B: | +// 8) +// A: |-| +// B: |-| +// 9) +// A: | +// B: |-| +// 10) +// A: |-| +// B: | +// B overlap on the left side of A. +// 11) +// A: |---| +// B: |---| +// 12) +// A: |---| +// B: |-----| +// A overlap on the left side of B +// 13) +// A: |---| +// B: |---| +// 14) +// A: |-----| +// B: |---| +// Equal ranges +// 15) +// A: |---| +// B: |---| +// 16) +// A: | +// B: | + +TEST_F(ContentExtensionTest, RangeOverlapCase1) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[a-m]\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"^[c-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { }, true); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { }, true); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { }, true); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("m://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("n://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[a-m]\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"[c-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { }, true); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { }, true); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { }, true); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.m.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.n.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase2) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[a-m]\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"^b\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { }, true); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("m://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("n://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[a-m]\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"l\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.k.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.l.xxx/"), { }, true); + testRequest(searchBackend, mainDocumentRequest("zzz://www.m.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.n.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase3) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[b-d]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[a-m]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("m://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("n://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[b-d]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[a-m]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.m.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.n.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase4) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^l\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[a-m]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("k://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("l://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("m://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("n://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"l\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[a-m]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.k.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.l.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.m.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.n.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase5) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[a-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[e-h]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("i://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[a-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[e-h]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.i.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase6) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^e\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[e-h]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("i://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"e\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[e-h]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.i.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase7) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[a-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^e\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[a-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"e\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase8) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[e-h]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[a-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("i://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[e-h]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[a-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.i.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase9) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^e\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[a-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"e\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[a-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase10) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[e-h]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^e\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("i://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[e-h]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"e\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.i.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase11) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[e-g]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[d-f]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("g://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[e-g]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[d-f]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.g.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { }); +} + + +TEST_F(ContentExtensionTest, RangeOverlapCase12) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[e-g]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[d-g]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("g://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[e-g]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[d-g]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.g.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase13) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[b-d]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[c-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[b-d]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[c-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase14) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[b-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[c-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[b-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[c-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase15) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^[c-f]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^[c-f]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("g://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[c-f]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[c-f]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.g.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, RangeOverlapCase16) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^c\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^c\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"c\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"c\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, QuantifiedOneOrMoreRangesCase11And13) +{ + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"[c-e]+[g-i]+YYY\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[b-d]+[h-j]+YYY\"}}]"); + + // The interesting ranges only match between 'b' and 'k', plus a gap in 'f'. + testRequest(searchBackend, mainDocumentRequest("zzz://www.aayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.abyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.acyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.adyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.aeyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.afyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.agyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ahyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.aiyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ajyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.akyyy.xxx/"), { }); + + // 'b' is the first character of the second rule. + testRequest(searchBackend, mainDocumentRequest("zzz://www.byyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bbyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bcyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bdyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.beyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bfyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bgyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.biyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bkyyy.xxx/"), { }); + + // 'c' is the first character of the first rule, and it overlaps the first character of the second rule. + testRequest(searchBackend, mainDocumentRequest("zzz://www.cyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cbyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ccyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cdyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ceyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cfyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.chyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ciyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ckyyy.xxx/"), { }); + + // 'd' is in the first range of both rule. This series cover overlaps between the two rules. + testRequest(searchBackend, mainDocumentRequest("zzz://www.dgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddhhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.degyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dehyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dfgyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dfhyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.djyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddjjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); +} + +TEST_F(ContentExtensionTest, QuantifiedOneOrMoreRangesCase11And13InGroups) +{ + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"([c-e])+([g-i]+YYY)\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"[b-d]+[h-j]+YYY\"}}]"); + + // The interesting ranges only match between 'b' and 'k', plus a gap in 'f'. + testRequest(searchBackend, mainDocumentRequest("zzz://www.aayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.abyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.acyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.adyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.aeyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.afyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.agyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ahyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.aiyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ajyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.akyyy.xxx/"), { }); + + // 'b' is the first character of the second rule. + testRequest(searchBackend, mainDocumentRequest("zzz://www.byyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bbyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bcyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bdyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.beyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bfyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bgyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.biyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bkyyy.xxx/"), { }); + + // 'c' is the first character of the first rule, and it overlaps the first character of the second rule. + testRequest(searchBackend, mainDocumentRequest("zzz://www.cyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cbyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ccyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cdyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ceyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cfyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.chyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ciyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ckyyy.xxx/"), { }); + + // 'd' is in the first range of both rule. This series cover overlaps between the two rules. + testRequest(searchBackend, mainDocumentRequest("zzz://www.dgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddhhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.degyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dehyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dfgyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dfhyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.djyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddjjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase1) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[a-m]\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"^(bar)*[c-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { }, true); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { }, true); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { }, true); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("m://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("n://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[a-m]\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"(bar)*[c-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { }, true); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { }, true); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { }, true); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.m.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.n.xxx/"), { }); +} + + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase2) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[a-m]\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"^(bar)*b\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { }, true); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("m://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("n://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[a-m]\"}}," + "{\"action\":{\"type\":\"ignore-previous-rules\"},\"trigger\":{\"url-filter\":\"(bar)*l\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.k.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.l.xxx/"), { }, true); + testRequest(searchBackend, mainDocumentRequest("zzz://www.m.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.n.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase3) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[b-d]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[a-m]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("m://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("n://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[b-d]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[a-m]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.m.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.n.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase4) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*l\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[a-m]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("k://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("l://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("m://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("n://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*l\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[a-m]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.k.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.l.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.m.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.n.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase5) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[a-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[e-h]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("i://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[a-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[e-h]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.i.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase6) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*e\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[e-h]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("i://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*e\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[e-h]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.i.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase7) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[a-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*e\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[a-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*e\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase8) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[e-h]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[a-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("i://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[e-h]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[a-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.i.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase9) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*e\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[a-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*e\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[a-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase10) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[e-h]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*e\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("i://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[e-h]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*e\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.i.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase11) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[e-g]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[d-f]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("g://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[e-g]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[d-f]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.g.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { }); +} + + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase12) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[e-g]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[d-g]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("g://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[e-g]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[d-g]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.g.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase13) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[b-d]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[c-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[b-d]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[c-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase14) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[b-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[c-e]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("h://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[b-e]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[c-e]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.h.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase15) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*[c-f]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*[c-f]\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("f://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("g://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[c-f]\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[c-f]\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.f.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.g.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedRangeOverlapCase16) +{ + auto matchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"^(foo)*c\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"^(bar)*c\"}}]"); + + testRequest(matchBackend, mainDocumentRequest("a://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("b://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("c://www.webkit.org/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(matchBackend, mainDocumentRequest("d://www.webkit.org/"), { }); + testRequest(matchBackend, mainDocumentRequest("e://www.webkit.org/"), { }); + + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*c\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*c\"}}]"); + testRequest(searchBackend, mainDocumentRequest("zzz://www.a.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.b.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.c.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.d.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.e.xxx/"), { }); +} + +TEST_F(ContentExtensionTest, CombinedQuantifiedOneOrMoreRangesCase11And13) +{ + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*[c-e]+[g-i]+YYY\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[b-d]+[h-j]+YYY\"}}]"); + + // The interesting ranges only match between 'b' and 'k', plus a gap in 'f'. + testRequest(searchBackend, mainDocumentRequest("zzz://www.aayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.abyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.acyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.adyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.aeyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.afyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.agyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ahyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.aiyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ajyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.akyyy.xxx/"), { }); + + // 'b' is the first character of the second rule. + testRequest(searchBackend, mainDocumentRequest("zzz://www.byyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bbyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bcyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bdyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.beyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bfyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bgyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.biyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bkyyy.xxx/"), { }); + + // 'c' is the first character of the first rule, and it overlaps the first character of the second rule. + testRequest(searchBackend, mainDocumentRequest("zzz://www.cyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cbyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ccyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cdyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ceyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cfyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.chyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ciyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ckyyy.xxx/"), { }); + + // 'd' is in the first range of both rule. This series cover overlaps between the two rules. + testRequest(searchBackend, mainDocumentRequest("zzz://www.dgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddhhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.degyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dehyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dfgyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dfhyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.djyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddjjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); +} + +TEST_F(ContentExtensionTest, CombinedQuantifiedOneOrMoreRangesCase11And13InGroups) +{ + auto searchBackend = makeBackend("[{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"(foo)*([c-e])+([g-i]+YYY)\"}}," + "{\"action\":{\"type\":\"css-display-none\",\"selector\":\".hidden\"},\"trigger\":{\"url-filter\":\"(bar)*[b-d]+[h-j]+YYY\"}}]"); + + // The interesting ranges only match between 'b' and 'k', plus a gap in 'f'. + testRequest(searchBackend, mainDocumentRequest("zzz://www.aayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.abyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.acyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.adyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.aeyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.afyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.agyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ahyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.aiyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ajyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.akyyy.xxx/"), { }); + + // 'b' is the first character of the second rule. + testRequest(searchBackend, mainDocumentRequest("zzz://www.byyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bbyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bcyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bdyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.beyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bfyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bgyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.biyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.bkyyy.xxx/"), { }); + + // 'c' is the first character of the first rule, and it overlaps the first character of the second rule. + testRequest(searchBackend, mainDocumentRequest("zzz://www.cyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cayyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cbyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ccyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cdyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ceyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cfyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.chyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ciyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.cjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ckyyy.xxx/"), { }); + + // 'd' is in the first range of both rule. This series cover overlaps between the two rules. + testRequest(searchBackend, mainDocumentRequest("zzz://www.dgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddgyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddhhyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector, ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.degyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dehyyy.xxx/"), { ContentExtensions::ActionType::BlockLoad }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dfgyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.dfhyyy.xxx/"), { }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.djyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); + testRequest(searchBackend, mainDocumentRequest("zzz://www.ddjjyyy.xxx/"), { ContentExtensions::ActionType::CSSDisplayNoneSelector }); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebCore/DFACombiner.cpp b/Tools/TestWebKitAPI/Tests/WebCore/DFACombiner.cpp new file mode 100644 index 000000000..d53ebb75a --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebCore/DFACombiner.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2015 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 "DFAHelpers.h" +#include <WebCore/DFACombiner.h> +#include <wtf/MainThread.h> + +using namespace WebCore; +using namespace ContentExtensions; + +namespace TestWebKitAPI { + +class DFACombinerTest : public testing::Test { +public: + virtual void SetUp() + { + WTF::initializeMainThread(); + } +}; + +Vector<DFA> combine(Vector<DFA> dfas, unsigned minimumSize) +{ + DFACombiner combiner; + for (DFA& dfa : dfas) + combiner.addDFA(WTFMove(dfa)); + + Vector<DFA> output; + combiner.combineDFAs(minimumSize, [&output](DFA&& dfa) { + output.append(dfa); + }); + return output; +} + +TEST_F(DFACombinerTest, Basic) +{ + Vector<DFA> dfas = { buildDFAFromPatterns({ "foo"}), buildDFAFromPatterns({ "bar"}) }; + Vector<DFA> combinedDFAs = combine(dfas, 10000); + EXPECT_EQ(static_cast<size_t>(1), combinedDFAs.size()); + + DFA reference = buildDFAFromPatterns({ "foo", "bar"}); + reference.minimize(); + EXPECT_EQ(countLiveNodes(reference), countLiveNodes(combinedDFAs.first())); +} + + +TEST_F(DFACombinerTest, IdenticalDFAs) +{ + Vector<DFA> dfas = { buildDFAFromPatterns({ "foo"}), buildDFAFromPatterns({ "foo"}) }; + Vector<DFA> combinedDFAs = combine(dfas, 10000); + EXPECT_EQ(static_cast<size_t>(1), combinedDFAs.size()); + + // The result should have the exact same size as the minimized input. + DFA reference = buildDFAFromPatterns({ "foo"}); + reference.minimize(); + EXPECT_EQ(countLiveNodes(reference), countLiveNodes(combinedDFAs.first())); +} + +TEST_F(DFACombinerTest, NoInput) +{ + DFACombiner combiner; + unsigned counter = 0; + combiner.combineDFAs(100000, [&counter](DFA&& dfa) { + ++counter; + }); + EXPECT_EQ(static_cast<unsigned>(0), counter); +} + +TEST_F(DFACombinerTest, SingleInput) +{ + Vector<DFA> dfas = { buildDFAFromPatterns({ "WebKit"}) }; + Vector<DFA> combinedDFAs = combine(dfas, 10000); + EXPECT_EQ(static_cast<size_t>(1), combinedDFAs.size()); + + DFA reference = buildDFAFromPatterns({ "WebKit"}); + reference.minimize(); + EXPECT_EQ(countLiveNodes(reference), countLiveNodes(combinedDFAs.first())); +} + +TEST_F(DFACombinerTest, InputTooLargeForMinimumSize) +{ + Vector<DFA> dfas = { buildDFAFromPatterns({ "foo"}), buildDFAFromPatterns({ "bar"}) }; + Vector<DFA> combinedDFAs = combine(dfas, 2); + EXPECT_EQ(static_cast<size_t>(2), combinedDFAs.size()); + EXPECT_EQ(static_cast<size_t>(4), countLiveNodes(combinedDFAs[0])); + EXPECT_EQ(static_cast<size_t>(4), countLiveNodes(combinedDFAs[1])); +} + +TEST_F(DFACombinerTest, CombinedInputReachesMinimumSize) +{ + Vector<DFA> dfas = { buildDFAFromPatterns({ "foo"}), buildDFAFromPatterns({ "bar"}), buildDFAFromPatterns({ "WebKit"}) }; + Vector<DFA> combinedDFAs = combine(dfas, 5); + EXPECT_EQ(static_cast<size_t>(2), combinedDFAs.size()); + EXPECT_EQ(static_cast<size_t>(7), countLiveNodes(combinedDFAs[0])); + EXPECT_EQ(static_cast<size_t>(6), countLiveNodes(combinedDFAs[1])); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebCore/win/BitmapImage.cpp b/Tools/TestWebKitAPI/Tests/WebCore/DFAHelpers.h index 61b87cdad..8c6402760 100644 --- a/Tools/TestWebKitAPI/Tests/WebCore/win/BitmapImage.cpp +++ b/Tools/TestWebKitAPI/Tests/WebCore/DFAHelpers.h @@ -1,6 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * Copyright (C) 2012 peavo@outlook.com All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,36 +23,45 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" -#include <WebCore/BitmapImage.h> +#include <WebCore/CombinedURLFilters.h> +#include <WebCore/NFA.h> +#include <WebCore/NFAToDFA.h> +#include <WebCore/URLFilterParser.h> using namespace WebCore; namespace TestWebKitAPI { -// Test that there is no crash when BitmapImage::getHBITMAPOfSize() is called -// for an image with empty frames (BitmapImage::frameAtIndex(i) return null), WebKit Bug 102689. - -class BitmapImageTest : public WebCore::BitmapImage { -public: - BitmapImageTest() - { - m_frames.grow(1); +static unsigned countLiveNodes(const ContentExtensions::DFA& dfa) +{ + unsigned counter = 0; + for (const auto& node : dfa.nodes) { + if (!node.isKilled()) + ++counter; } + return counter; +} - virtual size_t frameCount() - { - return 1; - } -}; +static Vector<ContentExtensions::NFA> createNFAs(ContentExtensions::CombinedURLFilters& combinedURLFilters) +{ + Vector<ContentExtensions::NFA> nfas; -TEST(WebCore, BitmapImageEmptyFrameTest) + combinedURLFilters.processNFAs(std::numeric_limits<size_t>::max(), [&](ContentExtensions::NFA&& nfa) { + nfas.append(WTFMove(nfa)); + }); + + return nfas; +} + +static ContentExtensions::DFA buildDFAFromPatterns(Vector<const char*> patterns) { - SIZE sz = {16, 16}; - RefPtr<BitmapImageTest> bitmapImageTest = adoptRef(new BitmapImageTest); - int bits[256]; - HBITMAP hBitmap = CreateBitmap(16, 16, 1, 32, bits); - bitmapImageTest->getHBITMAPOfSize(hBitmap, &sz); + ContentExtensions::CombinedURLFilters combinedURLFilters; + ContentExtensions::URLFilterParser parser(combinedURLFilters); + + for (const char* pattern : patterns) + parser.addPattern(pattern, false, 0); + Vector<ContentExtensions::NFA> nfas = createNFAs(combinedURLFilters); + return ContentExtensions::NFAToDFA::convert(nfas[0]); } } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebCore/DFAMinimizer.cpp b/Tools/TestWebKitAPI/Tests/WebCore/DFAMinimizer.cpp new file mode 100644 index 000000000..bb3ac2e2a --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebCore/DFAMinimizer.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2015 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 "DFAHelpers.h" +#include <wtf/MainThread.h> + +namespace TestWebKitAPI { + +class DFAMinimizerTest : public testing::Test { +public: + virtual void SetUp() + { + WTF::initializeMainThread(); + } +}; + +TEST_F(DFAMinimizerTest, BasicSearch) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ ".*foo", ".*bar", ".*bang"}); + EXPECT_EQ(static_cast<size_t>(8), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(7), countLiveNodes(dfa)); +} + +TEST_F(DFAMinimizerTest, MergeSuffixes) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ ".*aaa", ".*aab", ".*aba", ".*abb", ".*baa", ".*bab", ".*bba", ".*bbb"}); + EXPECT_EQ(static_cast<size_t>(12), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(4), countLiveNodes(dfa)); +} + +TEST_F(DFAMinimizerTest, MergeInfixes) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ ".*aaakit", ".*aabkit", ".*abakit", ".*abbkit", ".*baakit", ".*babkit", ".*bbakit", ".*bbbkit"}); + EXPECT_EQ(static_cast<size_t>(15), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(7), countLiveNodes(dfa)); +} + +TEST_F(DFAMinimizerTest, FallbackTransitionsWithDifferentiatorDoNotMerge1) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ "^a.a", "^b.a", "^bac", "^bbc", "^BCC"}); + EXPECT_EQ(static_cast<size_t>(6), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(6), countLiveNodes(dfa)); +} + +TEST_F(DFAMinimizerTest, FallbackTransitionsWithDifferentiatorDoNotMerge2) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ "^bbc", "^BCC", "^a.a", "^b.a"}); + EXPECT_EQ(static_cast<size_t>(6), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(6), countLiveNodes(dfa)); +} + +TEST_F(DFAMinimizerTest, FallbackTransitionsWithDifferentiatorDoNotMerge3) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ "^a.c", "^b.c", "^baa", "^bba", "^BCA"}); + EXPECT_EQ(static_cast<size_t>(6), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(6), countLiveNodes(dfa)); +} + +TEST_F(DFAMinimizerTest, FallbackTransitionsWithDifferentiatorDoNotMerge4) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ "^baa", "^bba", "^BCA", "^a.c", "^b.c"}); + EXPECT_EQ(static_cast<size_t>(6), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(6), countLiveNodes(dfa)); +} + +TEST_F(DFAMinimizerTest, FallbackTransitionsToOtherNodeInSameGroupDoesNotDifferentiateGroup) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ "^aac", "^a.c", "^b.c"}); + EXPECT_EQ(static_cast<size_t>(5), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(4), countLiveNodes(dfa)); +} + +TEST_F(DFAMinimizerTest, SimpleFallBackTransitionDifferentiator1) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ "^a.bc.de", "^a.bd.ef"}); + EXPECT_EQ(static_cast<size_t>(11), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(11), countLiveNodes(dfa)); +} + +TEST_F(DFAMinimizerTest, SimpleFallBackTransitionDifferentiator2) +{ + ContentExtensions::DFA dfa = buildDFAFromPatterns({ "^cb.", "^db.b"}); + EXPECT_EQ(static_cast<size_t>(7), countLiveNodes(dfa)); + dfa.minimize(); + EXPECT_EQ(static_cast<size_t>(7), countLiveNodes(dfa)); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebCore/FileSystem.cpp b/Tools/TestWebKitAPI/Tests/WebCore/FileSystem.cpp new file mode 100644 index 000000000..fb23a4b7c --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebCore/FileSystem.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015 Canon 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 "Test.h" +#include <WebCore/FileSystem.h> +#include <wtf/MainThread.h> +#include <wtf/StringExtras.h> + +using namespace WebCore; + +namespace TestWebKitAPI { + +const char* FileSystemTestData = "This is a test"; + +// FIXME: Refactor FileSystemTest and SharedBufferTest as a single class. +class FileSystemTest : public testing::Test { +public: + virtual void SetUp() override + { + WTF::initializeMainThread(); + + // create temp file + PlatformFileHandle handle; + m_tempFilePath = openTemporaryFile("tempTestFile", handle); + writeToFile(handle, FileSystemTestData, strlen(FileSystemTestData)); + closeFile(handle); + + m_tempEmptyFilePath = openTemporaryFile("tempEmptyTestFile", handle); + closeFile(handle); + } + + virtual void TearDown() override + { + deleteFile(m_tempFilePath); + deleteFile(m_tempEmptyFilePath); + } + + const String& tempFilePath() { return m_tempFilePath; } + const String& tempEmptyFilePath() { return m_tempEmptyFilePath; } + +private: + String m_tempFilePath; + String m_tempEmptyFilePath; +}; + +TEST_F(FileSystemTest, MappingMissingFile) +{ + bool success; + MappedFileData mappedFileData(String("not_existing_file"), success); + EXPECT_FALSE(success); + EXPECT_TRUE(!mappedFileData); +} + +TEST_F(FileSystemTest, MappingExistingFile) +{ + bool success; + MappedFileData mappedFileData(tempFilePath(), success); + EXPECT_TRUE(success); + EXPECT_TRUE(!!mappedFileData); + EXPECT_TRUE(mappedFileData.size() == strlen(FileSystemTestData)); + EXPECT_TRUE(strnstr(FileSystemTestData, static_cast<const char*>(mappedFileData.data()), mappedFileData.size())); +} + +TEST_F(FileSystemTest, MappingExistingEmptyFile) +{ + bool success; + MappedFileData mappedFileData(tempEmptyFilePath(), success); + EXPECT_TRUE(success); + EXPECT_TRUE(!mappedFileData); +} + +} diff --git a/Tools/TestWebKitAPI/Tests/WebCore/LayoutUnit.cpp b/Tools/TestWebKitAPI/Tests/WebCore/LayoutUnit.cpp index ceafb039c..f904c96a1 100644 --- a/Tools/TestWebKitAPI/Tests/WebCore/LayoutUnit.cpp +++ b/Tools/TestWebKitAPI/Tests/WebCore/LayoutUnit.cpp @@ -28,8 +28,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define ENABLE_SUBPIXEL_LAYOUT 1 -#define ENABLE_SATURATED_LAYOUT_ARITHMETIC 1 #include "config.h" #include <WebCore/LayoutUnit.h> @@ -77,6 +75,10 @@ TEST(WebCoreLayoutUnit, LayoutUnitFloat) ASSERT_NEAR(LayoutUnit(345634.12335f).toFloat(), 345634.12335f, tolerance); ASSERT_NEAR(LayoutUnit(-345634.12335f).toFloat(), -345634.12335f, tolerance); ASSERT_NEAR(LayoutUnit(-345634).toFloat(), -345634.0f, tolerance); + ASSERT_NEAR(LayoutUnit(33554432.f).toFloat(), 33554432.f, tolerance); + ASSERT_NEAR(LayoutUnit(-33554432.f).toFloat(), -33554432.f, tolerance); + ASSERT_NEAR(LayoutUnit(33554432.f).toDouble(), 33554432.f, tolerance); + ASSERT_NEAR(LayoutUnit(-33554432.f).toDouble(), -33554432.f, tolerance); } TEST(WebCoreLayoutUnit, LayoutUnitRounding) @@ -104,28 +106,6 @@ TEST(WebCoreLayoutUnit, LayoutUnitRounding) ASSERT_EQ(LayoutUnit::fromFloatRound(1.51f).round(), 2); } -TEST(WebCoreLayoutUnit, LayoutUnitSnapSizeToPixel) -{ - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1), LayoutUnit(0)), 1); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1), LayoutUnit(0.5)), 1); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1.5), LayoutUnit(0)), 2); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1.5), LayoutUnit(0.49)), 2); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1.5), LayoutUnit(0.5)), 1); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1.5), LayoutUnit(0.75)), 1); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1.5), LayoutUnit(0.99)), 1); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1)), 2); - - ASSERT_EQ(snapSizeToPixel(LayoutUnit(0.5), LayoutUnit(1.5)), 0); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(0.99), LayoutUnit(1.5)), 0); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1.0), LayoutUnit(1.5)), 1); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1.49), LayoutUnit(1.5)), 1); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1.5)), 1); - - ASSERT_EQ(snapSizeToPixel(LayoutUnit(100.5), LayoutUnit(100)), 101); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(intMaxForLayoutUnit), LayoutUnit(0.3)), intMaxForLayoutUnit); - ASSERT_EQ(snapSizeToPixel(LayoutUnit(intMinForLayoutUnit), LayoutUnit(-0.3)), intMinForLayoutUnit); -} - TEST(WebCoreLayoutUnit, LayoutUnitMultiplication) { ASSERT_EQ((LayoutUnit(1) * LayoutUnit(1)).toInt(), 1); @@ -250,5 +230,19 @@ TEST(WebCoreLayoutUnit, LayoutUnitFloor) ASSERT_EQ((LayoutUnit(intMinForLayoutUnit) + LayoutUnit(1)).floor(), intMinForLayoutUnit + 1); } +TEST(WebCoreLayoutUnit, LayoutUnitPixelSnapping) +{ + for (int i = -100000; i <= 100000; ++i) { + ASSERT_EQ(roundToDevicePixel(LayoutUnit(i), 1), i); + ASSERT_EQ(roundToDevicePixel(LayoutUnit(i), 2), i); + ASSERT_EQ(roundToDevicePixel(LayoutUnit(i), 3), i); + } + + for (float i = -10000; i < 0; i = i + 0.5) + ASSERT_FLOAT_EQ(roundToDevicePixel(LayoutUnit(i), 2), i); + + for (float i = -10000.25; i < 0; i = i + 0.5) + ASSERT_FLOAT_EQ(roundToDevicePixel(LayoutUnit(i), 2), i + 0.25); +} } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentRange.cpp b/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentRange.cpp new file mode 100644 index 000000000..986388302 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebCore/ParsedContentRange.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2016 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 <WebCore/ParsedContentRange.h> +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace TestWebKitAPI { + +TEST(WebCore, ParsedContentRangeFromString) +{ + // Basic parsing + ASSERT_TRUE(ParsedContentRange("bytes 0-1/2").isValid()); + ASSERT_TRUE(ParsedContentRange("bytes 0-1/*").isValid()); + ASSERT_EQ(0, ParsedContentRange("bytes 0-1/2").firstBytePosition()); + ASSERT_EQ(1, ParsedContentRange("bytes 0-1/2").lastBytePosition()); + ASSERT_EQ(2, ParsedContentRange("bytes 0-1/2").instanceLength()); + ASSERT_EQ(ParsedContentRange::UnknownLength, ParsedContentRange("bytes 0-1/*").instanceLength()); + + // Whitespace errors + ASSERT_FALSE(ParsedContentRange("bytes 0-1/*").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0 -1/*").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0- 1/*").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0-1 /*").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0-1/ *").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0-1/* ").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0-1/ 2").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0-1/2 ").isValid()); + + // Non-digit errors + ASSERT_FALSE(ParsedContentRange("bytes abcd-1/2").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0-abcd/2").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0-1/abcd").isValid()); + + // Range requirement errors + ASSERT_FALSE(ParsedContentRange("bytes 1-0/2").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0-2/1").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 2/0-1").isValid()); + ASSERT_FALSE(ParsedContentRange("abcd 0/1-2").isValid()); + + // Negative value errors + ASSERT_FALSE(ParsedContentRange("bytes -0-1/*").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes -1/*").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0--0/2").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 0-1/-2").isValid()); + + // Edge cases + ASSERT_TRUE(ParsedContentRange("bytes 9223372036854775805-9223372036854775806/9223372036854775807").isValid()); + ASSERT_FALSE(ParsedContentRange("bytes 9223372036854775808-9223372036854775809/9223372036854775810").isValid()); +} + +TEST(WebCore, ParsedContentRangeFromValues) +{ + ASSERT_TRUE(ParsedContentRange(0, 1, 2).isValid()); + ASSERT_TRUE(ParsedContentRange(0, 1, ParsedContentRange::UnknownLength).isValid()); + ASSERT_FALSE(ParsedContentRange().isValid()); + ASSERT_FALSE(ParsedContentRange(1, 0, 2).isValid()); + ASSERT_FALSE(ParsedContentRange(0, 2, 1).isValid()); + ASSERT_FALSE(ParsedContentRange(0, 0, 0).isValid()); + ASSERT_FALSE(ParsedContentRange(-1, 1, 2).isValid()); + ASSERT_FALSE(ParsedContentRange(0, -1, 2).isValid()); + ASSERT_FALSE(ParsedContentRange(0, 1, -2).isValid()); + ASSERT_FALSE(ParsedContentRange(-2, -1, 2).isValid()); +} + +TEST(WebCore, ParsedContentRangeToString) +{ + ASSERT_STREQ("bytes 0-1/2", ParsedContentRange(0, 1, 2).headerValue().utf8().data()); + ASSERT_STREQ("bytes 0-1/*", ParsedContentRange(0, 1, ParsedContentRange::UnknownLength).headerValue().utf8().data()); + ASSERT_STREQ("", ParsedContentRange().headerValue().utf8().data()); +} + +} diff --git a/Tools/TestWebKitAPI/Tests/mac/PublicSuffix.mm b/Tools/TestWebKitAPI/Tests/WebCore/PublicSuffix.cpp index cb72414f3..f87ba63eb 100644 --- a/Tools/TestWebKitAPI/Tests/mac/PublicSuffix.mm +++ b/Tools/TestWebKitAPI/Tests/WebCore/PublicSuffix.cpp @@ -25,7 +25,7 @@ #include "config.h" -#if USE(PUBLIC_SUFFIX_LIST) +#if ENABLE(PUBLIC_SUFFIX_LIST) #include "WTFStringUtilities.h" #include <WebCore/PublicSuffix.h> @@ -40,7 +40,6 @@ public: virtual void SetUp() { WTF::initializeMainThread(); - [WebView initialize]; } }; @@ -76,4 +75,4 @@ TEST_F(PublicSuffix, TopPrivatelyControlledDomain) } -#endif +#endif // ENABLE(PUBLIC_SUFFIX_LIST) diff --git a/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp b/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp new file mode 100644 index 000000000..295281ef9 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2015 Canon 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 "Test.h" +#include <WebCore/SharedBuffer.h> +#include <wtf/MainThread.h> +#include <wtf/StringExtras.h> + +using namespace WebCore; + +namespace TestWebKitAPI { + +const char* SharedBufferTestData = "This is a test"; + +class SharedBufferTest : public testing::Test { +public: + virtual void SetUp() override + { + WTF::initializeMainThread(); + + // create temp file + PlatformFileHandle handle; + m_tempFilePath = openTemporaryFile("tempTestFile", handle); + writeToFile(handle, SharedBufferTestData, strlen(SharedBufferTestData)); + closeFile(handle); + + m_tempEmptyFilePath = openTemporaryFile("tempEmptyTestFile", handle); + closeFile(handle); + } + + virtual void TearDown() override + { + deleteFile(m_tempFilePath); + deleteFile(m_tempEmptyFilePath); + } + + const String& tempFilePath() { return m_tempFilePath; } + const String& tempEmptyFilePath() { return m_tempEmptyFilePath; } + +private: + String m_tempFilePath; + String m_tempEmptyFilePath; +}; + +TEST_F(SharedBufferTest, createWithContentsOfMissingFile) +{ + RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(String("not_existing_file")); + ASSERT_NULL(buffer); +} + +TEST_F(SharedBufferTest, createWithContentsOfExistingFile) +{ + RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempFilePath()); + ASSERT_NOT_NULL(buffer); + EXPECT_TRUE(buffer->size() == strlen(SharedBufferTestData)); + EXPECT_TRUE(String(SharedBufferTestData) == String(buffer->data(), buffer->size())); +} + +TEST_F(SharedBufferTest, createWithContentsOfExistingEmptyFile) +{ + RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempEmptyFilePath()); + ASSERT_NOT_NULL(buffer); + EXPECT_TRUE(buffer->isEmpty()); +} + +TEST_F(SharedBufferTest, copyBufferCreatedWithContentsOfExistingFile) +{ + RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempFilePath()); + ASSERT_NOT_NULL(buffer); + RefPtr<SharedBuffer> copy = buffer->copy(); + EXPECT_GT(buffer->size(), 0U); + EXPECT_TRUE(buffer->size() == copy->size()); + EXPECT_TRUE(!memcmp(buffer->data(), copy->data(), buffer->size())); +} + +TEST_F(SharedBufferTest, clearBufferCreatedWithContentsOfExistingFile) +{ + RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempFilePath()); + ASSERT_NOT_NULL(buffer); + buffer->clear(); + EXPECT_TRUE(!buffer->size()); + EXPECT_TRUE(!buffer->data()); +} + +TEST_F(SharedBufferTest, appendBufferCreatedWithContentsOfExistingFile) +{ + RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(tempFilePath()); + ASSERT_NOT_NULL(buffer); + buffer->append("a", 1); + EXPECT_TRUE(buffer->size() == (strlen(SharedBufferTestData) + 1)); + EXPECT_TRUE(!memcmp(buffer->data(), SharedBufferTestData, strlen(SharedBufferTestData))); + EXPECT_EQ('a', buffer->data()[strlen(SharedBufferTestData)]); +} + +} diff --git a/Tools/TestWebKitAPI/Tests/WebCore/TimeRanges.cpp b/Tools/TestWebKitAPI/Tests/WebCore/TimeRanges.cpp new file mode 100644 index 000000000..1612bf8f0 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebCore/TimeRanges.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2013, 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 <WebCore/TimeRanges.h> + +#include <WebCore/ExceptionCodePlaceholder.h> + +using namespace WebCore; + +namespace TestWebKitAPI { + +static std::string ToString(const TimeRanges& ranges) +{ + std::stringstream ss; + ss << "{"; + for (unsigned i = 0; i < ranges.length(); ++i) + ss << " [" << ranges.start(i, IGNORE_EXCEPTION) << "," << ranges.end(i, IGNORE_EXCEPTION) << ")"; + ss << " }"; + + return ss.str(); +} + +#define ASSERT_RANGE(expected, range) EXPECT_EQ(expected, ToString(*range)) + +TEST(TimeRanges, Empty) +{ + ASSERT_RANGE("{ }", TimeRanges::create().ptr()); +} + +TEST(TimeRanges, SingleRange) +{ + ASSERT_RANGE("{ [1,2) }", TimeRanges::create(1, 2).ptr()); +} + +TEST(TimeRanges, AddOrder) +{ + RefPtr<TimeRanges> rangeA = TimeRanges::create(); + RefPtr<TimeRanges> rangeB = TimeRanges::create(); + + rangeA->add(0, 2); + rangeA->add(3, 4); + rangeA->add(5, 100); + + std::string expected = "{ [0,2) [3,4) [5,100) }"; + ASSERT_RANGE(expected, rangeA); + + // Add the values in rangeA to rangeB in reverse order. + for (int i = rangeA->length() - 1; i >= 0; --i) + rangeB->add(rangeA->start(i, IGNORE_EXCEPTION), rangeA->end(i, IGNORE_EXCEPTION)); + + ASSERT_RANGE(expected, rangeB); +} + +TEST(TimeRanges, OverlappingAdds) +{ + RefPtr<TimeRanges> ranges = TimeRanges::create(); + + ranges->add(0, 2); + ranges->add(10, 11); + ASSERT_RANGE("{ [0,2) [10,11) }", ranges); + + ranges->add(0, 2); + ASSERT_RANGE("{ [0,2) [10,11) }", ranges); + + ranges->add(2, 3); + ASSERT_RANGE("{ [0,3) [10,11) }", ranges); + + ranges->add(2, 6); + ASSERT_RANGE("{ [0,6) [10,11) }", ranges); + + ranges->add(9, 10); + ASSERT_RANGE("{ [0,6) [9,11) }", ranges); + + ranges->add(8, 10); + ASSERT_RANGE("{ [0,6) [8,11) }", ranges); + + ranges->add(-1, 7); + ASSERT_RANGE("{ [-1,7) [8,11) }", ranges); + + ranges->add(6, 9); + ASSERT_RANGE("{ [-1,11) }", ranges); +} + +TEST(TimeRanges, IntersectWith_Self) +{ + RefPtr<TimeRanges> ranges = TimeRanges::create(0, 2); + + ASSERT_RANGE("{ [0,2) }", ranges); + + ranges->intersectWith(*ranges.get()); + + ASSERT_RANGE("{ [0,2) }", ranges); +} + +TEST(TimeRanges, IntersectWith_IdenticalRange) +{ + RefPtr<TimeRanges> rangesA = TimeRanges::create(0, 2); + RefPtr<TimeRanges> rangesB = rangesA->copy(); + + ASSERT_RANGE("{ [0,2) }", rangesA); + ASSERT_RANGE("{ [0,2) }", rangesB); + + rangesA->intersectWith(*rangesB.get()); + + ASSERT_RANGE("{ [0,2) }", rangesA); + ASSERT_RANGE("{ [0,2) }", rangesB); +} + +TEST(TimeRanges, IntersectWith_Empty) +{ + RefPtr<TimeRanges> rangesA = TimeRanges::create(0, 2); + RefPtr<TimeRanges> rangesB = TimeRanges::create(); + + ASSERT_RANGE("{ [0,2) }", rangesA); + ASSERT_RANGE("{ }", rangesB); + + rangesA->intersectWith(*rangesB.get()); + + ASSERT_RANGE("{ }", rangesA); + ASSERT_RANGE("{ }", rangesB); +} + +TEST(TimeRanges, IntersectWith_DisjointRanges1) +{ + + RefPtr<TimeRanges> rangesA = TimeRanges::create(); + RefPtr<TimeRanges> rangesB = TimeRanges::create(); + + rangesA->add(0, 1); + rangesA->add(4, 5); + + rangesB->add(2, 3); + rangesB->add(6, 7); + + ASSERT_RANGE("{ [0,1) [4,5) }", rangesA); + ASSERT_RANGE("{ [2,3) [6,7) }", rangesB); + + rangesA->intersectWith(*rangesB.get()); + + ASSERT_RANGE("{ }", rangesA); + ASSERT_RANGE("{ [2,3) [6,7) }", rangesB); +} + +TEST(TimeRanges, IntersectWith_DisjointRanges2) +{ + RefPtr<TimeRanges> rangesA = TimeRanges::create(); + RefPtr<TimeRanges> rangesB = TimeRanges::create(); + + rangesA->add(0, 1); + rangesA->add(4, 5); + + rangesB->add(1, 4); + rangesB->add(5, 7); + + ASSERT_RANGE("{ [0,1) [4,5) }", rangesA); + ASSERT_RANGE("{ [1,4) [5,7) }", rangesB); + + rangesA->intersectWith(*rangesB.get()); + + ASSERT_RANGE("{ }", rangesA); + ASSERT_RANGE("{ [1,4) [5,7) }", rangesB); +} + +TEST(TimeRanges, IntersectWith_CompleteOverlap1) +{ + RefPtr<TimeRanges> rangesA = TimeRanges::create(); + RefPtr<TimeRanges> rangesB = TimeRanges::create(); + + rangesA->add(1, 3); + rangesA->add(4, 5); + rangesA->add(6, 9); + + rangesB->add(0, 10); + + ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA); + ASSERT_RANGE("{ [0,10) }", rangesB); + + rangesA->intersectWith(*rangesB.get()); + + ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA); + ASSERT_RANGE("{ [0,10) }", rangesB); +} + +TEST(TimeRanges, IntersectWith_CompleteOverlap2) +{ + RefPtr<TimeRanges> rangesA = TimeRanges::create(); + RefPtr<TimeRanges> rangesB = TimeRanges::create(); + + rangesA->add(1, 3); + rangesA->add(4, 5); + rangesA->add(6, 9); + + rangesB->add(1, 9); + + ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA); + ASSERT_RANGE("{ [1,9) }", rangesB); + + rangesA->intersectWith(*rangesB.get()); + + ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA); + ASSERT_RANGE("{ [1,9) }", rangesB); +} + +TEST(TimeRanges, IntersectWith_Gaps1) +{ + RefPtr<TimeRanges> rangesA = TimeRanges::create(); + RefPtr<TimeRanges> rangesB = TimeRanges::create(); + + rangesA->add(0, 2); + rangesA->add(4, 6); + + rangesB->add(1, 5); + + ASSERT_RANGE("{ [0,2) [4,6) }", rangesA); + ASSERT_RANGE("{ [1,5) }", rangesB); + + rangesA->intersectWith(*rangesB.get()); + + ASSERT_RANGE("{ [1,2) [4,5) }", rangesA); + ASSERT_RANGE("{ [1,5) }", rangesB); +} + +TEST(TimeRanges, IntersectWith_Gaps2) +{ + RefPtr<TimeRanges> rangesA = TimeRanges::create(); + RefPtr<TimeRanges> rangesB = TimeRanges::create(); + + rangesA->add(0, 2); + rangesA->add(4, 6); + rangesA->add(8, 10); + + rangesB->add(1, 9); + + ASSERT_RANGE("{ [0,2) [4,6) [8,10) }", rangesA); + ASSERT_RANGE("{ [1,9) }", rangesB); + + rangesA->intersectWith(*rangesB.get()); + + ASSERT_RANGE("{ [1,2) [4,6) [8,9) }", rangesA); + ASSERT_RANGE("{ [1,9) }", rangesB); +} + +TEST(TimeRanges, IntersectWith_Gaps3) +{ + RefPtr<TimeRanges> rangesA = TimeRanges::create(); + RefPtr<TimeRanges> rangesB = TimeRanges::create(); + + rangesA->add(0, 2); + rangesA->add(4, 7); + rangesA->add(8, 10); + + rangesB->add(1, 5); + rangesB->add(6, 9); + + ASSERT_RANGE("{ [0,2) [4,7) [8,10) }", rangesA); + ASSERT_RANGE("{ [1,5) [6,9) }", rangesB); + + rangesA->intersectWith(*rangesB.get()); + + ASSERT_RANGE("{ [1,2) [4,5) [6,7) [8,9) }", rangesA); + ASSERT_RANGE("{ [1,5) [6,9) }", rangesB); +} + +} + diff --git a/Tools/TestWebKitAPI/Tests/WebCore/KURL.cpp b/Tools/TestWebKitAPI/Tests/WebCore/URL.cpp index 6eade5586..4a7f53977 100644 --- a/Tools/TestWebKitAPI/Tests/WebCore/KURL.cpp +++ b/Tools/TestWebKitAPI/Tests/WebCore/URL.cpp @@ -25,14 +25,14 @@ #include "config.h" #include "WTFStringUtilities.h" -#include <WebCore/KURL.h> +#include <WebCore/URL.h> #include <wtf/MainThread.h> using namespace WebCore; namespace TestWebKitAPI { -class KURLTest : public testing::Test { +class URLTest : public testing::Test { public: virtual void SetUp() { @@ -40,18 +40,18 @@ public: } }; -TEST_F(KURLTest, KURLConstructorDefault) +TEST_F(URLTest, URLConstructorDefault) { - KURL kurl; + URL kurl; EXPECT_TRUE(kurl.isEmpty()); EXPECT_TRUE(kurl.isNull()); EXPECT_FALSE(kurl.isValid()); } -TEST_F(KURLTest, KURLConstructorConstChar) +TEST_F(URLTest, URLConstructorConstChar) { - KURL kurl(ParsedURLString, "http://username:password@www.example.com:8080/index.html?var=val#fragment"); + URL kurl(ParsedURLString, "http://username:password@www.example.com:8080/index.html?var=val#fragment"); EXPECT_FALSE(kurl.isEmpty()); EXPECT_FALSE(kurl.isNull()); @@ -70,12 +70,12 @@ TEST_F(KURLTest, KURLConstructorConstChar) EXPECT_EQ(String("fragment"), kurl.fragmentIdentifier()); } -TEST_F(KURLTest, KURLDataURIStringSharing) +TEST_F(URLTest, URLDataURIStringSharing) { - KURL baseURL(ParsedURLString, "http://www.webkit.org/"); + URL baseURL(ParsedURLString, "http://www.webkit.org/"); String threeApples = "data:text/plain;charset=utf-8;base64,76O/76O/76O/"; - KURL url(baseURL, threeApples); + URL url(baseURL, threeApples); EXPECT_EQ(threeApples.impl(), url.string().impl()); } diff --git a/Tools/TestWebKitAPI/Tests/WebKit/win/WebViewDestruction.cpp b/Tools/TestWebKitAPI/Tests/WebKit/win/WebViewDestruction.cpp deleted file mode 100644 index 3e6630f98..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit/win/WebViewDestruction.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2010 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 "HostWindow.h" -#include "Test.h" -#include <WebCore/COMPtr.h> -#include <WebKit/WebKit.h> -#include <WebKit/WebKitCOMAPI.h> -#include <wtf/PassOwnPtr.h> - -namespace TestWebKitAPI { - -template <typename T> -static HRESULT WebKitCreateInstance(REFCLSID clsid, T** object) -{ - return WebKitCreateInstance(clsid, 0, __uuidof(T), reinterpret_cast<void**>(object)); -} - -class WebViewDestruction : public ::testing::Test { -protected: - virtual void SetUp(); - virtual void TearDown(); - - static int webViewCount(); - static void runMessagePump(DWORD timeoutMilliseconds); - - COMPtr<IWebView> m_webView; -}; - -class WebViewDestructionWithHostWindow : public WebViewDestruction { -protected: - virtual void SetUp(); - virtual void TearDown(); - - HostWindow m_window; - HWND m_viewWindow; -}; - -void WebViewDestruction::SetUp() -{ - EXPECT_HRESULT_SUCCEEDED(WebKitCreateInstance(__uuidof(WebView), &m_webView)); -} - -int WebViewDestruction::webViewCount() -{ - COMPtr<IWebKitStatistics> statistics; - if (FAILED(WebKitCreateInstance(__uuidof(WebKitStatistics), &statistics))) - return -1; - int count; - if (FAILED(statistics->webViewCount(&count))) - return -1; - return count; -} - -void WebViewDestructionWithHostWindow::SetUp() -{ - WebViewDestruction::SetUp(); - - EXPECT_TRUE(m_window.initialize()); - EXPECT_HRESULT_SUCCEEDED(m_webView->setHostWindow(reinterpret_cast<OLE_HANDLE>(m_window.window()))); - EXPECT_HRESULT_SUCCEEDED(m_webView->initWithFrame(m_window.clientRect(), 0, 0)); - - COMPtr<IWebViewPrivate> viewPrivate(Query, m_webView); - ASSERT_NOT_NULL(viewPrivate); - EXPECT_HRESULT_SUCCEEDED(viewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&m_viewWindow))); - EXPECT_TRUE(::IsWindow(m_viewWindow)); -} - -void WebViewDestruction::runMessagePump(DWORD timeoutMilliseconds) -{ - // FIXME: We should move this functionality to PlatformUtilities at some point. - - DWORD startTickCount = ::GetTickCount(); - MSG msg; - BOOL result; - while ((result = ::PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) && ::GetTickCount() - startTickCount <= timeoutMilliseconds) { - if (result == -1) - break; - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } -} - -void WebViewDestruction::TearDown() -{ - // Allow window messages to be processed, because in some cases that would trigger a crash (e.g., <http://webkit.org/b/32827>). - runMessagePump(50); - - // We haven't crashed. Release the WebView and ensure that its view window has been destroyed and the WebView doesn't leak. - int currentWebViewCount = webViewCount(); - EXPECT_GT(currentWebViewCount, 0); - - m_webView = 0; - - EXPECT_EQ(webViewCount(), currentWebViewCount - 1); -} - -void WebViewDestructionWithHostWindow::TearDown() -{ - WebViewDestruction::TearDown(); - - EXPECT_FALSE(::IsWindow(m_viewWindow)); -} - -// Tests that releasing a WebView without calling IWebView::initWithFrame works. -TEST_F(WebViewDestruction, NoInitWithFrame) -{ -} - -TEST_F(WebViewDestruction, CloseWithoutInitWithFrame) -{ - EXPECT_HRESULT_SUCCEEDED(m_webView->close()); -} - -// Tests that calling IWebView::close without calling DestroyWindow, then releasing a WebView doesn't crash. <http://webkit.org/b/32827> -TEST_F(WebViewDestructionWithHostWindow, CloseWithoutDestroyViewWindow) -{ - EXPECT_HRESULT_SUCCEEDED(m_webView->close()); -} - -TEST_F(WebViewDestructionWithHostWindow, DestroyViewWindowWithoutClose) -{ - ::DestroyWindow(m_viewWindow); -} - -TEST_F(WebViewDestructionWithHostWindow, CloseThenDestroyViewWindow) -{ - EXPECT_HRESULT_SUCCEEDED(m_webView->close()); - ::DestroyWindow(m_viewWindow); -} - -TEST_F(WebViewDestructionWithHostWindow, DestroyViewWindowThenClose) -{ - ::DestroyWindow(m_viewWindow); - EXPECT_HRESULT_SUCCEEDED(m_webView->close()); -} - -TEST_F(WebViewDestructionWithHostWindow, DestroyHostWindow) -{ - ::DestroyWindow(m_window.window()); -} - -TEST_F(WebViewDestructionWithHostWindow, DestroyHostWindowThenClose) -{ - ::DestroyWindow(m_window.window()); - EXPECT_HRESULT_SUCCEEDED(m_webView->close()); -} - -TEST_F(WebViewDestructionWithHostWindow, CloseThenDestroyHostWindow) -{ - EXPECT_HRESULT_SUCCEEDED(m_webView->close()); - ::DestroyWindow(m_window.window()); -} - -} // namespace WebKitAPITest diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/AboutBlankLoad.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/AboutBlankLoad.cpp index 42939dd2d..5503edd9e 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/AboutBlankLoad.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/AboutBlankLoad.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" @@ -43,10 +46,13 @@ TEST(WebKit2, AboutBlankLoad) WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; - memset(&loaderClient, 0 , sizeof(loaderClient)); + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKPageLoadURL(webView.page(), adoptWK(WKURLCreateWithUTF8CString("about:blank")).get()); @@ -54,3 +60,5 @@ TEST(WebKit2, AboutBlankLoad) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/mac/Ahem.ttf b/Tools/TestWebKitAPI/Tests/WebKit2/Ahem.ttf Binary files differindex ac81cb031..ac81cb031 100644 --- a/Tools/TestWebKitAPI/Tests/mac/Ahem.ttf +++ b/Tools/TestWebKitAPI/Tests/WebKit2/Ahem.ttf diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest.cpp index e3e5d0cc6..a1d09f2cd 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKContextPrivate.h> +#include <WebKit/WKContextPrivate.h> namespace TestWebKitAPI { @@ -45,11 +48,13 @@ static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messag static void setInjectedBundleClient(WKContextRef context) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } TEST(WebKit2, CanHandleRequest) @@ -69,3 +74,5 @@ TEST(WebKit2, CanHandleRequest) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest_Bundle.cpp index 5f66b537a..590615e8c 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CanHandleRequest_Bundle.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> +#include <WebKit/WKBundlePage.h> namespace TestWebKitAPI { @@ -65,3 +68,5 @@ void CanHandleRequestTest::didReceiveMessage(WKBundleRef bundle, WKStringRef mes } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/win/AltKeyGeneratesWMSysCommand.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/CloseFromWithinCreatePage.cpp index 000f9cdd0..b5e4a901b 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/win/AltKeyGeneratesWMSysCommand.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CloseFromWithinCreatePage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,62 +24,64 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include "WindowMessageObserver.h" -#include <WebKit2/WKRetainPtr.h> namespace TestWebKitAPI { -class WMSysCommandObserver : public WindowMessageObserver { -public: - WMSysCommandObserver() : m_windowDidReceiveWMSysCommand(false) { } +static bool testDone; +static std::unique_ptr<PlatformWebView> openedWebView; - bool windowDidReceiveWMSysCommand() const { return m_windowDidReceiveWMSysCommand; } +static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef, const void* clientInfo) +{ + // FIXME: Check that the alert text matches the storage. + testDone = true; +} -private: - virtual void windowReceivedMessage(HWND, UINT message, WPARAM, LPARAM) - { - if (message == WM_SYSCOMMAND) - m_windowDidReceiveWMSysCommand = true; - } +static WKPageRef createNewPage(WKPageRef page, WKURLRequestRef urlRequest, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void *clientInfo) +{ + EXPECT_TRUE(openedWebView == nullptr); - bool m_windowDidReceiveWMSysCommand; -}; + openedWebView = std::make_unique<PlatformWebView>(page); -static bool didNotHandleWMSysKeyUp; + WKPageUIClientV5 uiClient; + memset(&uiClient, 0, sizeof(uiClient)); -static void didNotHandleKeyEventCallback(WKPageRef, WKNativeEventPtr event, const void*) -{ - if (event->message != WM_SYSKEYUP) - return; + uiClient.base.version = 5; + uiClient.runJavaScriptAlert = runJavaScriptAlert; + WKPageSetPageUIClient(openedWebView->page(), &uiClient.base); + + WKPageClose(page); - didNotHandleWMSysKeyUp = true; + WKRetain(openedWebView->page()); + return openedWebView->page(); } -TEST(WebKit2, AltKeyGeneratesWMSysCommand) +TEST(WebKit2, CloseFromWithinCreatePage) { WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + PlatformWebView webView(context.get()); - WKPageUIClient uiClient; + WKPageUIClientV5 uiClient; memset(&uiClient, 0, sizeof(uiClient)); - uiClient.didNotHandleKeyEvent = didNotHandleKeyEventCallback; - WKPageSetPageUIClient(webView.page(), &uiClient); + uiClient.base.version = 5; + uiClient.createNewPage = createNewPage; + uiClient.runJavaScriptAlert = runJavaScriptAlert; + WKPageSetPageUIClient(webView.page(), &uiClient.base); - WMSysCommandObserver observer; - webView.setParentWindowMessageObserver(&observer); + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("close-from-within-create-page", "html")); + WKPageLoadURL(webView.page(), url.get()); - webView.simulateAltKeyPress(); + Util::run(&testDone); - Util::run(&didNotHandleWMSysKeyUp); - - webView.setParentWindowMessageObserver(0); + openedWebView = nullptr; +} - // The WM_SYSKEYUP message should have generated a WM_SYSCOMMAND message that was sent to the - // WKView's parent window. - EXPECT_TRUE(observer.windowDidReceiveWMSysCommand()); } -} // namespace TestWebKitAPI +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/CloseThenTerminate.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/CloseThenTerminate.cpp index 09230bb57..71239e4f0 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/CloseThenTerminate.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CloseThenTerminate.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" @@ -44,10 +47,13 @@ TEST(WebKit2, CloseThenTerminate) WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0 , sizeof(loaderClient)); + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -59,3 +65,5 @@ TEST(WebKit2, CloseThenTerminate) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/CookieManager.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/CookieManager.cpp index df5fb2eb0..d231e0e75 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/CookieManager.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CookieManager.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKCookieManager.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKCookieManager.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -72,12 +75,13 @@ TEST(WebKit2, CookieManager) wkContext.adopt(WKContextCreate()); PlatformWebView webView(wkContext.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKPageLoadURL(webView.page(), adoptWK(WKURLCreateWithUTF8CString("about:blank")).get()); @@ -85,3 +89,5 @@ TEST(WebKit2, CookieManager) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewIsActiveSetIsActive.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewIsActiveSetIsActive.cpp new file mode 100644 index 000000000..ef9625b99 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewIsActiveSetIsActive.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * + * 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 THE COPYRIGHT HOLDERS ``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 HOLDERS 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 "PlatformUtilities.h" +#include "Test.h" + +#include <WebKit/WKContext.h> +#include <WebKit/WKPage.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKView.h> + +namespace TestWebKitAPI { + +static bool didWebProcessCrash = false; +static bool didWebProcessRelaunch = false; +static bool didFinishLoad = false; + +static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) +{ + didFinishLoad = true; +} + +static void webProcessCrashed(WKViewRef view, WKURLRef, const void*) +{ + // WebProcess crashed, so at this point the view should not be active. + ASSERT_FALSE(WKViewIsActive(view)); + didWebProcessCrash = true; +} + +static void webProcessRelaunched(WKViewRef view, const void*) +{ + // WebProcess just relaunched, so at this point the view should not be active. + ASSERT_FALSE(WKViewIsActive(view)); + + didWebProcessRelaunch = true; +} + +TEST(WebKit2, WKViewIsActiveSetIsActive) +{ + WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); + WKRetainPtr<WKViewRef> view = adoptWK(WKViewCreate(context.get(), 0)); + + WKViewInitialize(view.get()); + + // At this point we should have an active view. + ASSERT_TRUE(WKViewIsActive(view.get())); + + // Now we are going to play with its active state a few times. + WKViewSetIsActive(view.get(), true); + ASSERT_TRUE(WKViewIsActive(view.get())); + + WKViewSetIsActive(view.get(), false); + ASSERT_FALSE(WKViewIsActive(view.get())); + + WKViewSetIsActive(view.get(), false); + ASSERT_FALSE(WKViewIsActive(view.get())); + + WKViewSetIsActive(view.get(), true); + ASSERT_TRUE(WKViewIsActive(view.get())); +} + +TEST(WebKit2, WKViewIsActive) +{ + WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("WKViewIsActiveSetIsActiveTest")); + WKRetainPtr<WKViewRef> view = adoptWK(WKViewCreate(context.get(), 0)); + + WKViewClientV0 viewClient; + memset(&viewClient, 0, sizeof(WKViewClientV0)); + viewClient.base.version = 0; + viewClient.webProcessCrashed = webProcessCrashed; + viewClient.webProcessDidRelaunch = webProcessRelaunched; + WKViewSetViewClient(view.get(), &viewClient.base); + + WKViewInitialize(view.get()); + + // At this point we should have an active view. + ASSERT_TRUE(WKViewIsActive(view.get())); + + WKPageLoaderClientV3 pageLoaderClient; + memset(&pageLoaderClient, 0, sizeof(WKPageLoaderClient)); + pageLoaderClient.base.version = 3; + pageLoaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + WKPageSetPageLoaderClient(WKViewGetPage(view.get()), &pageLoaderClient.base); + + const WKSize size = WKSizeMake(100, 100); + WKViewSetSize(view.get(), size); + + didFinishLoad = false; + didWebProcessCrash = false; + didWebProcessRelaunch = false; + + WKRetainPtr<WKURLRef> simpleUrl = adoptWK(Util::createURLForResource("../WebKit/simple", "html")); + WKPageLoadURL(WKViewGetPage(view.get()), simpleUrl.get()); + Util::run(&didFinishLoad); + didFinishLoad = false; + + WKContextPostMessageToInjectedBundle(context.get(), Util::toWK("Crash").get(), 0); + Util::run(&didWebProcessCrash); + ASSERT_TRUE(didWebProcessCrash); + + WKPageLoadURL(WKViewGetPage(view.get()), simpleUrl.get()); + Util::run(&didFinishLoad); + + ASSERT_TRUE(didWebProcessRelaunch); + ASSERT_TRUE(didFinishLoad); +} + +} // TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewIsActiveSetIsActive_Bundle.cpp index 83a95c069..a3cb1b6de 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewIsActiveSetIsActive_Bundle.cpp @@ -25,32 +25,28 @@ #include "config.h" #include "InjectedBundleTest.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> + +#include <cstdlib> namespace TestWebKitAPI { -class WKViewClientWebProcessCallbacksTest : public InjectedBundleTest { +class WKViewIsActiveSetIsActiveTest : public InjectedBundleTest { public: - WKViewClientWebProcessCallbacksTest(const std::string& identifier); - -private: - virtual void didReceiveMessage(WKBundleRef, WKStringRef messageName, WKTypeRef messageBody); + WKViewIsActiveSetIsActiveTest(const std::string& identifier) + : InjectedBundleTest(identifier) + { + } + + virtual void didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody) + { + if (!WKStringIsEqualToUTF8CString(messageName, "Crash")) + return; + abort(); + } }; -static InjectedBundleTest::Register<WKViewClientWebProcessCallbacksTest> registrar("WKViewClientWebProcessCallbacksTest"); - -WKViewClientWebProcessCallbacksTest::WKViewClientWebProcessCallbacksTest(const std::string& identifier) - : InjectedBundleTest(identifier) -{ -} - -void WKViewClientWebProcessCallbacksTest::didReceiveMessage(WKBundleRef, WKStringRef messageName, WKTypeRef) -{ - if (!WKStringIsEqualToUTF8CString(messageName, "Crash")) - return; - - // Simulating a crash - abort(); -} +static InjectedBundleTest::Register<WKViewIsActiveSetIsActiveTest> registrar("WKViewIsActiveSetIsActiveTest"); } // namespace TestWebKitAPI + diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewRestoreZoomAndScrollBackForward.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewRestoreZoomAndScrollBackForward.cpp new file mode 100644 index 000000000..5c556ecee --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewRestoreZoomAndScrollBackForward.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2012-2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2011 Samsung Electronics. 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 THE COPYRIGHT HOLDERS ``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 HOLDERS 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 "ewk_view_private.h" +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include <WebKit/WKContext.h> +#include <WebKit/WKRetainPtr.h> +#include "Test.h" + +namespace TestWebKitAPI { + +static bool finishedLoad = false; +static bool scroll = false; + +static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) +{ + finishedLoad = true; +} + +static void didChangeContentsPosition(WKViewRef, WKPoint p, const void*) +{ + scroll = true; +} + +TEST(WebKit2, WKViewRestoreZoomAndScrollBackForward) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + PlatformWebView webView(context.get()); + WKRetainPtr<WKViewRef> view = EWKViewGetWKView(webView.platformView()); + + WKPageSetUseFixedLayout(webView.page(), true); + + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + loaderClient.base.version = 0; + loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); + + WKViewClientV0 viewClient; + memset(&viewClient, 0, sizeof(viewClient)); + viewClient.base.version = 0; + viewClient.didChangeContentsPosition = didChangeContentsPosition; + WKViewSetViewClient(view.get(), &viewClient.base); + + // Load first page. + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("CoordinatedGraphics/backforward1", "html")); + WKPageLoadURL(webView.page(), url.get()); + Util::run(&finishedLoad); + + // Change scale and position on first page. + float firstPageScale = 2.0; + WKPoint firstPageScrollPosition = WKPointMake(10, 350); // Scroll position of first page. + WKViewSetContentPosition(view.get(), firstPageScrollPosition); + WKViewSetContentScaleFactor(view.get(), firstPageScale); + float currentPageScale = WKViewGetContentScaleFactor(view.get()); + WKPoint currentPagePosition = WKViewGetContentPosition(view.get()); + Util::run(&scroll); + EXPECT_EQ(firstPageScale, currentPageScale); + EXPECT_EQ(firstPageScrollPosition.x, currentPagePosition.x); + EXPECT_EQ(firstPageScrollPosition.y, currentPagePosition.y); + + // Load second page. + finishedLoad = false; + url = adoptWK(Util::createURLForResource("CoordinatedGraphics/backforward2", "html")); + WKPageLoadURL(webView.page(), url.get()); + Util::run(&finishedLoad); + + // Check if second page scale and position is correct. + currentPageScale = WKViewGetContentScaleFactor(view.get()); + currentPagePosition = WKViewGetContentPosition(view.get()); + EXPECT_EQ(1, currentPageScale); + EXPECT_EQ(0, currentPagePosition.x); + EXPECT_EQ(0, currentPagePosition.y); + + // Go back first page. + scroll = false; + finishedLoad = false; + WKPageGoBack(webView.page()); + Util::run(&finishedLoad); + Util::run(&scroll); + + // Check if scroll position and scale of first page are restored correctly. + currentPageScale = WKViewGetContentScaleFactor(view.get()); + currentPagePosition = WKViewGetContentPosition(view.get()); + EXPECT_EQ(firstPageScale, currentPageScale); + EXPECT_EQ(firstPageScrollPosition.x, currentPagePosition.x); + EXPECT_EQ(firstPageScrollPosition.y, currentPagePosition.y); + + // Go to second page again. + WKPageGoForward(webView.page()); + scroll = false; + finishedLoad = false; + Util::run(&finishedLoad); + + // Check if the scroll position and scale of second page are restored correctly. + currentPageScale = WKViewGetContentScaleFactor(view.get()); + currentPagePosition = WKViewGetContentPosition(view.get()); + EXPECT_EQ(1, currentPageScale); + EXPECT_EQ(0, currentPagePosition.x); + EXPECT_EQ(0, currentPagePosition.y); +} + +} // TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewUserViewportToContents.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewUserViewportToContents.cpp index de80f4437..2445fd71f 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewUserViewportToContents.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/WKViewUserViewportToContents.cpp @@ -25,12 +25,12 @@ #include "config.h" -#include "WebKit2/WKView.h" -#include "WebKit2/WKRetainPtr.h" +#include "WebKit/WKView.h" +#include "WebKit/WKRetainPtr.h" namespace TestWebKitAPI { -TEST(WebKit2, WKViewUserViewportToContents) +TEST(WebKit2, DISABLED_WKViewUserViewportToContents) { // This test creates a WKView and uses the WKViewUserViewportToContents // function to convert viewport coordinates to contents (page) coordinates. @@ -38,9 +38,12 @@ TEST(WebKit2, WKViewUserViewportToContents) // conversion math is right. WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - WKRetainPtr<WKViewRef> webView(AdoptWK, WKViewCreate(context.get(), 0)); + WKRetainPtr<WKPageConfigurationRef> configuration(AdoptWK, WKPageConfigurationCreate()); + WKPageConfigurationSetContext(configuration.get(), context.get()); - WKViewInitialize(webView.get()); + WKRetainPtr<WKViewRef> webView(AdoptWK, WKViewCreate(context.get(), configuration.get())); + + WKViewSetIsActive(webView.get(), true); WKPageSetUseFixedLayout(WKViewGetPage(webView.get()), false); WKPoint out; diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/backforward1.html b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/backforward1.html new file mode 100644 index 000000000..98c1c107c --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/backforward1.html @@ -0,0 +1,5 @@ +<html> +<body style="width:100%; height:100%"> + <div style="position: absolute; top: 0; left: 0; width: 900px; height: 1200px;"></div> +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/backforward2.html b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/backforward2.html new file mode 100644 index 000000000..3806b9d32 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/CoordinatedGraphics/backforward2.html @@ -0,0 +1 @@ +<body style="width:100%; height:100%"/> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic.cpp index 7ccddaea2..c336652ac 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> #include <wtf/Vector.h> namespace TestWebKitAPI { @@ -83,12 +86,13 @@ TEST(WebKit2, DISABLED_DOMWindowExtensionBasic) WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextForInjectedBundleTest("DOMWindowExtensionBasic", pageGroup.get())); - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = 0; - injectedBundleClient.clientInfo = 0; + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient); + + WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient.base); // The default cache model has a capacity of 0, so it is necessary to switch to a cache // model that actually allows for a page cache. @@ -132,3 +136,5 @@ TEST(WebKit2, DISABLED_DOMWindowExtensionBasic) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp index 5b1296f47..9bdc683ba 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp @@ -24,14 +24,17 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" -#include <WebKit2/WKBundleDOMWindowExtension.h> -#include <WebKit2/WKBundleFrame.h> -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundlePageGroup.h> -#include <WebKit2/WKBundlePrivate.h> -#include <WebKit2/WKBundleScriptWorld.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKBundleDOMWindowExtension.h> +#include <WebKit/WKBundleFrame.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundlePageGroup.h> +#include <WebKit/WKBundlePrivate.h> +#include <WebKit/WKBundleScriptWorld.h> +#include <WebKit/WKRetainPtr.h> #include <wtf/HashMap.h> #include <assert.h> @@ -152,18 +155,18 @@ void DOMWindowExtensionBasic::didCreatePage(WKBundleRef bundle, WKBundlePageRef { m_bundle = bundle; - WKBundlePageLoaderClient pageLoaderClient; + WKBundlePageLoaderClientV1 pageLoaderClient; memset(&pageLoaderClient, 0, sizeof(pageLoaderClient)); - pageLoaderClient.version = 1; - pageLoaderClient.clientInfo = this; + pageLoaderClient.base.version = 1; + pageLoaderClient.base.clientInfo = this; pageLoaderClient.didFinishLoadForFrame = didFinishLoadForFrameCallback; pageLoaderClient.globalObjectIsAvailableForFrame = globalObjectIsAvailableForFrameCallback; pageLoaderClient.willDisconnectDOMWindowExtensionFromGlobalObject = willDisconnectDOMWindowExtensionFromGlobalObjectCallback; pageLoaderClient.didReconnectDOMWindowExtensionToGlobalObject = didReconnectDOMWindowExtensionToGlobalObjectCallback; pageLoaderClient.willDestroyGlobalObjectForDOMWindowExtension = willDestroyGlobalObjectForDOMWindowExtensionCallback; - WKBundlePageSetPageLoaderClient(page, &pageLoaderClient); + WKBundlePageSetPageLoaderClient(page, &pageLoaderClient.base); } void DOMWindowExtensionBasic::willDestroyPage(WKBundleRef, WKBundlePageRef) @@ -257,3 +260,5 @@ static void willDestroyGlobalObjectForDOMWindowExtensionCallback(WKBundlePageRef } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache.cpp index ac04012ca..56a069fb9 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" @@ -84,12 +87,13 @@ TEST(WebKit2, DISABLED_DOMWindowExtensionNoCache) WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextForInjectedBundleTest("DOMWindowExtensionNoCache", pageGroup.get())); - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV1 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = kWKContextInjectedBundleClientCurrentVersion; - injectedBundleClient.clientInfo = 0; + + injectedBundleClient.base.version = 1; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient); + + WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient.base); // Disable the page cache. WKContextSetCacheModel(context.get(), kWKCacheModelDocumentViewer); @@ -131,3 +135,5 @@ TEST(WebKit2, DISABLED_DOMWindowExtensionNoCache) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp index f563b67c6..e48dadd1e 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_Bundle.cpp @@ -24,14 +24,17 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" -#include <WebKit2/WKBundleDOMWindowExtension.h> -#include <WebKit2/WKBundleFrame.h> -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundlePageGroup.h> -#include <WebKit2/WKBundlePrivate.h> -#include <WebKit2/WKBundleScriptWorld.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKBundleDOMWindowExtension.h> +#include <WebKit/WKBundleFrame.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundlePageGroup.h> +#include <WebKit/WKBundlePrivate.h> +#include <WebKit/WKBundleScriptWorld.h> +#include <WebKit/WKRetainPtr.h> #include <wtf/HashMap.h> #include <assert.h> @@ -159,18 +162,18 @@ void DOMWindowExtensionNoCache::didCreatePage(WKBundleRef bundle, WKBundlePageRe { m_bundle = bundle; - WKBundlePageLoaderClient pageLoaderClient; + WKBundlePageLoaderClientV7 pageLoaderClient; memset(&pageLoaderClient, 0, sizeof(pageLoaderClient)); - pageLoaderClient.version = kWKBundlePageLoaderClientCurrentVersion; - pageLoaderClient.clientInfo = this; + pageLoaderClient.base.version = 7; + pageLoaderClient.base.clientInfo = this; pageLoaderClient.didFinishLoadForFrame = didFinishLoadForFrameCallback; pageLoaderClient.globalObjectIsAvailableForFrame = globalObjectIsAvailableForFrameCallback; pageLoaderClient.willDisconnectDOMWindowExtensionFromGlobalObject = willDisconnectDOMWindowExtensionFromGlobalObjectCallback; pageLoaderClient.didReconnectDOMWindowExtensionToGlobalObject = didReconnectDOMWindowExtensionToGlobalObjectCallback; pageLoaderClient.willDestroyGlobalObjectForDOMWindowExtension = willDestroyGlobalObjectForDOMWindowExtensionCallback; - WKBundlePageSetPageLoaderClient(page, &pageLoaderClient); + WKBundlePageSetPageLoaderClient(page, &pageLoaderClient.base); } void DOMWindowExtensionNoCache::willDestroyPage(WKBundleRef, WKBundlePageRef) @@ -276,3 +279,5 @@ static void willDestroyGlobalObjectForDOMWindowExtensionCallback(WKBundlePageRef } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DidAssociateFormControls.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DidAssociateFormControls.cpp index 4e6b4fe1d..a930f5346 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/DidAssociateFormControls.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DidAssociateFormControls.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" @@ -63,11 +66,13 @@ static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messag static void setInjectedBundleClient(WKContextRef context) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } TEST(WebKit2, DidAssociateFormControls) @@ -81,3 +86,5 @@ TEST(WebKit2, DidAssociateFormControls) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DidAssociateFormControls_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DidAssociateFormControls_Bundle.cpp index b742650af..5dcd91da8 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/DidAssociateFormControls_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DidAssociateFormControls_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundle.h> -#include <WebKit2/WKBundlePage.h> +#include <WebKit/WKBundle.h> +#include <WebKit/WKBundlePage.h> namespace TestWebKitAPI { @@ -36,7 +39,7 @@ class DidAssociateFormControlsTest : public InjectedBundleTest { public: DidAssociateFormControlsTest(const std::string& identifier); - virtual void didCreatePage(WKBundleRef, WKBundlePageRef) OVERRIDE; + virtual void didCreatePage(WKBundleRef, WKBundlePageRef) override; }; static InjectedBundleTest::Register<DidAssociateFormControlsTest> registrar("DidAssociateFormControlsTest"); @@ -50,11 +53,11 @@ static void didAssociateFormControls(WKBundlePageRef page, WKArrayRef elementHan { WKRetainPtr<WKMutableDictionaryRef> messageBody = adoptWK(WKMutableDictionaryCreate()); - WKDictionaryAddItem(messageBody.get(), Util::toWK("Page").get(), page); + WKDictionarySetItem(messageBody.get(), Util::toWK("Page").get(), page); WKRetainPtr<WKUInt64Ref> numberOfElements = adoptWK(WKUInt64Create(WKArrayGetSize(elementHandles))); - WKDictionaryAddItem(messageBody.get(), Util::toWK("NumberOfControls").get(), numberOfElements.get()); + WKDictionarySetItem(messageBody.get(), Util::toWK("NumberOfControls").get(), numberOfElements.get()); - WKBundlePostMessage(InjectedBundleController::shared().bundle(), Util::toWK("DidReceiveDidAssociateFormControls").get(), messageBody.get()); + WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("DidReceiveDidAssociateFormControls").get(), messageBody.get()); } DidAssociateFormControlsTest::DidAssociateFormControlsTest(const std::string& identifier) @@ -64,15 +67,17 @@ DidAssociateFormControlsTest::DidAssociateFormControlsTest(const std::string& id void DidAssociateFormControlsTest::didCreatePage(WKBundleRef bundle, WKBundlePageRef page) { - WKBundlePageFormClient formClient; + WKBundlePageFormClientV2 formClient; memset(&formClient, 0, sizeof(formClient)); - formClient.version = 2; - formClient.clientInfo = this; + formClient.base.version = 2; + formClient.base.clientInfo = this; formClient.shouldNotifyOnFormChanges = shouldNotifyOnFormChanges; formClient.didAssociateFormControls = didAssociateFormControls; - WKBundlePageSetFormClient(page, &formClient); + WKBundlePageSetFormClient(page, &formClient.base); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/mac/EditorCommands.mm b/Tools/TestWebKitAPI/Tests/WebKit2/DidNotHandleKeyDown.cpp index 583dc7a53..b5f4fb863 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/mac/EditorCommands.mm +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DidNotHandleKeyDown.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,46 +24,60 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "JavaScriptTest.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { -static bool didFinishLoad; +static bool didFinishTest; +static bool didNotHandleKeyDownEvent; static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) { - didFinishLoad = true; } -TEST(WebKit2, ScrollByLineCommands) +static void didNotHandleKeyEventCallback(WKPageRef, WKNativeEventPtr event, const void*) +{ + if (Util::isKeyDown(event)) + didNotHandleKeyDownEvent = true; + didFinishTest = true; +} + +TEST(WebKit2, DidNotHandleKeyDown) { WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextWithInjectedBundle()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); - WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple-tall", "html")); - WKPageLoadURL(webView.page(), url.get()); - Util::run(&didFinishLoad); + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); + + WKPageUIClientV0 uiClient; + memset(&uiClient, 0, sizeof(uiClient)); - EXPECT_JS_EQ(webView.page(), "window.scrollY", "0"); + uiClient.base.version = 0; + uiClient.didNotHandleKeyEvent = didNotHandleKeyEventCallback; - ASSERT_TRUE([webView.platformView() respondsToSelector:@selector(scrollLineDown:)]); - [webView.platformView() scrollLineDown:nil]; + WKPageSetPageUIClient(webView.page(), &uiClient.base); - EXPECT_JS_EQ(webView.page(), "window.scrollY", "40"); + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); + WKPageLoadURL(webView.page(), url.get()); - ASSERT_TRUE([webView.platformView() respondsToSelector:@selector(scrollLineUp:)]); - [webView.platformView() scrollLineUp:nil]; + webView.simulateSpacebarKeyPress(); - EXPECT_JS_EQ(webView.page(), "window.scrollY", "0"); + Util::run(&didFinishTest); + EXPECT_TRUE(didNotHandleKeyDownEvent); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash.cpp index 7559da28d..21bca74dd 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -50,12 +53,13 @@ TEST(WebKit2, DocumentStartUserScriptAlertCrashTest) WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextForInjectedBundleTest("DocumentStartUserScriptAlertCrashTest", pageGroup.get())); PlatformWebView webView(context.get(), pageGroup.get()); - WKPageUIClient uiClient; + WKPageUIClientV0 uiClient; memset(&uiClient, 0, sizeof(uiClient)); - uiClient.version = 0; - uiClient.clientInfo = 0; + + uiClient.base.version = 0; uiClient.runJavaScriptAlert = runJavaScriptAlert; - WKPageSetPageUIClient(webView.page(), &uiClient); + + WKPageSetPageUIClient(webView.page(), &uiClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -64,3 +68,5 @@ TEST(WebKit2, DocumentStartUserScriptAlertCrashTest) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp index 30805f759..18b9f1b48 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DocumentStartUserScriptAlertCrash_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" -#include <WebKit2/WKBundlePageGroup.h> -#include <WebKit2/WKBundlePrivate.h> -#include <WebKit2/WKBundleScriptWorld.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKBundlePageGroup.h> +#include <WebKit/WKBundlePrivate.h> +#include <WebKit/WKBundleScriptWorld.h> +#include <WebKit/WKRetainPtr.h> #include <assert.h> namespace TestWebKitAPI { @@ -53,3 +56,5 @@ public: static InjectedBundleTest::Register<DocumentStartUserScriptAlertCrashTest> registrar("DocumentStartUserScriptAlertCrashTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/DownloadDecideDestinationCrash.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/DownloadDecideDestinationCrash.cpp index f360646dd..eac36d87a 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/DownloadDecideDestinationCrash.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/DownloadDecideDestinationCrash.cpp @@ -24,15 +24,18 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKDownload.h> +#include <WebKit/WKDownload.h> namespace TestWebKitAPI { static bool didDecideDestination; -static void decidePolicyForNavigationAction(WKPageRef, WKFrameRef, WKFrameNavigationType, WKEventModifiers, WKEventMouseButton, WKURLRequestRef, WKFramePolicyListenerRef listener, WKTypeRef, const void*) +static void decidePolicyForNavigationAction(WKPageRef, WKFrameRef, WKFrameNavigationType, WKEventModifiers, WKEventMouseButton, WKFrameRef, WKURLRequestRef, WKFramePolicyListenerRef listener, WKTypeRef, const void*) { WKFramePolicyListenerDownload(listener); } @@ -41,25 +44,29 @@ static WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownlo { didDecideDestination = true; WKDownloadCancel(download); - return Util::toWK("does not matter").leakRef(); + return Util::toWK("/tmp/WebKitAPITest/DownloadDecideDestinationCrash").leakRef(); } static void setContextDownloadClient(WKContextRef context) { - WKContextDownloadClient client; + WKContextDownloadClientV0 client; memset(&client, 0, sizeof(client)); + + client.base.version = 0; client.decideDestinationWithSuggestedFilename = decideDestinationWithSuggestedFilename; - WKContextSetDownloadClient(context, &client); + WKContextSetDownloadClient(context, &client.base); } static void setPagePolicyClient(WKPageRef page) { - WKPagePolicyClient policyClient; + WKPagePolicyClientV1 policyClient; memset(&policyClient, 0, sizeof(policyClient)); + + policyClient.base.version = 1; policyClient.decidePolicyForNavigationAction = decidePolicyForNavigationAction; - WKPageSetPagePolicyClient(page, &policyClient); + WKPageSetPagePolicyClient(page, &policyClient.base); } TEST(WebKit2, DownloadDecideDestinationCrash) @@ -79,3 +86,5 @@ TEST(WebKit2, DownloadDecideDestinationCrash) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/win/HideFindIndicator.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/EphemeralSessionPushStateNoHistoryCallback.cpp index 6e350ff81..07a81f646 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/win/HideFindIndicator.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/EphemeralSessionPushStateNoHistoryCallback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,62 +24,60 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { -static bool didFinishLoad; -static bool findIndicatorCallbackWasCalled; -static HBITMAP bitmap; +static bool testDone; -static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) +static void didNavigateWithNavigationData(WKContextRef context, WKPageRef page, WKNavigationDataRef navigationData, WKFrameRef frame, const void* clientInfo) { - didFinishLoad = true; + // This should never be called when navigating in Private Browsing. + FAIL(); } -static void findIndicatorCallback(WKViewRef, HBITMAP selectionBitmap, RECT, bool, void*) +static void didSameDocumentNavigationForFrame(WKPageRef page, WKFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef userData, const void *clientInfo) { - findIndicatorCallbackWasCalled = true; - bitmap = selectionBitmap; + testDone = true; } -static void initialize(const PlatformWebView& webView) +TEST(WebKit2, EphemeralSessionPushStateNoHistoryCallback) { - WKPageLoaderClient loaderClient; - memset(&loaderClient, 0, sizeof(loaderClient)); + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - loaderClient.version = 0; - loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + WKContextHistoryClientV0 historyClient; + memset(&historyClient, 0, sizeof(historyClient)); - WKViewSetFindIndicatorCallback(webView.platformView(), findIndicatorCallback, 0); -} + historyClient.base.version = 0; + historyClient.didNavigateWithNavigationData = didNavigateWithNavigationData; + + WKContextSetHistoryClient(context.get(), &historyClient.base); -TEST(WebKit2, HideFindIndicator) -{ - WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - initialize(webView); - WKRetainPtr<WKURLRef> url = adoptWK(Util::createURLForResource("find", "html")); - WKPageLoadURL(webView.page(), url.get()); - Util::run(&didFinishLoad); - didFinishLoad = false; + WKPageLoaderClientV0 pageLoaderClient; + memset(&pageLoaderClient, 0, sizeof(pageLoaderClient)); - WKPageFindString(webView.page(), Util::toWK("Hello").get(), kWKFindOptionsShowFindIndicator, 100); - Util::run(&findIndicatorCallbackWasCalled); - findIndicatorCallbackWasCalled = false; + pageLoaderClient.base.version = 0; + pageLoaderClient.didSameDocumentNavigationForFrame = didSameDocumentNavigationForFrame; - EXPECT_NOT_NULL(bitmap); - ::DeleteObject(bitmap); - bitmap = 0; + WKPageSetPageLoaderClient(webView.page(), &pageLoaderClient.base); - WKPageHideFindUI(webView.page()); - Util::run(&findIndicatorCallbackWasCalled); + WKSessionRef session = WKSessionCreate(true); + WKPageSetSession(webView.page(), session); - EXPECT_NULL(bitmap); + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("push-state", "html")); + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&testDone); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/EvaluateJavaScript.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/EvaluateJavaScript.cpp index 90ad04fd1..a6b5a4dd5 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/EvaluateJavaScript.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/EvaluateJavaScript.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKSerializedScriptValue.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKSerializedScriptValue.h> namespace TestWebKitAPI { @@ -58,3 +61,5 @@ TEST(WebKit2, EvaluateJavaScriptThatThrowsAnException) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp index 99b1b9744..c12b5366b 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/FailedLoad.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -50,13 +53,13 @@ TEST(WebKit2, FailedLoad) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.clientInfo = 0; + loaderClient.base.version = 0; loaderClient.didFailProvisionalLoadWithErrorForFrame = didFailProvisionalLoadWithErrorForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::URLForNonExistentResource()); WKPageLoadURL(webView.page(), url.get()); @@ -65,3 +68,5 @@ TEST(WebKit2, FailedLoad) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/Find.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/Find.cpp index 2717c1355..2e2189906 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/Find.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/Find.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -51,19 +54,21 @@ TEST(WebKit2, Find) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); - WKPageFindClient findClient; + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); + + WKPageFindClientV0 findClient; memset(&findClient, 0, sizeof(findClient)); - findClient.version = 0; + findClient.base.version = 0; findClient.didCountStringMatches = didCountStringMatches; - WKPageSetPageFindClient(webView.page(), &findClient); + + WKPageSetPageFindClient(webView.page(), &findClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("find", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -77,3 +82,5 @@ TEST(WebKit2, Find) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/FindMatches.mm b/Tools/TestWebKitAPI/Tests/WebKit2/FindMatches.mm deleted file mode 100644 index 4a5734f58..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/FindMatches.mm +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformUtilities.h" -#include "PlatformWebView.h" -#import <WebKit/WebDocumentPrivate.h> -#import <WebKit/DOMPrivate.h> -#include <WebKit2/WKImage.h> -#import <wtf/RetainPtr.h> - -@interface FindMatchesWK1FrameLoadDelegate : NSObject { -} -@end - -static bool didFinishLoadWK1; - -@implementation FindMatchesWK1FrameLoadDelegate - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoadWK1 = true; -} - -@end - -namespace TestWebKitAPI { - -static bool didFinishLoad = false; -static bool didCallFindStringMatches = false; -static bool didCallGetImage = false; -static WKFindOptions findOptions = kWKFindOptionsAtWordStarts; - -RetainPtr<WebView> webkit1View; - -static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) -{ - didFinishLoad = true; -} - -static void didFindStringMatches(WKPageRef page, WKStringRef string, WKArrayRef matches, int firstIndex, const void* clientInfo) -{ - if (WKStringIsEqualToUTF8CString(string, "Hello")) { - size_t numMatches = WKArrayGetSize(matches); - EXPECT_EQ(3u, numMatches); - - if (findOptions & kWKFindOptionsBackwards) - EXPECT_EQ(1, firstIndex); - else - EXPECT_EQ(2, firstIndex); - - for (size_t i = 0; i < numMatches; ++i) { - WKTypeRef items = WKArrayGetItemAtIndex(matches, i); - WKTypeID type = WKGetTypeID(items); - EXPECT_EQ(type, WKArrayGetTypeID()); - WKArrayRef rects = reinterpret_cast<WKArrayRef>(items); - size_t numRects = WKArrayGetSize(rects); - EXPECT_EQ(1u, numRects); - items = WKArrayGetItemAtIndex(rects, 0); - type = WKGetTypeID(items); - EXPECT_EQ(type, WKRectGetTypeID()); - WKRect rect = WKRectGetValue(reinterpret_cast<WKRectRef>(items)); - rect = rect; - } - } else if (WKStringIsEqualToUTF8CString(string, "crazy")) { - size_t numMatches = WKArrayGetSize(matches); - EXPECT_EQ(1u, numMatches); - EXPECT_EQ(kWKFindResultNoMatchAfterUserSelection, firstIndex); - } - didCallFindStringMatches = true; -} - -static void didGetImageForMatchResult(WKPageRef page, WKImageRef image, uint32_t index, const void* clientInfo) -{ - WKSize size = WKImageGetSize(image); - - DOMDocument *document = webkit1View.get().mainFrameDocument; - DOMRange *range = [document createRange]; - DOMNode *target = [document getElementById:@"target"]; - [range selectNode:target]; - NSImage *expectedImage = [range renderedImageForcingBlackText:YES]; - NSSize expectedSize = [expectedImage size]; - EXPECT_EQ(size.width, expectedSize.width); - EXPECT_EQ(size.height, expectedSize.height); - didCallGetImage = true; -} - -TEST(WebKit2, FindMatches) -{ - WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - PlatformWebView webView(context.get()); - - WKPageLoaderClient loaderClient; - memset(&loaderClient, 0, sizeof(loaderClient)); - - loaderClient.version = 0; - loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); - - WKPageFindMatchesClient findMatchesClient; - memset(&findMatchesClient, 0, sizeof(findMatchesClient)); - - findMatchesClient.version = 0; - findMatchesClient.didFindStringMatches = didFindStringMatches; - findMatchesClient.didGetImageForMatchResult = didGetImageForMatchResult; - - WKPageSetPageFindMatchesClient(webView.page(), &findMatchesClient); - - // This HTML file contains 3 occurrences of the word Hello and has the second occurence of the word 'world' selected. - // It contains 1 occurrence of the word 'crazy' that is before the selected word. - WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("findRanges", "html")); - WKPageLoadURL(webView.page(), url.get()); - - Util::run(&didFinishLoad); - - WKRetainPtr<WKStringRef> findString(AdoptWK, WKStringCreateWithUTF8CString("Hello")); - - WKPageFindStringMatches(webView.page(), findString.get(), findOptions, 100); - Util::run(&didCallFindStringMatches); - - didCallFindStringMatches = false; - findOptions |= kWKFindOptionsBackwards; - WKPageFindStringMatches(webView.page(), findString.get(), findOptions, 100); - Util::run(&didCallFindStringMatches); - - webkit1View = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<FindMatchesWK1FrameLoadDelegate> frameLoadDelegate = adoptNS([FindMatchesWK1FrameLoadDelegate new]); - - webkit1View.get().frameLoadDelegate = frameLoadDelegate.get(); - [webkit1View.get().mainFrame loadHTMLString:@"Test search. Hello <span id=\"target\">Hello</span> Hello!" baseURL:[NSURL URLWithString:@"about:blank"]]; - - Util::run(&didFinishLoadWK1); - - WKPageGetImageForFindMatch(webView.page(), 0); - Util::run(&didCallGetImage); - - didCallFindStringMatches = false; - findOptions &= ~kWKFindOptionsBackwards; - WKRetainPtr<WKStringRef> findOtherString(AdoptWK, WKStringCreateWithUTF8CString("crazy")); - WKPageFindStringMatches(webView.page(), findOtherString.get(), findOptions, 100); - Util::run(&didCallFindStringMatches); - - WKPageHideFindUI(webView.page()); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ForceRepaint.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ForceRepaint.cpp index 08873f843..6cd63fab4 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ForceRepaint.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ForceRepaint.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -51,12 +54,13 @@ TEST(WebKit2, ForceRepaint) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple-accelerated-compositing", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -66,3 +70,5 @@ TEST(WebKit2, ForceRepaint) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypeHTML.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypeHTML.cpp index 734986628..2c9c11332 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypeHTML.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypeHTML.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -58,15 +61,15 @@ TEST(WebKit2, FrameMIMETypeHTML) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.clientInfo = 0; + loaderClient.base.version = 0; loaderClient.didStartProvisionalLoadForFrame = didStartProvisionalLoadForFrame; loaderClient.didCommitLoadForFrame = didCommitLoadForFrame; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -75,3 +78,5 @@ TEST(WebKit2, FrameMIMETypeHTML) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypePNG.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypePNG.cpp index 46f63dae9..eb3bf38a3 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypePNG.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/FrameMIMETypePNG.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -57,15 +60,15 @@ TEST(WebKit2, FrameMIMETypePNG) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.clientInfo = 0; + loaderClient.base.version = 0; loaderClient.didStartProvisionalLoadForFrame = didStartProvisionalLoadForFrame; loaderClient.didCommitLoadForFrame = didCommitLoadForFrame; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("icon", "png")); WKPageLoadURL(webView.page(), url.get()); @@ -74,3 +77,5 @@ TEST(WebKit2, FrameMIMETypePNG) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/Geolocation.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/Geolocation.cpp new file mode 100644 index 000000000..90fd37937 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/Geolocation.cpp @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2013 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" + +#if WK_HAVE_C_SPI + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" +#include <WebKit/WKContextPrivate.h> +#include <WebKit/WKRetainPtr.h> +#include <string.h> +#include <vector> + +using namespace std; + +namespace TestWebKitAPI { + +enum class GeolocationEvent { + StartUpdating, + StopUpdating, + EnableHighAccuracy, + DisableHighAccuracy +}; + +ostream& operator<<(ostream& outputStream, const GeolocationEvent& geolocationEvent) +{ + switch (geolocationEvent) { + case GeolocationEvent::StartUpdating: + outputStream << "GeolocationEvent::StartUpdating"; + break; + case GeolocationEvent::StopUpdating: + outputStream << "GeolocationEvent::StopUpdating"; + break; + case GeolocationEvent::EnableHighAccuracy: + outputStream << "GeolocationEvent::EnableHighAccuracy"; + break; + case GeolocationEvent::DisableHighAccuracy: + outputStream << "GeolocationEvent::DisableHighAccuracy"; + break; + } + return outputStream; +} + +struct GeolocationStateTracker { + vector<GeolocationEvent> events; + + virtual ~GeolocationStateTracker() { } + virtual void eventsChanged() { } + + static void startUpdatingCallback(WKGeolocationManagerRef manager, const void* clientInfo) + { + GeolocationStateTracker* stateTracker = static_cast<GeolocationStateTracker*>(const_cast<void*>(clientInfo)); + stateTracker->events.push_back(GeolocationEvent::StartUpdating); + stateTracker->eventsChanged(); + + WKRetainPtr<WKGeolocationPositionRef> position = adoptWK(WKGeolocationPositionCreate(0, 50.644358, 3.345453, 2.53)); + WKGeolocationManagerProviderDidChangePosition(manager, position.get()); + } + + static void stopUpdatingCallback(WKGeolocationManagerRef, const void* clientInfo) + { + GeolocationStateTracker* stateTracker = static_cast<GeolocationStateTracker*>(const_cast<void*>(clientInfo)); + stateTracker->events.push_back(GeolocationEvent::StopUpdating); + stateTracker->eventsChanged(); + } + + static void setEnableHighAccuracyCallback(WKGeolocationManagerRef, bool enable, const void* clientInfo) + { + GeolocationStateTracker* stateTracker = static_cast<GeolocationStateTracker*>(const_cast<void*>(clientInfo)); + if (enable) + stateTracker->events.push_back(GeolocationEvent::EnableHighAccuracy); + else + stateTracker->events.push_back(GeolocationEvent::DisableHighAccuracy); + stateTracker->eventsChanged(); + } +}; + +void decidePolicyForGeolocationPermissionRequestCallBack(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKGeolocationPermissionRequestRef permissionRequest, const void* clientInfo) +{ + WKGeolocationPermissionRequestAllow(permissionRequest); +} + +void setupGeolocationProvider(WKContextRef context, void *clientInfo) +{ + WKGeolocationProviderV1 providerCallback; + memset(&providerCallback, 0, sizeof(WKGeolocationProviderV1)); + + providerCallback.base.version = 1; + providerCallback.base.clientInfo = clientInfo; + providerCallback.startUpdating = GeolocationStateTracker::startUpdatingCallback; + providerCallback.stopUpdating = GeolocationStateTracker::stopUpdatingCallback; + providerCallback.setEnableHighAccuracy = GeolocationStateTracker::setEnableHighAccuracyCallback; + + WKGeolocationManagerSetProvider(WKContextGetGeolocationManager(context), &providerCallback.base); +} + +void setupView(PlatformWebView& webView) +{ + WKPageUIClientV2 uiClient; + memset(&uiClient, 0, sizeof(uiClient)); + + uiClient.base.version = 2; + uiClient.decidePolicyForGeolocationPermissionRequest = decidePolicyForGeolocationPermissionRequestCallBack; + + WKPageSetPageUIClient(webView.page(), &uiClient.base); +} + +// GeolocationBasic. +struct GeolocationBasicStateTracker : GeolocationStateTracker { + bool finished; + + GeolocationBasicStateTracker() : finished(false) { } + virtual void eventsChanged() + { + switch (events.size()) { + case 1: + EXPECT_EQ(GeolocationEvent::DisableHighAccuracy, events[0]); + break; + case 2: + EXPECT_EQ(GeolocationEvent::StartUpdating, events[1]); + break; + case 3: + EXPECT_EQ(GeolocationEvent::StopUpdating, events[2]); + finished = true; + break; + default: + EXPECT_TRUE(false); + finished = true; + } + } +}; + +TEST(WebKit2, GeolocationBasic) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + + GeolocationBasicStateTracker stateTracker; + setupGeolocationProvider(context.get(), &stateTracker); + + PlatformWebView webView(context.get()); + setupView(webView); + + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("geolocationGetCurrentPosition", "html")); + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&stateTracker.finished); +} + +// Geolocation requested with High Accuracy. +struct GeolocationBasicWithHighAccuracyStateTracker : GeolocationStateTracker { + bool finished; + + GeolocationBasicWithHighAccuracyStateTracker() : finished(false) { } + virtual void eventsChanged() + { + switch (events.size()) { + case 1: + EXPECT_EQ(GeolocationEvent::EnableHighAccuracy, events[0]); + break; + case 2: + EXPECT_EQ(GeolocationEvent::StartUpdating, events[1]); + break; + case 3: + EXPECT_EQ(GeolocationEvent::StopUpdating, events[2]); + finished = true; + break; + default: + EXPECT_TRUE(false); + finished = true; + } + } +}; + +TEST(WebKit2, GeolocationBasicWithHighAccuracy) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + + GeolocationBasicWithHighAccuracyStateTracker stateTracker; + setupGeolocationProvider(context.get(), &stateTracker); + + PlatformWebView webView(context.get()); + setupView(webView); + + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("geolocationGetCurrentPositionWithHighAccuracy", "html")); + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&stateTracker.finished); +} + +// Geolocation start without High Accuracy, then requires High Accuracy. +struct GeolocationTransitionToHighAccuracyStateTracker : GeolocationStateTracker { + bool finishedFirstStep { false }; + bool enabledHighAccuracy { false }; + bool finished { false }; + + virtual void eventsChanged() + { + switch (events.size()) { + case 1: + EXPECT_EQ(GeolocationEvent::DisableHighAccuracy, events[0]); + break; + case 2: + EXPECT_EQ(GeolocationEvent::StartUpdating, events[1]); + finishedFirstStep = true; + break; + case 3: + EXPECT_EQ(GeolocationEvent::EnableHighAccuracy, events[2]); + enabledHighAccuracy = true; + break; + case 4: + EXPECT_EQ(GeolocationEvent::DisableHighAccuracy, events[3]); + break; + case 5: + EXPECT_EQ(GeolocationEvent::StopUpdating, events[4]); + finished = true; + break; + default: + EXPECT_TRUE(false); + finishedFirstStep = true; + enabledHighAccuracy = true; + finished = true; + } + } +}; + +TEST(WebKit2, GeolocationTransitionToHighAccuracy) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + WKContextSetMaximumNumberOfProcesses(context.get(), 1); + + GeolocationTransitionToHighAccuracyStateTracker stateTracker; + setupGeolocationProvider(context.get(), &stateTracker); + + PlatformWebView lowAccuracyWebView(context.get()); + setupView(lowAccuracyWebView); + WKRetainPtr<WKURLRef> lowAccuracyURL(AdoptWK, Util::createURLForResource("geolocationWatchPosition", "html")); + WKPageLoadURL(lowAccuracyWebView.page(), lowAccuracyURL.get()); + Util::run(&stateTracker.finishedFirstStep); + + PlatformWebView highAccuracyWebView(context.get()); + setupView(highAccuracyWebView); + WKRetainPtr<WKURLRef> highAccuracyURL(AdoptWK, Util::createURLForResource("geolocationWatchPositionWithHighAccuracy", "html")); + WKPageLoadURL(highAccuracyWebView.page(), highAccuracyURL.get()); + Util::run(&stateTracker.enabledHighAccuracy); + + WKRetainPtr<WKURLRef> resetUrl = adoptWK(WKURLCreateWithUTF8CString("about:blank")); + WKPageLoadURL(highAccuracyWebView.page(), resetUrl.get()); + Util::run(&stateTracker.enabledHighAccuracy); + WKPageLoadURL(lowAccuracyWebView.page(), resetUrl.get()); + Util::run(&stateTracker.finished); +} + +// Geolocation start with High Accuracy, then should fall back to low accuracy. +struct GeolocationTransitionToLowAccuracyStateTracker : GeolocationStateTracker { + bool finishedFirstStep { false }; + bool disabledHighAccuracy { false }; + bool finished { false }; + + virtual void eventsChanged() + { + switch (events.size()) { + case 1: + EXPECT_EQ(GeolocationEvent::EnableHighAccuracy, events[0]); + break; + case 2: + EXPECT_EQ(GeolocationEvent::StartUpdating, events[1]); + finishedFirstStep = true; + break; + case 3: + EXPECT_EQ(GeolocationEvent::DisableHighAccuracy, events[2]); + disabledHighAccuracy = true; + break; + case 4: + EXPECT_EQ(GeolocationEvent::StopUpdating, events[3]); + finished = true; + break; + default: + EXPECT_TRUE(false); + finishedFirstStep = true; + disabledHighAccuracy = true; + finished = true; + } + } +}; + +static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) +{ + *static_cast<bool*>(const_cast<void*>(clientInfo)) = true; +} + +TEST(WebKit2, GeolocationTransitionToLowAccuracy) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + WKContextSetMaximumNumberOfProcesses(context.get(), 1); + + GeolocationTransitionToLowAccuracyStateTracker stateTracker; + setupGeolocationProvider(context.get(), &stateTracker); + + PlatformWebView highAccuracyWebView(context.get()); + setupView(highAccuracyWebView); + WKRetainPtr<WKURLRef> highAccuracyURL(AdoptWK, Util::createURLForResource("geolocationWatchPositionWithHighAccuracy", "html")); + WKPageLoadURL(highAccuracyWebView.page(), highAccuracyURL.get()); + Util::run(&stateTracker.finishedFirstStep); + + PlatformWebView lowAccuracyWebView(context.get()); + setupView(lowAccuracyWebView); + + bool finishedSecondStep = false; + + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 0; + loaderClient.base.clientInfo = &finishedSecondStep; + loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + + WKPageSetPageLoaderClient(lowAccuracyWebView.page(), &loaderClient.base); + + WKRetainPtr<WKURLRef> lowAccuracyURL(AdoptWK, Util::createURLForResource("geolocationWatchPosition", "html")); + WKPageLoadURL(lowAccuracyWebView.page(), lowAccuracyURL.get()); + Util::run(&finishedSecondStep); + + WKRetainPtr<WKURLRef> resetUrl = adoptWK(WKURLCreateWithUTF8CString("about:blank")); + WKPageLoadURL(highAccuracyWebView.page(), resetUrl.get()); + Util::run(&stateTracker.disabledHighAccuracy); + WKPageLoadURL(lowAccuracyWebView.page(), resetUrl.get()); + Util::run(&stateTracker.finished); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback.cpp index 4bfe87949..e3280a3b7 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -47,13 +50,14 @@ TEST(WebKit2, GetInjectedBundleInitializationUserDataCallback) { WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextWithInjectedBundle()); - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV1 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = 1; - injectedBundleClient.clientInfo = 0; + + injectedBundleClient.base.version = 1; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; injectedBundleClient.getInjectedBundleInitializationUserData = getInjectedBundleInitializationUserData; - WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient); + + WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient.base); PlatformWebView webView(context.get()); @@ -64,3 +68,5 @@ TEST(WebKit2, GetInjectedBundleInitializationUserDataCallback) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback_Bundle.cpp index 97500b59b..bf8da42e3 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/GetInjectedBundleInitializationUserDataCallback_Bundle.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -46,3 +49,5 @@ public: static InjectedBundleTest::Register<GetInjectedBundleInitializationUserDataCallbackTest> registrar("GetInjectedBundleInitializationUserDataCallbackTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle.cpp index 2100d28c3..1f4a3726c 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -48,22 +51,24 @@ static void didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRe static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } static void setInjectedBundleClient(WKContextRef context) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = 0; - injectedBundleClient.clientInfo = 0; + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } TEST(WebKit2, HitTestResultNodeHandle) @@ -84,3 +89,5 @@ TEST(WebKit2, HitTestResultNodeHandle) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle_Bundle.cpp index 882909e81..d68ff2193 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/HitTestResultNodeHandle_Bundle.cpp @@ -24,12 +24,15 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "InjectedBundleController.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundleHitTestResult.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundleHitTestResult.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -46,19 +49,23 @@ public: if (!nodeHandle) return; - WKBundlePostMessage(InjectedBundleController::shared().bundle(), Util::toWK("HitTestResultNodeHandleTestDoneMessageName").get(), Util::toWK("HitTestResultNodeHandleTestDoneMessageBody").get()); + WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("HitTestResultNodeHandleTestDoneMessageName").get(), Util::toWK("HitTestResultNodeHandleTestDoneMessageBody").get()); } virtual void didCreatePage(WKBundleRef bundle, WKBundlePageRef page) { - WKBundlePageContextMenuClient contextMenuClient; + WKBundlePageContextMenuClientV0 contextMenuClient; memset(&contextMenuClient, 0, sizeof(contextMenuClient)); + + contextMenuClient.base.version = 0; contextMenuClient.getContextMenuFromDefaultMenu = getContextMenuFromDefaultMenu; - WKBundlePageSetContextMenuClient(page, &contextMenuClient); + WKBundlePageSetContextMenuClient(page, &contextMenuClient.base); } }; static InjectedBundleTest::Register<HitTestResultNodeHandleTest> registrar("HitTestResultNodeHandleTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic.cpp index 083a88f05..a1d4046ed 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -52,21 +55,23 @@ TEST(WebKit2, InjectedBundleBasic) { WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextForInjectedBundleTest("InjectedBundleBasicTest")); - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = 0; - injectedBundleClient.clientInfo = 0; + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient); + + WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient.base); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.clientInfo = 0; + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -75,3 +80,5 @@ TEST(WebKit2, InjectedBundleBasic) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic_Bundle.cpp index 6a597be41..4d8689b93 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleBasic_Bundle.cpp @@ -24,8 +24,11 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -47,3 +50,5 @@ public: static InjectedBundleTest::Register<InjectedBundleBasicTest> registrar("InjectedBundleBasicTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleFrameHitTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleFrameHitTest.cpp index 9320801d3..e178dc3cb 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleFrameHitTest.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleFrameHitTest.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -43,12 +46,13 @@ static void didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRe static void setInjectedBundleClient(WKContextRef context) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = 0; - injectedBundleClient.clientInfo = 0; + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } TEST(WebKit2, InjectedBundleFrameHitTest) @@ -65,3 +69,5 @@ TEST(WebKit2, InjectedBundleFrameHitTest) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleFrameHitTest_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleFrameHitTest_Bundle.cpp index ddaeec182..14806685e 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleFrameHitTest_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleFrameHitTest_Bundle.cpp @@ -24,13 +24,16 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundle.h> -#include <WebKit2/WKBundleFramePrivate.h> -#include <WebKit2/WKBundleHitTestResult.h> -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKBundle.h> +#include <WebKit/WKBundleFramePrivate.h> +#include <WebKit/WKBundleHitTestResult.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -41,7 +44,7 @@ public: { } - virtual void didCreatePage(WKBundleRef, WKBundlePageRef) OVERRIDE; + virtual void didCreatePage(WKBundleRef, WKBundlePageRef) override; void frameLoadFinished(WKBundleFrameRef); WKBundleRef m_bundle; @@ -58,14 +61,14 @@ void InjectedBundleFrameHitTestTest::didCreatePage(WKBundleRef bundle, WKBundleP { m_bundle = bundle; - WKBundlePageLoaderClient pageLoaderClient; + WKBundlePageLoaderClientV1 pageLoaderClient; memset(&pageLoaderClient, 0, sizeof(pageLoaderClient)); - pageLoaderClient.version = 1; - pageLoaderClient.clientInfo = this; + pageLoaderClient.base.version = 1; + pageLoaderClient.base.clientInfo = this; pageLoaderClient.didFinishLoadForFrame = didFinishLoadForFrameCallback; - WKBundlePageSetPageLoaderClient(page, &pageLoaderClient); + WKBundlePageSetPageLoaderClient(page, &pageLoaderClient.base); } void InjectedBundleFrameHitTestTest::frameLoadFinished(WKBundleFrameRef frame) @@ -76,3 +79,5 @@ void InjectedBundleFrameHitTestTest::frameLoadFinished(WKBundleFrameRef frame) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins.cpp index 360cf39db..678aaa85b 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -49,13 +52,14 @@ TEST(WebKit2, InjectedBundleInitializationUserDataCallbackWins) WKRetainPtr<WKDictionaryRef> initializationDictionary(AdoptWK, Util::createInitializationDictionaryForInjectedBundleTest("InjectedBundleInitializationUserDataCallbackWinsTest", Util::toWK("Set with WKContextSetInitializationUserDataForInjectedBundle").get())); WKContextSetInitializationUserDataForInjectedBundle(context.get(), initializationDictionary.get()); - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV1 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = 1; - injectedBundleClient.clientInfo = 0; + + injectedBundleClient.base.version = 1; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; injectedBundleClient.getInjectedBundleInitializationUserData = getInjectedBundleInitializationUserData; - WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient); + + WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient.base); PlatformWebView webView(context.get()); @@ -66,3 +70,5 @@ TEST(WebKit2, InjectedBundleInitializationUserDataCallbackWins) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp index 36708a4d7..cac7738dd 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleInitializationUserDataCallbackWins_Bundle.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -46,3 +49,5 @@ public: static InjectedBundleTest::Register<InjectedBundleInitializationUserDataCallbackWinsTest> registrar("InjectedBundleInitializationUserDataCallbackWinsTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKConnection_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootOpen_Bundle.cpp index 9ab2c9768..4a923dba9 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WKConnection_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootOpen_Bundle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,37 +24,42 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" -#include "PlatformUtilities.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKBundlePageGroup.h> +#include <WebKit/WKBundlePrivate.h> +#include <WebKit/WKBundleScriptWorld.h> +#include <WebKit/WKRetainPtr.h> +#include <assert.h> namespace TestWebKitAPI { -/* WKConnectionClient */ -static void connectionDidReceiveMessage(WKConnectionRef connection, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo) -{ - // Post a simple message to the back to the application layer. - WKConnectionPostMessage(connection, Util::toWK("PongMessageName").get(), Util::toWK("PongMessageBody").get()); -} - -class WKConnectionTest : public InjectedBundleTest { +class InjectedBundleMakeAllShadowRootOpenTest : public InjectedBundleTest { public: - WKConnectionTest(const std::string& identifier) + InjectedBundleMakeAllShadowRootOpenTest(const std::string& identifier) : InjectedBundleTest(identifier) - { - } + { } - virtual void initialize(WKBundleRef bundle, WKTypeRef) + virtual void initialize(WKBundleRef bundle, WKTypeRef userData) { - WKConnectionClient connectionClient; - memset(&connectionClient, 0, sizeof(connectionClient)); - connectionClient.version = WKConnectionClientCurrentVersion; - connectionClient.clientInfo = 0; - connectionClient.didReceiveMessage = connectionDidReceiveMessage; - WKConnectionSetConnectionClient(WKBundleGetApplicationConnection(bundle), &connectionClient); + assert(WKGetTypeID(userData) == WKBundlePageGroupGetTypeID()); + WKBundlePageGroupRef pageGroup = static_cast<WKBundlePageGroupRef>(userData); + + auto world = WKBundleScriptWorldCreateWorld(); + WKBundleScriptWorldMakeAllShadowRootsOpen(world); + + WKRetainPtr<WKStringRef> source(AdoptWK, WKStringCreateWithUTF8CString( + "var element = document.createElement('div');" + "element.attachShadow({mode: 'closed'});" + "alert(element.shadowRoot ? 'PASS' : 'FAIL');")); + WKBundleAddUserScript(bundle, pageGroup, world, source.get(), 0, 0, 0, kWKInjectAtDocumentStart, kWKInjectInAllFrames); } }; -static InjectedBundleTest::Register<WKConnectionTest> registrar("WKConnectionTest"); +static InjectedBundleTest::Register<InjectedBundleMakeAllShadowRootOpenTest> registrar("InjectedBundleMakeAllShadowRootOpenTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp new file mode 100644 index 000000000..982e6964e --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/InjectedBundleMakeAllShadowRootsOpen.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010, 2016 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" + +#if WK_HAVE_C_SPI + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" +#include <WebKit/WKRetainPtr.h> + +namespace TestWebKitAPI { + +static bool done; + +static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo) +{ + ASSERT_NOT_NULL(frame); + + EXPECT_EQ(page, WKFrameGetPage(frame)); + EXPECT_WK_STREQ("PASS", alertText); + + done = true; +} + +TEST(WebKit2, InjectedBundleMakeAllShadowRootOpenTest) +{ + WKRetainPtr<WKPageGroupRef> pageGroup(AdoptWK, WKPageGroupCreateWithIdentifier(WKStringCreateWithUTF8CString("InjectedBundleMakeAllShadowRootOpenTestPageGroup"))); + + WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextForInjectedBundleTest("InjectedBundleMakeAllShadowRootOpenTest", pageGroup.get())); + PlatformWebView webView(context.get(), pageGroup.get()); + + WKPageUIClientV0 uiClient; + memset(&uiClient, 0, sizeof(uiClient)); + + uiClient.base.version = 0; + uiClient.runJavaScriptAlert = runJavaScriptAlert; + + WKPageSetPageUIClient(webView.page(), &uiClient.base); + + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&done); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/mac/GetPIDAfterAbortedProcessLaunch.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/LayoutMilestonesWithAllContentInFrame.cpp index 5b37b0845..aa294643c 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/mac/GetPIDAfterAbortedProcessLaunch.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/LayoutMilestonesWithAllContentInFrame.cpp @@ -24,49 +24,48 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" - -#include <WebKit2/WKPagePrivateMac.h> -#include <WebKit2/WKContextPrivate.h> +#include "Test.h" +#include <WebKit/WKContextPrivate.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { -static bool loaded; +static bool testDone; -static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) +static void didLayout(WKPageRef page, WKLayoutMilestones milestones, WKTypeRef, const void* clientInfo) { - loaded = true; + // This test ensures that the DidFirstVisuallyNonEmptyLayout will be reached for the main frame + // even when all of the content is in a subframe. + if (milestones & kWKDidFirstVisuallyNonEmptyLayout) + testDone = true; } -TEST(WebKit2, GetPIDAfterAbortedProcessLaunch) +TEST(WebKit2, LayoutMilestonesWithAllContentInFrame) { WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - WKContextSetUsesNetworkProcess(context.get(), true); - PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV3 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); - - WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); - WKPageLoadURL(webView.page(), url.get()); - - Util::run(&loaded); - WKPageTerminate(webView.page()); + loaderClient.base.version = 3; + loaderClient.base.clientInfo = &webView; + loaderClient.didLayout = didLayout; - // Reloading will start relaunching the process. - WKPageReload(webView.page()); + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); - WKPageClose(webView.page()); + WKPageListenForLayoutMilestones(webView.page(), kWKDidFirstVisuallyNonEmptyLayout); + WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("all-content-in-one-iframe", "html")).get()); - // And now we try to get the PID page when the page has been closed before the process launch was complete. - EXPECT_EQ(0, WKPageGetProcessIdentifier(webView.page())); + Util::run(&testDone); + EXPECT_TRUE(testDone); } } // namespace TestWebKitAPI +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/LoadAlternateHTMLStringWithNonDirectoryURL.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/LoadAlternateHTMLStringWithNonDirectoryURL.cpp index 78787414d..acc23348b 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/LoadAlternateHTMLStringWithNonDirectoryURL.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/LoadAlternateHTMLStringWithNonDirectoryURL.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2015 Igalia S.L. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,13 +25,16 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "JavaScriptTest.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKContext.h> -#include <WebKit2/WKPage.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKContext.h> +#include <WebKit/WKPage.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -41,26 +45,41 @@ static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef us didFinishLoad = true; } -TEST(WebKit2, LoadAlternateHTMLStringWithNonDirectoryURL) +static void loadAlternateHTMLString(WKURLRef baseURL, WKURLRef unreachableURL) { WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); - WKRetainPtr<WKURLRef> fileURL(AdoptWK, Util::createURLForResource("simple", "html")); WKRetainPtr<WKStringRef> alternateHTMLString(AdoptWK, WKStringCreateWithUTF8CString("<html><body><img src='icon.png'></body></html>")); - - // Call WKPageLoadAlternateHTMLString() with fileURL which does not point to a directory - WKPageLoadAlternateHTMLString(webView.page(), alternateHTMLString.get(), fileURL.get(), fileURL.get()); - + WKPageLoadAlternateHTMLString(webView.page(), alternateHTMLString.get(), baseURL, unreachableURL); + // If we can finish loading the html without resulting in an invalid message being sent from the WebProcess, this test passes. Util::run(&didFinishLoad); } +TEST(WebKit2, LoadAlternateHTMLStringWithNonDirectoryURL) +{ + // Call WKPageLoadAlternateHTMLString() with fileURL which does not point to a directory. + WKRetainPtr<WKURLRef> fileURL(AdoptWK, Util::createURLForResource("simple", "html")); + loadAlternateHTMLString(fileURL.get(), fileURL.get()); +} + +TEST(WebKit2, LoadAlternateHTMLStringWithEmptyBaseURL) +{ + // Call WKPageLoadAlternateHTMLString() with empty baseURL to make sure this test works + // when baseURL does not grant read access to the unreachableURL. We use a separate test + // to ensure the previous test does not pollute the result. + WKRetainPtr<WKURLRef> unreachableURL(AdoptWK, Util::URLForNonExistentResource()); + loadAlternateHTMLString(nullptr, unreachableURL.get()); +} + } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback.cpp index 7dbd063bc..ac45fba26 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback.cpp @@ -24,13 +24,16 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "JavaScriptTest.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKContext.h> -#include <WebKit2/WKFrame.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKContext.h> +#include <WebKit/WKFrame.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -59,27 +62,30 @@ TEST(WebKit2, LoadCanceledNoServerRedirectCallback) { WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextForInjectedBundleTest("LoadCanceledNoServerRedirectCallbackTest")); - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = 0; - injectedBundleClient.clientInfo = 0; - WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient); + + injectedBundleClient.base.version = 0; + + WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient.base); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); - WKContextHistoryClient historyClient; + WKContextHistoryClientV0 historyClient; memset(&historyClient, 0, sizeof(historyClient)); - historyClient.version = 0; + historyClient.base.version = 0; historyClient.didPerformServerRedirect = didPerformServerRedirect; - WKContextSetHistoryClient(context.get(), &historyClient); + + WKContextSetHistoryClient(context.get(), &historyClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple-iframe", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -90,3 +96,5 @@ TEST(WebKit2, LoadCanceledNoServerRedirectCallback) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback_Bundle.cpp index 0792c3f8a..6ea0dc77d 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/LoadCanceledNoServerRedirectCallback_Bundle.cpp @@ -24,13 +24,16 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" #include "Test.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundleFrame.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundleFrame.h> +#include <WebKit/WKRetainPtr.h> #include <wtf/Assertions.h> @@ -56,13 +59,13 @@ public: virtual void didCreatePage(WKBundleRef bundle, WKBundlePageRef page) { - WKBundlePageResourceLoadClient resourceLoadClient; + WKBundlePageResourceLoadClientV0 resourceLoadClient; memset(&resourceLoadClient, 0, sizeof(resourceLoadClient)); - resourceLoadClient.version = 0; + resourceLoadClient.base.version = 0; resourceLoadClient.willSendRequestForFrame = willSendRequestForFrame; - WKBundlePageSetResourceLoadClient(page, &resourceLoadClient); + WKBundlePageSetResourceLoadClient(page, &resourceLoadClient.base); } }; @@ -70,3 +73,5 @@ public: static InjectedBundleTest::Register<LoadCanceledNoServerRedirectCallbackTest> registrar("LoadCanceledNoServerRedirectCallbackTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/LoadPageOnCrash.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/LoadPageOnCrash.cpp index f3d1830d6..63ad664e2 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/LoadPageOnCrash.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/LoadPageOnCrash.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -43,9 +46,12 @@ public: , secondSuccessfulLoad(false) { memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.clientInfo = this; + + loaderClient.base.version = 0; + loaderClient.base.clientInfo = this; loaderClient.didFinishLoadForFrame = didFinishLoad; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); } void loadUrl() @@ -59,7 +65,7 @@ public: } WKRetainPtr<WKContextRef> context; - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; PlatformWebView webView; WKRetainPtr<WKURLRef> url; @@ -100,3 +106,5 @@ TEST(WebKit2, LoadPageAfterCrash) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/MenuTypesForMouseEvents.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/MenuTypesForMouseEvents.cpp new file mode 100644 index 000000000..f77a11ad8 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/MenuTypesForMouseEvents.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2015 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" + +#if WK_HAVE_C_SPI + +#include "JavaScriptTest.h" +#include "PlatformUtilities.h" +#include "PlatformWebView.h" + +namespace TestWebKitAPI { + +static bool didFinishLoad; + +static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) +{ + didFinishLoad = true; +} + +static void setPageLoaderClient(WKPageRef page) +{ + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 0; + loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + + WKPageSetPageLoaderClient(page, &loaderClient.base); +} + +static void buildAndPerformTest(WKEventMouseButton button, WKEventModifiers modifiers, const char* expectedButton, const char* expectedMenuType) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + PlatformWebView webView(context.get()); + setPageLoaderClient(webView.page()); + + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("mouse-button-listener", "html")); + WKPageLoadURL(webView.page(), url.get()); + Util::run(&didFinishLoad); + + didFinishLoad = false; + + webView.simulateButtonClick(button, 10, 10, modifiers); + + EXPECT_JS_EQ(webView.page(), "pressedMouseButton()", expectedButton); + EXPECT_JS_EQ(webView.page(), "displayedMenu()", expectedMenuType); +} + +TEST(WebKit2, MenuAndButtonForNormalLeftClick) +{ + buildAndPerformTest(kWKEventMouseButtonLeftButton, 0, "0", "none"); +} + +TEST(WebKit2, MenuAndButtonForNormalRightClick) +{ + buildAndPerformTest(kWKEventMouseButtonRightButton, 0, "2", "context"); +} + +TEST(WebKit2, MenuAndButtonForNormalMiddleClick) +{ + buildAndPerformTest(kWKEventMouseButtonMiddleButton, 0, "1", "none"); +} + +TEST(WebKit2, MenuAndButtonForControlLeftClick) +{ + buildAndPerformTest(kWKEventMouseButtonLeftButton, kWKEventModifiersControlKey, "0", "context"); +} + +TEST(WebKit2, MenuAndButtonForControlRightClick) +{ + buildAndPerformTest(kWKEventMouseButtonRightButton, kWKEventModifiersControlKey, "2", "context"); +} + +TEST(WebKit2, MenuAndButtonForControlMiddleClick) +{ + buildAndPerformTest(kWKEventMouseButtonMiddleButton, kWKEventModifiersControlKey, "1", "none"); +} + +TEST(WebKit2, MenuAndButtonForShiftLeftClick) +{ + buildAndPerformTest(kWKEventMouseButtonLeftButton, kWKEventModifiersShiftKey, "0", "none"); +} + +TEST(WebKit2, MenuAndButtonForShiftRightClick) +{ + buildAndPerformTest(kWKEventMouseButtonRightButton, kWKEventModifiersShiftKey, "2", "context"); +} + +TEST(WebKit2, MenuAndButtonForShiftMiddleClick) +{ + buildAndPerformTest(kWKEventMouseButtonMiddleButton, kWKEventModifiersShiftKey, "1", "none"); +} + +TEST(WebKit2, MenuAndButtonForCommandLeftClick) +{ + buildAndPerformTest(kWKEventMouseButtonLeftButton, kWKEventModifiersMetaKey, "0", "none"); +} + +TEST(WebKit2, MenuAndButtonForCommandRightClick) +{ + buildAndPerformTest(kWKEventMouseButtonRightButton, kWKEventModifiersMetaKey, "2", "context"); +} + +TEST(WebKit2, MenuAndButtonForCommandMiddleClick) +{ + buildAndPerformTest(kWKEventMouseButtonMiddleButton, kWKEventModifiersMetaKey, "1", "none"); +} + +TEST(WebKit2, MenuAndButtonForAltLeftClick) +{ + buildAndPerformTest(kWKEventMouseButtonLeftButton, kWKEventModifiersAltKey, "0", "none"); +} + +TEST(WebKit2, MenuAndButtonForAltRightClick) +{ + buildAndPerformTest(kWKEventMouseButtonRightButton, kWKEventModifiersAltKey, "2", "context"); +} + +TEST(WebKit2, MenuAndButtonForAltMiddleClick) +{ + buildAndPerformTest(kWKEventMouseButtonMiddleButton, kWKEventModifiersAltKey, "1", "none"); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ModalAlertsSPI.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ModalAlertsSPI.cpp new file mode 100644 index 000000000..0278f005b --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ModalAlertsSPI.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2015 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" + +#if WK_HAVE_C_SPI + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" +#include <WebKit/WKFrame.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKSecurityOriginRef.h> + +namespace TestWebKitAPI { + +static bool done; +static unsigned dialogsSeen; +static const unsigned dialogsExpected = 3; + +static void analyzeDialogArguments(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef securityOrigin) +{ + EXPECT_EQ(page, WKFrameGetPage(frame)); + + WKRetainPtr<WKURLRef> url = adoptWK(WKFrameCopyURL(frame)); + WKRetainPtr<WKStringRef> urlString = adoptWK(WKURLCopyString(url.get())); + EXPECT_WK_STREQ("about:blank", urlString.get()); + + WKRetainPtr<WKStringRef> protocol = adoptWK(WKSecurityOriginCopyProtocol(securityOrigin)); + EXPECT_WK_STREQ("file", protocol.get()); + + WKRetainPtr<WKStringRef> host = adoptWK(WKSecurityOriginCopyHost(securityOrigin)); + EXPECT_WK_STREQ("", host.get()); + + EXPECT_EQ(WKSecurityOriginGetPort(securityOrigin), 0); + + if (++dialogsSeen == dialogsExpected) + done = true; +} + +static void runJavaScriptAlert(WKPageRef page, WKStringRef, WKFrameRef frame, WKSecurityOriginRef securityOrigin, const void*) +{ + analyzeDialogArguments(page, frame, securityOrigin); +} + +static bool runJavaScriptConfirm(WKPageRef page, WKStringRef, WKFrameRef frame, WKSecurityOriginRef securityOrigin, const void*) +{ + analyzeDialogArguments(page, frame, securityOrigin); + return false; +} + +static WKStringRef runJavaScriptPrompt(WKPageRef page, WKStringRef, WKStringRef, WKFrameRef frame, WKSecurityOriginRef securityOrigin, const void*) +{ + analyzeDialogArguments(page, frame, securityOrigin); + return nullptr; +} + +static std::unique_ptr<PlatformWebView> openedWebView; + +static WKPageRef createNewPage(WKPageRef page, WKURLRequestRef urlRequest, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void *clientInfo) +{ + EXPECT_TRUE(openedWebView == nullptr); + + openedWebView = std::make_unique<PlatformWebView>(page); + + WKPageUIClientV5 uiClient; + memset(&uiClient, 0, sizeof(uiClient)); + + uiClient.base.version = 5; + uiClient.runJavaScriptAlert = runJavaScriptAlert; + uiClient.runJavaScriptConfirm = runJavaScriptConfirm; + uiClient.runJavaScriptPrompt = runJavaScriptPrompt; + + WKPageSetPageUIClient(openedWebView->page(), &uiClient.base); + + WKRetain(openedWebView->page()); + return openedWebView->page(); +} + +TEST(WebKit2, ModalAlertsSPI) +{ + WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); + PlatformWebView webView(context.get()); + + WKPageUIClientV5 uiClient; + memset(&uiClient, 0, sizeof(uiClient)); + + uiClient.base.version = 5; + uiClient.createNewPage = createNewPage; + + WKPageSetPageUIClient(webView.page(), &uiClient.base); + + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("modal-alerts-in-new-about-blank-window", "html")); + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&done); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash.cpp index 4bf5527f9..9d7f3997d 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "JavaScriptTest.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" @@ -39,20 +42,16 @@ static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.clientInfo = 0; + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } -#if PLATFORM(WIN) -TEST(WebKit2, DISABLED_MouseMoveAfterCrash) -#else TEST(WebKit2, MouseMoveAfterCrash) -#endif { WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("MouseMoveAfterCrashTest")); @@ -90,3 +89,5 @@ TEST(WebKit2, MouseMoveAfterCrash) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash_Bundle.cpp index a07562093..8d92f4209 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/MouseMoveAfterCrash_Bundle.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" @@ -54,3 +57,5 @@ void MouseMoveAfterCrashTest::didReceiveMessage(WKBundleRef bundle, WKStringRef } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout.cpp index 605003ed6..778d285ba 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKContextPrivate.h> +#include <WebKit/WKContextPrivate.h> namespace TestWebKitAPI { @@ -57,12 +60,13 @@ static void didLayout(WKPageRef, WKLayoutMilestones type, WKTypeRef, const void static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV3 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = kWKPageLoaderClientCurrentVersion; + + loaderClient.base.version = 3; loaderClient.didLayout = didLayout; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } // FIXME: This test has been broken since http://trac.webkit.org/changeset/115752 It's failing because @@ -85,3 +89,5 @@ TEST(WebKit2, DISABLED_NewFirstVisuallyNonEmptyLayout) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails.cpp index 06c71502e..5cff318fa 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKContextPrivate.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKContextPrivate.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -56,13 +59,14 @@ static void didLayout(WKPageRef, WKLayoutMilestones type, WKTypeRef, const void static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV3 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = kWKPageLoaderClientCurrentVersion; + + loaderClient.base.version = 3; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; loaderClient.didLayout = didLayout; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } TEST(WebKit2, NewFirstVisuallyNonEmptyLayoutFails) @@ -85,3 +89,5 @@ TEST(WebKit2, NewFirstVisuallyNonEmptyLayoutFails) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp index b909ec941..2700d66c8 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFails_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundlePagePrivate.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundlePagePrivate.h> namespace TestWebKitAPI { @@ -49,3 +52,5 @@ public: static InjectedBundleTest::Register<NewFirstVisuallyNonEmptyLayoutFailsTest> registrar("NewFirstVisuallyNonEmptyLayoutFailsTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages.cpp index 2ec5bd05c..7bd1fd7b3 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKContextPrivate.h> +#include <WebKit/WKContextPrivate.h> namespace TestWebKitAPI { @@ -57,12 +60,13 @@ static void didLayout(WKPageRef, WKLayoutMilestones type, WKTypeRef, const void static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV3 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = kWKPageLoaderClientCurrentVersion; + + loaderClient.base.version = 3; loaderClient.didLayout = didLayout; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } // FIXME: This test has been broken since http://trac.webkit.org/changeset/115752 It's failing because @@ -85,3 +89,5 @@ TEST(WebKit2, DISABLED_NewFirstVisuallyNonEmptyLayoutForImages) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp index bdaade77b..d8644bb69 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundlePagePrivate.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundlePagePrivate.h> namespace TestWebKitAPI { @@ -49,3 +52,5 @@ public: static InjectedBundleTest::Register<NewFirstVisuallyNonEmptyLayoutForImagesTest> registrar("NewFirstVisuallyNonEmptyLayoutForImagesTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames.cpp index 1ad4b9986..c7b24680e 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKContextPrivate.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKContextPrivate.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -61,13 +64,14 @@ static void didLayout(WKPageRef, WKLayoutMilestones type, WKTypeRef, const void static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV3 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = kWKPageLoaderClientCurrentVersion; + + loaderClient.base.version = 3; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; loaderClient.didLayout = didLayout; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } TEST(WebKit2, NewFirstVisuallyNonEmptyLayoutFrames) @@ -89,3 +93,5 @@ TEST(WebKit2, NewFirstVisuallyNonEmptyLayoutFrames) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp index 33e16bd3e..f66fc957d 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundlePagePrivate.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundlePagePrivate.h> namespace TestWebKitAPI { @@ -49,3 +52,5 @@ public: static InjectedBundleTest::Register<NewFirstVisuallyNonEmptyLayoutFramesTest> registrar("NewFirstVisuallyNonEmptyLayoutFramesTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout_Bundle.cpp index c408c3b2c..8f1901d10 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/NewFirstVisuallyNonEmptyLayout_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundlePagePrivate.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundlePagePrivate.h> namespace TestWebKitAPI { @@ -49,3 +52,5 @@ public: static InjectedBundleTest::Register<NewFirstVisuallyNonEmptyLayoutTest> registrar("NewFirstVisuallyNonEmptyLayoutTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp index 5f2f6e283..ad62a5b29 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/PageLoadBasic.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -85,7 +88,7 @@ static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef us test1Done = true; } -static void decidePolicyForNavigationAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) +static void decidePolicyForNavigationAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKFrameRef originatingFrame, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) { State* state = reinterpret_cast<State*>(const_cast<void*>(clientInfo)); EXPECT_FALSE(state->didStartProvisionalLoadForFrame); @@ -103,11 +106,12 @@ static void decidePolicyForNewWindowAction(WKPageRef page, WKFrameRef frame, WKF WKFramePolicyListenerUse(listener); } -static void decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) +static void decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, bool canShowMIMEType, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) { WKFramePolicyListenerUse(listener); } +// FIXME: http://webkit.org/b/127934 REGRESSION (r163037): WebKit2.PageLoadBasic API test failing on Mountain Lion TEST(WebKit2, PageLoadBasic) { State state; @@ -115,25 +119,27 @@ TEST(WebKit2, PageLoadBasic) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.clientInfo = &state; + loaderClient.base.version = 0; + loaderClient.base.clientInfo = &state; loaderClient.didStartProvisionalLoadForFrame = didStartProvisionalLoadForFrame; loaderClient.didCommitLoadForFrame = didCommitLoadForFrame; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); - WKPagePolicyClient policyClient; + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); + + WKPagePolicyClientV1 policyClient; memset(&policyClient, 0, sizeof(policyClient)); - policyClient.version = 0; - policyClient.clientInfo = &state; + policyClient.base.version = 1; + policyClient.base.clientInfo = &state; policyClient.decidePolicyForNavigationAction = decidePolicyForNavigationAction; policyClient.decidePolicyForNewWindowAction = decidePolicyForNewWindowAction; policyClient.decidePolicyForResponse = decidePolicyForResponse; - WKPageSetPagePolicyClient(webView.page(), &policyClient); + + WKPageSetPagePolicyClient(webView.page(), &policyClient.base); // Before loading anything, the active url should be null EXPECT_NULL(WKPageCopyActiveURL(webView.page())); @@ -149,4 +155,26 @@ TEST(WebKit2, PageLoadBasic) Util::run(&test1Done); } +TEST(WebKit2, PageReload) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + PlatformWebView webView(context.get()); + + // Reload test before url loading. + WKPageReload(webView.page()); + WKPageReload(webView.page()); + + WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); + WKPageLoadURL(webView.page(), url.get()); + + // Reload test after url loading. + WKPageReload(webView.page()); + + WKRetainPtr<WKURLRef> activeUrl = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeUrl.get()); + EXPECT_TRUE(WKURLIsEqual(activeUrl.get(), url.get())); +} + } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/PageLoadDidChangeLocationWithinPageForFrame.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/PageLoadDidChangeLocationWithinPageForFrame.cpp index 86fbe5ed6..46838db93 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/PageLoadDidChangeLocationWithinPageForFrame.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/PageLoadDidChangeLocationWithinPageForFrame.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -60,11 +63,14 @@ TEST(WebKit2, PageLoadDidChangeLocationWithinPageForFrame) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; loaderClient.didSameDocumentNavigationForFrame = didSameDocumentNavigationForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("file-with-anchor", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -81,3 +87,5 @@ TEST(WebKit2, PageLoadDidChangeLocationWithinPageForFrame) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/PageVisibilityState.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/PageVisibilityState.cpp deleted file mode 100644 index 8907b92e5..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/PageVisibilityState.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformUtilities.h" -#include "PlatformWebView.h" -#include "Test.h" -#include <JavaScriptCore/JSContextRef.h> -#include <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKSerializedScriptValue.h> - -namespace TestWebKitAPI { - -static bool testDone; - -static void didRunStep1StateChangeVisibleToHidden(WKSerializedScriptValueRef, WKErrorRef, void*); -static void didRunStep2StateChangeHiddenToPrerender(WKSerializedScriptValueRef, WKErrorRef, void*); -static void didRunStep3StateChangePrerenderToUnloaded(WKSerializedScriptValueRef, WKErrorRef, void*); -static void didRunStep4InStateUnloaded(WKSerializedScriptValueRef, WKErrorRef, void*); - -static void setPageVisibilityStateWithEvalContinuation(PlatformWebView* webView, WKPageVisibilityState visibilityState, WKPageRunJavaScriptFunction callback) -{ - WKPageSetVisibilityState(webView->page(), visibilityState, false); - WKRetainPtr<WKStringRef> javaScriptString(AdoptWK, WKStringCreateWithUTF8CString("document.visibilityState")); - WKPageRunJavaScriptInMainFrame(webView->page(), javaScriptString.get(), static_cast<void*>(webView), callback); -} - -static void assertSerializedScriptValueIsStringValue(WKSerializedScriptValueRef serializedValue, WKErrorRef error, const char *expected) -{ - EXPECT_NULL(error); - EXPECT_NOT_NULL(serializedValue); - if (error || !serializedValue) - return; - - JSGlobalContextRef scriptContext = JSGlobalContextCreate(0); - JSValueRef scriptValue = WKSerializedScriptValueDeserialize(serializedValue, scriptContext, 0); - EXPECT_TRUE(JSValueIsString(scriptContext, scriptValue)); - if (!JSValueIsString(scriptContext, scriptValue)) { - JSGlobalContextRelease(scriptContext); - return; - } - - JSStringRef expectedString = JSStringCreateWithUTF8CString(expected); - JSStringRef scriptString = JSValueToStringCopy(scriptContext, scriptValue, 0); - EXPECT_TRUE(JSStringIsEqual(scriptString, expectedString)); - - JSStringRelease(scriptString); - JSStringRelease(expectedString); - JSGlobalContextRelease(scriptContext); -} - -static void didRunStep1StateChangeVisibleToHidden(WKSerializedScriptValueRef resultSerializedScriptValue, WKErrorRef error, void* context) -{ - assertSerializedScriptValueIsStringValue(resultSerializedScriptValue, error, "visible"); - setPageVisibilityStateWithEvalContinuation(static_cast<PlatformWebView*>(context), kWKPageVisibilityStateHidden, didRunStep2StateChangeHiddenToPrerender); -} - -static void didRunStep2StateChangeHiddenToPrerender(WKSerializedScriptValueRef resultSerializedScriptValue, WKErrorRef error, void* context) -{ - assertSerializedScriptValueIsStringValue(resultSerializedScriptValue, error, "hidden"); - setPageVisibilityStateWithEvalContinuation(static_cast<PlatformWebView*>(context), kWKPageVisibilityStatePrerender, didRunStep3StateChangePrerenderToUnloaded); -} - -static void didRunStep3StateChangePrerenderToUnloaded(WKSerializedScriptValueRef resultSerializedScriptValue, WKErrorRef error, void* context) -{ - assertSerializedScriptValueIsStringValue(resultSerializedScriptValue, error, "prerender"); - setPageVisibilityStateWithEvalContinuation(static_cast<PlatformWebView*>(context), kWKPageVisibilityStateUnloaded, didRunStep4InStateUnloaded); -} - -static void didRunStep4InStateUnloaded(WKSerializedScriptValueRef resultSerializedScriptValue, WKErrorRef error, void* context) -{ - assertSerializedScriptValueIsStringValue(resultSerializedScriptValue, error, "unloaded"); - testDone = true; -} - -TEST(WebKit2, PageVisibilityState) -{ - WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - - // Pass the PlatformWebView webView on as the context of the evals, so we can continue to eval on it. - PlatformWebView webView(context.get()); - setPageVisibilityStateWithEvalContinuation(&webView, kWKPageVisibilityStateVisible, didRunStep1StateChangeVisibleToHidden); - - Util::run(&testDone); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame.cpp index 7645c66ee..7953608c8 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKContextPrivate.h> +#include <WebKit/WKContextPrivate.h> namespace TestWebKitAPI { @@ -45,11 +48,13 @@ static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messag static void setInjectedBundleClient(WKContextRef context) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } TEST(WebKit2, ParentFrame) @@ -66,3 +71,5 @@ TEST(WebKit2, ParentFrame) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame_Bundle.cpp index 40035e90c..e1da9ee02 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ParentFrame_Bundle.cpp @@ -24,12 +24,15 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundleFrame.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundleFrame.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -67,13 +70,15 @@ void ParentFrameTest::didCreatePage(WKBundleRef bundle, WKBundlePageRef page) { testBundle = bundle; - WKBundlePageLoaderClient pageLoaderClient; + WKBundlePageLoaderClientV1 pageLoaderClient; memset(&pageLoaderClient, 0, sizeof(pageLoaderClient)); - pageLoaderClient.version = 1; + pageLoaderClient.base.version = 1; pageLoaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKBundlePageSetPageLoaderClient(page, &pageLoaderClient); + WKBundlePageSetPageLoaderClient(page, &pageLoaderClient.base); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/PasteboardNotifications_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/PasteboardNotifications_Bundle.cpp index d33b77b55..8c1404e7a 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/PasteboardNotifications_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/PasteboardNotifications_Bundle.cpp @@ -24,13 +24,16 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKArray.h> -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundleBackForwardListItem.h> -#include <WebKit2/WKWebArchive.h> +#include <WebKit/WKArray.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundleBackForwardListItem.h> +#include <WebKit/WKWebArchive.h> namespace TestWebKitAPI { @@ -46,7 +49,7 @@ static InjectedBundleTest::Register<PasteboardNotificationsTest> registrar("Past static void willWriteToPasteboard(WKBundlePageRef page, WKBundleRangeHandleRef range, const void*) { if (!range) - WKBundlePostMessage(InjectedBundleController::shared().bundle(), Util::toWK("PasteboardNotificationTestDoneMessageName").get(), Util::toWK("willWritetoPasteboardFail").get()); + WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("PasteboardNotificationTestDoneMessageName").get(), Util::toWK("willWritetoPasteboardFail").get()); } static void getPasteboardDataForRange(WKBundlePageRef, WKBundleRangeHandleRef range, WKArrayRef* pasteboardTypes, WKArrayRef* pasteboardData, const void*) @@ -59,7 +62,7 @@ static void getPasteboardDataForRange(WKBundlePageRef, WKBundleRangeHandleRef ra static void didWriteToPasteboard(WKBundlePageRef, const void*) { - WKBundlePostMessage(InjectedBundleController::shared().bundle(), Util::toWK("PasteboardNotificationTestDoneMessageName").get(), Util::toWK("didWriteToPasteboard").get()); + WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("PasteboardNotificationTestDoneMessageName").get(), Util::toWK("didWriteToPasteboard").get()); } PasteboardNotificationsTest::PasteboardNotificationsTest(const std::string& identifier) @@ -69,17 +72,18 @@ PasteboardNotificationsTest::PasteboardNotificationsTest(const std::string& iden void PasteboardNotificationsTest::didCreatePage(WKBundleRef bundle, WKBundlePageRef page) { - WKBundlePageEditorClient pageEditorClient; - + WKBundlePageEditorClientV1 pageEditorClient; memset(&pageEditorClient, 0, sizeof(pageEditorClient)); - pageEditorClient.version = 1; - pageEditorClient.clientInfo = this; + pageEditorClient.base.version = 1; + pageEditorClient.base.clientInfo = this; pageEditorClient.willWriteToPasteboard = willWriteToPasteboard; pageEditorClient.getPasteboardDataForRange = getPasteboardDataForRange; pageEditorClient.didWriteToPasteboard = didWriteToPasteboard; - WKBundlePageSetEditorClient(page, &pageEditorClient); + WKBundlePageSetEditorClient(page, &pageEditorClient.base); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/PendingAPIRequestURL.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/PendingAPIRequestURL.cpp new file mode 100644 index 000000000..d02a5acf3 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/PendingAPIRequestURL.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * 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 "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" +#include <WebKit/WKRetainPtr.h> + +namespace TestWebKitAPI { + +static bool done; + +TEST(WebKit2, PendingAPIRequestURL) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + PlatformWebView webView(context.get()); + + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + loaderClient.base.version = 0; + loaderClient.didFinishLoadForFrame = [](WKPageRef, WKFrameRef, WKTypeRef, const void*) { done = true; }; + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); + + WKRetainPtr<WKURLRef> activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + EXPECT_NULL(activeURL.get()); + + WKRetainPtr<WKURLRef> url = adoptWK(Util::createURLForResource("simple", "html")); + WKPageLoadURL(webView.page(), url.get()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get())); + Util::run(&done); + done = false; + + WKPageReload(webView.page()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get())); + Util::run(&done); + done = false; + + WKRetainPtr<WKStringRef> htmlString = Util::toWK("<body>Hello, World</body>"); + WKRetainPtr<WKURLRef> blankURL = adoptWK(WKURLCreateWithUTF8CString("about:blank")); + WKPageLoadHTMLString(webView.page(), htmlString.get(), nullptr); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get())); + Util::run(&done); + done = false; + + WKPageReload(webView.page()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get())); + Util::run(&done); + done = false; + + url = adoptWK(Util::createURLForResource("simple2", "html")); + WKPageLoadHTMLString(webView.page(), htmlString.get(), url.get()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get())); + Util::run(&done); + done = false; + + WKPageReload(webView.page()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get())); + Util::run(&done); + done = false; + + WKRetainPtr<WKDataRef> data = adoptWK(WKDataCreate(nullptr, 0)); + WKPageLoadData(webView.page(), data.get(), nullptr, nullptr, nullptr); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get())); + Util::run(&done); + done = false; + + WKPageReload(webView.page()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get())); + Util::run(&done); + done = false; + + WKPageLoadData(webView.page(), data.get(), nullptr, nullptr, url.get()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get())); + Util::run(&done); + done = false; + + WKPageReload(webView.page()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get())); + Util::run(&done); + done = false; + + WKPageLoadAlternateHTMLString(webView.page(), htmlString.get(), nullptr, url.get()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get())); + Util::run(&done); + done = false; + + WKPageReload(webView.page()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get())); + Util::run(&done); + done = false; + + WKRetainPtr<WKStringRef> plainTextString = Util::toWK("Hello, World"); + WKPageLoadPlainTextString(webView.page(), plainTextString.get()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get())); + Util::run(&done); + done = false; + + WKPageReload(webView.page()); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get())); + Util::run(&done); + done = false; + + url = adoptWK(WKURLCreateWithUTF8CString("file:///tmp/index.html")); + WKPageLoadFile(webView.page(), url.get(), nullptr); + activeURL = adoptWK(WKPageCopyActiveURL(webView.page())); + ASSERT_NOT_NULL(activeURL.get()); + EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get())); + WKPageStopLoading(webView.page()); +} + +} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/PreventEmptyUserAgent.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/PreventEmptyUserAgent.cpp index c5acb6172..7712b142c 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/PreventEmptyUserAgent.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/PreventEmptyUserAgent.cpp @@ -24,12 +24,15 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" #include <JavaScriptCore/JSContextRef.h> -#include <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKSerializedScriptValue.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKSerializedScriptValue.h> namespace TestWebKitAPI { @@ -68,3 +71,5 @@ TEST(WebKit2, PreventEmptyUserAgent) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/PrivateBrowsingPushStateNoHistoryCallback.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/PrivateBrowsingPushStateNoHistoryCallback.cpp index 164466b2c..532c92373 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/PrivateBrowsingPushStateNoHistoryCallback.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/PrivateBrowsingPushStateNoHistoryCallback.cpp @@ -24,47 +24,56 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { -static bool testDone; +static bool didNavigate; +static bool didSameDocumentNavigation; -static void didNavigateWithNavigationData(WKContextRef context, WKPageRef page, WKNavigationDataRef navigationData, WKFrameRef frame, const void* clientInfo) +static void didNavigateWithoutNavigationData(WKContextRef context, WKPageRef page, WKNavigationDataRef navigationData, WKFrameRef frame, const void* clientInfo) { // This should never be called when navigating in Private Browsing. FAIL(); } +static void didNavigateWithNavigationData(WKContextRef context, WKPageRef page, WKNavigationDataRef navigationData, WKFrameRef frame, const void* clientInfo) +{ + didNavigate = true; +} + static void didSameDocumentNavigationForFrame(WKPageRef page, WKFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef userData, const void *clientInfo) { - testDone = true; + didSameDocumentNavigation = true; } TEST(WebKit2, PrivateBrowsingPushStateNoHistoryCallback) { WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - WKContextHistoryClient historyClient; + WKContextHistoryClientV0 historyClient; memset(&historyClient, 0, sizeof(historyClient)); - historyClient.version = 0; - historyClient.clientInfo = 0; - historyClient.didNavigateWithNavigationData = didNavigateWithNavigationData; - WKContextSetHistoryClient(context.get(), &historyClient); + historyClient.base.version = 0; + historyClient.didNavigateWithNavigationData = didNavigateWithoutNavigationData; + + WKContextSetHistoryClient(context.get(), &historyClient.base); PlatformWebView webView(context.get()); - WKPageLoaderClient pageLoaderClient; + WKPageLoaderClientV0 pageLoaderClient; memset(&pageLoaderClient, 0, sizeof(pageLoaderClient)); - pageLoaderClient.version = 0; - pageLoaderClient.clientInfo = 0; + pageLoaderClient.base.version = 0; pageLoaderClient.didSameDocumentNavigationForFrame = didSameDocumentNavigationForFrame; - WKPageSetPageLoaderClient(webView.page(), &pageLoaderClient); + + WKPageSetPageLoaderClient(webView.page(), &pageLoaderClient.base); WKRetainPtr<WKPreferencesRef> preferences(AdoptWK, WKPreferencesCreate()); WKPreferencesSetPrivateBrowsingEnabled(preferences.get(), true); @@ -75,7 +84,18 @@ TEST(WebKit2, PrivateBrowsingPushStateNoHistoryCallback) WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("push-state", "html")); WKPageLoadURL(webView.page(), url.get()); - Util::run(&testDone); + Util::run(&didSameDocumentNavigation); + + WKPreferencesSetPrivateBrowsingEnabled(preferences.get(), false); + + historyClient.didNavigateWithNavigationData = didNavigateWithNavigationData; + WKContextSetHistoryClient(context.get(), &historyClient.base); + + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&didNavigate); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ReloadPageAfterCrash.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ReloadPageAfterCrash.cpp index 7960dcbf1..190c85341 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ReloadPageAfterCrash.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ReloadPageAfterCrash.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -65,11 +68,14 @@ TEST(WebKit2, ReloadPageAfterCrash) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoad; loaderClient.processDidCrash = didCrash; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url = adoptWK(WKURLCreateWithUTF8CString("about:blank")); // Load a blank page and next kills WebProcess. @@ -83,3 +89,5 @@ TEST(WebKit2, ReloadPageAfterCrash) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ResizeReversePaginatedWebView.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ResizeReversePaginatedWebView.cpp index f032849ba..f2e1ae17f 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ResizeReversePaginatedWebView.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ResizeReversePaginatedWebView.cpp @@ -24,14 +24,17 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "JavaScriptTest.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" #include <JavaScriptCore/JSContextRef.h> -#include <WebKit2/WKContextPrivate.h> -#include <WebKit2/WKPagePrivate.h> -#include <WebKit2/WKSerializedScriptValue.h> +#include <WebKit/WKContextPrivate.h> +#include <WebKit/WKPagePrivate.h> +#include <WebKit/WKSerializedScriptValue.h> namespace TestWebKitAPI { @@ -61,13 +64,14 @@ TEST(WebKit2, ResizeReversePaginatedWebView) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV3 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = kWKPageLoaderClientCurrentVersion; + + loaderClient.base.version = 3; + loaderClient.base.clientInfo = &webView; loaderClient.didLayout = didLayout; - loaderClient.clientInfo = &webView; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKPageListenForLayoutMilestones(webView.page(), kWKDidFirstLayoutAfterSuppressedIncrementalRendering); @@ -87,3 +91,5 @@ TEST(WebKit2, ResizeReversePaginatedWebView) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ResizeWindowAfterCrash.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ResizeWindowAfterCrash.cpp index 1af639de7..2dfc8b4c2 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ResizeWindowAfterCrash.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ResizeWindowAfterCrash.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -75,12 +78,15 @@ TEST(WebKit2, ResizeWindowAfterCrash) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); TestStatesData states(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.clientInfo = &states; + + loaderClient.base.version = 0; + loaderClient.base.clientInfo = &states; loaderClient.didFinishLoadForFrame = didFinishLoad; loaderClient.processDidCrash = didCrash; - WKPageSetPageLoaderClient(states.webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(states.webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url = adoptWK(WKURLCreateWithUTF8CString("about:blank")); // Load a blank page and next kills WebProcess. @@ -94,3 +100,5 @@ TEST(WebKit2, ResizeWindowAfterCrash) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly.cpp index 10f04c180..a034637e3 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" @@ -51,25 +54,25 @@ static void processDidBecomeUnresponsive(WKPageRef, const void*) static void setInjectedBundleClient(WKContextRef context) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = 0; - injectedBundleClient.clientInfo = 0; + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.clientInfo = 0; + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; loaderClient.processDidBecomeUnresponsive = processDidBecomeUnresponsive; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } TEST(WebKit2, ResponsivenessTimerDoesntFireEarly) @@ -96,3 +99,5 @@ TEST(WebKit2, ResponsivenessTimerDoesntFireEarly) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly_Bundle.cpp index 50d664f38..ddd2ca158 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ResponsivenessTimerDoesntFireEarly_Bundle.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" @@ -57,3 +60,5 @@ void ResponsivenessTimerDoesntFireEarlyTest::didReceiveMessage(WKBundleRef bundl } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/RestoreSessionStateContainingFormData.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/RestoreSessionStateContainingFormData.cpp index f75de124e..b16537e70 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/RestoreSessionStateContainingFormData.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/RestoreSessionStateContainingFormData.cpp @@ -24,10 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "JavaScriptTest.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" +#include <WebKit/WKSessionStateRef.h> namespace TestWebKitAPI { @@ -40,15 +44,16 @@ static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } -static WKRetainPtr<WKDataRef> createSessionStateContainingFormData(WKContextRef context) +static WKRetainPtr<WKDataRef> createSessionStateDataContainingFormData(WKContextRef context) { PlatformWebView webView(context); setPageLoaderClient(webView.page()); @@ -61,7 +66,8 @@ static WKRetainPtr<WKDataRef> createSessionStateContainingFormData(WKContextRef Util::run(&didFinishLoad); didFinishLoad = false; - return adoptWK(WKPageCopySessionState(webView.page(), 0, 0)); + auto sessionState = adoptWK(static_cast<WKSessionStateRef>(WKPageCopySessionState(webView.page(), reinterpret_cast<void*>(1), nullptr))); + return adoptWK(WKSessionStateCopyData(sessionState.get())); } TEST(WebKit2, RestoreSessionStateContainingFormData) @@ -74,13 +80,17 @@ TEST(WebKit2, RestoreSessionStateContainingFormData) PlatformWebView webView(context.get()); setPageLoaderClient(webView.page()); - WKRetainPtr<WKDataRef> data = createSessionStateContainingFormData(context.get()); + WKRetainPtr<WKDataRef> data = createSessionStateDataContainingFormData(context.get()); EXPECT_NOT_NULL(data); - WKPageRestoreFromSessionState(webView.page(), data.get()); + auto sessionState = adoptWK(WKSessionStateCreateFromData(data.get())); + WKPageRestoreFromSessionState(webView.page(), sessionState.get()); + Util::run(&didFinishLoad); EXPECT_TRUE(WKPageCanGoBack(webView.page())); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ScrollPinningBehaviors.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ScrollPinningBehaviors.cpp index 695e912df..015571f5f 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ScrollPinningBehaviors.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ScrollPinningBehaviors.cpp @@ -24,14 +24,18 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "JavaScriptTest.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" #include <JavaScriptCore/JSContextRef.h> -#include <WebKit2/WKContextPrivate.h> -#include <WebKit2/WKPagePrivate.h> -#include <WebKit2/WKSerializedScriptValue.h> +#include <WebKit/WKContextPrivate.h> +#include <WebKit/WKPagePrivate.h> +#include <WebKit/WKPreferencesRefPrivate.h> +#include <WebKit/WKSerializedScriptValue.h> namespace TestWebKitAPI { @@ -68,15 +72,24 @@ static void didFinishDocumentLoadForFrame(WKPageRef page, WKFrameRef frame, WKTy TEST(WebKit2, ScrollPinningBehaviors) { WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + // Turn off threaded scrolling; synchronously waiting for the main thread scroll position to + // update using WKPageForceRepaint would be better, but for some reason doesn't block until + // it's updated after the initial WKPageSetScrollPinningBehavior above. + WKRetainPtr<WKPageGroupRef> pageGroup(AdoptWK, WKPageGroupCreateWithIdentifier(Util::toWK("NoThreadedScrollingPageGroup").get())); + WKPreferencesRef preferences = WKPageGroupGetPreferences(pageGroup.get()); + WKPreferencesSetThreadedScrollingEnabled(preferences, false); + + PlatformWebView webView(context.get(), pageGroup.get()); + + WKPageLoaderClientV3 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = kWKPageLoaderClientCurrentVersion; + + loaderClient.base.version = 3; + loaderClient.base.clientInfo = &webView; loaderClient.didFinishDocumentLoadForFrame = didFinishDocumentLoadForFrame; - loaderClient.clientInfo = &webView; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple-tall", "html")).get()); @@ -85,3 +98,5 @@ TEST(WebKit2, ScrollPinningBehaviors) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/SeccompFilters.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/SeccompFilters.cpp index c666bf687..9ca6080d3 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/SeccompFilters.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/SeccompFilters.cpp @@ -25,9 +25,9 @@ #include "config.h" -#include <WebKit2/SeccompBroker.h> -#include <WebKit2/SeccompFilters.h> -#include <WebKit2/SyscallPolicy.h> +#include <WebKit/SeccompBroker.h> +#include <WebKit/SeccompFilters.h> +#include <WebKit/SyscallPolicy.h> #include <errno.h> #include <fcntl.h> #include <pthread.h> @@ -42,16 +42,16 @@ using namespace WebKit; namespace TestWebKitAPI { -DEFINE_STATIC_LOCAL(String, rootDir, (ASCIILiteral("/"))); -DEFINE_STATIC_LOCAL(String, homeDir, (String(getenv("HOME")))); -DEFINE_STATIC_LOCAL(String, usrDir, (ASCIILiteral("/usr"))); -DEFINE_STATIC_LOCAL(String, usrSbinDir, (ASCIILiteral("/usr/sbin"))); -DEFINE_STATIC_LOCAL(String, testDirRead, (ASCIILiteral("/tmp/WebKitSeccompFilters/testRead"))); -DEFINE_STATIC_LOCAL(String, testDirWrite, (ASCIILiteral("/tmp/WebKitSeccompFilters/testWrite"))); -DEFINE_STATIC_LOCAL(String, testDirReadAndWrite, (ASCIILiteral("/tmp/WebKitSeccompFilters/testReadAndWrite"))); -DEFINE_STATIC_LOCAL(String, testDirNotAllowed, (ASCIILiteral("/tmp/WebKitSeccompFilters/testNotAllowed"))); -DEFINE_STATIC_LOCAL(String, testFileNotAllowed, (testDirReadAndWrite + "/testFilePolicy")); -DEFINE_STATIC_LOCAL(String, testFileReadAndWrite, (testDirNotAllowed + "/testFilePolicy")); +DEPRECATED_DEFINE_STATIC_LOCAL(String, rootDir, (ASCIILiteral("/"))); +DEPRECATED_DEFINE_STATIC_LOCAL(String, homeDir, (String(getenv("HOME")))); +DEPRECATED_DEFINE_STATIC_LOCAL(String, usrDir, (ASCIILiteral("/usr"))); +DEPRECATED_DEFINE_STATIC_LOCAL(String, usrSbinDir, (ASCIILiteral("/usr/sbin"))); +DEPRECATED_DEFINE_STATIC_LOCAL(String, testDirRead, (ASCIILiteral("/tmp/WebKitSeccompFilters/testRead"))); +DEPRECATED_DEFINE_STATIC_LOCAL(String, testDirWrite, (ASCIILiteral("/tmp/WebKitSeccompFilters/testWrite"))); +DEPRECATED_DEFINE_STATIC_LOCAL(String, testDirReadAndWrite, (ASCIILiteral("/tmp/WebKitSeccompFilters/testReadAndWrite"))); +DEPRECATED_DEFINE_STATIC_LOCAL(String, testDirNotAllowed, (ASCIILiteral("/tmp/WebKitSeccompFilters/testNotAllowed"))); +DEPRECATED_DEFINE_STATIC_LOCAL(String, testFileNotAllowed, (testDirReadAndWrite + "/testFilePolicy")); +DEPRECATED_DEFINE_STATIC_LOCAL(String, testFileReadAndWrite, (testDirNotAllowed + "/testFilePolicy")); static const mode_t defaultMode = S_IRUSR | S_IWUSR | S_IXUSR; diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem.cpp index c6f3b1bac..f41e44a5e 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" -#include <WebKit2/WKString.h> +#include <WebKit/WKString.h> namespace TestWebKitAPI { @@ -56,14 +59,14 @@ static void willGoToBackForwardListItem(WKPageRef, WKBackForwardListItemRef, WKT static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV1 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 1; - loaderClient.clientInfo = 0; + + loaderClient.base.version = 1; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; loaderClient.willGoToBackForwardListItem = willGoToBackForwardListItem; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } TEST(WebKit2, ShouldGoToBackForwardListItem) @@ -90,3 +93,5 @@ TEST(WebKit2, ShouldGoToBackForwardListItem) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem_Bundle.cpp index 0f15c477c..5eba75a9e 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ShouldGoToBackForwardListItem_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundleBackForwardListItem.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundleBackForwardListItem.h> namespace TestWebKitAPI { @@ -57,14 +60,16 @@ ShouldGoToBackForwardListItemTest::ShouldGoToBackForwardListItemTest(const std:: void ShouldGoToBackForwardListItemTest::didCreatePage(WKBundleRef bundle, WKBundlePageRef page) { - WKBundlePageLoaderClient pageLoaderClient; + WKBundlePageLoaderClientV1 pageLoaderClient; memset(&pageLoaderClient, 0, sizeof(pageLoaderClient)); - pageLoaderClient.version = 1; - pageLoaderClient.clientInfo = this; + pageLoaderClient.base.version = 1; + pageLoaderClient.base.clientInfo = this; pageLoaderClient.shouldGoToBackForwardListItem = shouldGoToBackForwardListItemCallback; - WKBundlePageSetPageLoaderClient(page, &pageLoaderClient); + WKBundlePageSetPageLoaderClient(page, &pageLoaderClient.base); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/ShouldKeepCurrentBackForwardListItemInList.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/ShouldKeepCurrentBackForwardListItemInList.cpp new file mode 100644 index 000000000..f8098e6f1 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/ShouldKeepCurrentBackForwardListItemInList.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2014 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" + +#if WK_HAVE_C_SPI + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" + +// This test navigates from simple.html, to simple2.html, to simple3.html +// When navigating from simple2 to simple3, it disallows the simple2 back/forward list item from staying in the list +// It then navigates back from simple3, expecting to land at simple. + +namespace TestWebKitAPI { + +static bool finished = false; +static bool successfulSoFar = true; +static int navigationNumber = 0; + +static bool itemURLLastComponentIsString(WKBackForwardListItemRef item, const char* string) +{ + WKRetainPtr<WKURLRef> url = adoptWK(WKBackForwardListItemCopyURL(item)); + WKRetainPtr<WKStringRef> path = adoptWK(WKURLCopyLastPathComponent(url.get())); + + return WKStringIsEqualToUTF8CString(path.get(), string); +} + +static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef, const void*) +{ + // Only mark finished when the main frame loads + if (!WKFrameIsMainFrame(frame)) + return; + + finished = true; + navigationNumber++; + + WKBackForwardListRef list = WKPageGetBackForwardList(page); + WKBackForwardListItemRef currentItem = WKBackForwardListGetCurrentItem(list); + WKBackForwardListItemRef backItem = WKBackForwardListGetBackItem(list); + WKBackForwardListItemRef forwardItem = WKBackForwardListGetForwardItem(list); + unsigned forwardCount = WKBackForwardListGetForwardListCount(list); + + // This test should never have a forward list. + if (forwardCount) + successfulSoFar = false; + + if (navigationNumber == 1) { + // We've only performed 1 navigation, we should only have a current item. + if (!currentItem || !itemURLLastComponentIsString(currentItem, "simple.html")) + successfulSoFar = false; + if (backItem || forwardItem) + successfulSoFar = false; + } else if (navigationNumber == 2) { + // On the second navigation, simple2 should be current and simple should be the back item. + if (!currentItem || !itemURLLastComponentIsString(currentItem, "simple2.html")) + successfulSoFar = false; + if (!backItem || !itemURLLastComponentIsString(backItem, "simple.html")) + successfulSoFar = false; + if (forwardItem) + successfulSoFar = false; + } else if (navigationNumber == 3) { + // On the third navigation the item for simple2 should have been removed. + // So simple3 should be current and simple should still be the back item. + if (!currentItem || !itemURLLastComponentIsString(currentItem, "simple3.html")) + successfulSoFar = false; + if (!backItem || !itemURLLastComponentIsString(backItem, "simple.html")) + successfulSoFar = false; + if (forwardItem) + successfulSoFar = false; + } else if (navigationNumber == 4) { + // After the fourth navigation (which was a "back" navigation), the item for simple3 should have been removed. + // So simple should be current and there should be no other items. + if (!currentItem || !itemURLLastComponentIsString(currentItem, "simple.html")) + successfulSoFar = false; + if (backItem || forwardItem) + successfulSoFar = false; + } +} + +static void willGoToBackForwardListItem(WKPageRef, WKBackForwardListItemRef item, WKTypeRef userData, const void*) +{ + if (!itemURLLastComponentIsString(item, "simple.html")) + successfulSoFar = false; +} + +static bool shouldKeepCurrentBackForwardListItemInList(WKPageRef page, WKBackForwardListItemRef item, const void*) +{ + // We make sure the item for "simple2.html" is removed when we navigate to "simple3.html" + // We also want to make sure the item for "simple3.html" is removed when we go back to "simple.html" + // So we only want to keep "simple.html" + return itemURLLastComponentIsString(item, "simple.html"); +} + +static void setPageLoaderClient(WKPageRef page) +{ + WKPageLoaderClientV5 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 5; + loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + loaderClient.shouldKeepCurrentBackForwardListItemInList = shouldKeepCurrentBackForwardListItemInList; + loaderClient.willGoToBackForwardListItem = willGoToBackForwardListItem; + + WKPageSetPageLoaderClient(page, &loaderClient.base); +} + +TEST(WebKit2, ShouldKeepCurrentBackForwardListItemInList) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + + PlatformWebView webView(context.get()); + setPageLoaderClient(webView.page()); + + WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple", "html")).get()); + Util::run(&finished); + EXPECT_EQ(successfulSoFar, true); + + finished = false; + WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple2", "html")).get()); + Util::run(&finished); + EXPECT_EQ(successfulSoFar, true); + + finished = false; + WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple3", "html")).get()); + Util::run(&finished); + EXPECT_EQ(successfulSoFar, true); + + finished = false; + WKPageGoBack(webView.page()); + Util::run(&finished); + + EXPECT_EQ(successfulSoFar, true); + EXPECT_EQ(navigationNumber, 4); +} + +} // namespace TestWebKitAPI + + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp index d6a787061..226f52cc2 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/SpacebarScrolling.cpp @@ -24,10 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "JavaScriptTest.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKPreferencesPrivate.h> namespace TestWebKitAPI { @@ -48,20 +52,30 @@ static void didNotHandleKeyEventCallback(WKPageRef, WKNativeEventPtr event, cons TEST(WebKit2, SpacebarScrolling) { WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextWithInjectedBundle()); - PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + // Turn off threaded scrolling; synchronously waiting for the main thread scroll position to + // update using WKPageForceRepaint would be better, but for some reason the test still fails occasionally. + WKRetainPtr<WKPageGroupRef> pageGroup(AdoptWK, WKPageGroupCreateWithIdentifier(Util::toWK("NoThreadedScrollingPageGroup").get())); + WKPreferencesRef preferences = WKPageGroupGetPreferences(pageGroup.get()); + WKPreferencesSetThreadedScrollingEnabled(preferences, false); + + PlatformWebView webView(context.get(), pageGroup.get()); + + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - - loaderClient.version = 0; + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); - WKPageUIClient uiClient; + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); + + WKPageUIClientV0 uiClient; memset(&uiClient, 0, sizeof(uiClient)); + uiClient.base.version = 0; uiClient.didNotHandleKeyEvent = didNotHandleKeyEventCallback; - WKPageSetPageUIClient(webView.page(), &uiClient); + + WKPageSetPageUIClient(webView.page(), &uiClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("spacebar-scrolling", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -75,13 +89,11 @@ TEST(WebKit2, SpacebarScrolling) EXPECT_JS_FALSE(webView.page(), "isDocumentScrolled()"); EXPECT_JS_TRUE(webView.page(), "textFieldContainsSpace()"); - // On Mac, a key down event represents both a raw key down and a key press. On Windows, a key - // down event only represents a raw key down. We expect the key press to be handled (because it - // inserts text into the text field). But the raw key down should not be handled. -#if PLATFORM(MAC) + // On Mac, a key down event represents both a raw key down and a key press. + // We expect the key press to be handled (because it inserts text into the text field), + // but the raw key down should not be handled. +#if PLATFORM(COCOA) EXPECT_FALSE(didNotHandleKeyDownEvent); -#elif PLATFORM(WIN) - EXPECT_TRUE(didNotHandleKeyDownEvent); #endif EXPECT_JS_EQ(webView.page(), "blurTextField()", "undefined"); @@ -89,18 +101,14 @@ 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) +#if PLATFORM(COCOA) EXPECT_FALSE(didNotHandleKeyDownEvent); -#elif PLATFORM(WIN) - EXPECT_TRUE(didNotHandleKeyDownEvent); #endif } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/PasteboardNotifications.mm b/Tools/TestWebKitAPI/Tests/WebKit2/StopLoadingDuringDidFailProvisionalLoad.cpp index 6635fae9e..386dfd303 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/PasteboardNotifications.mm +++ b/Tools/TestWebKitAPI/Tests/WebKit2/StopLoadingDuringDidFailProvisionalLoad.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,53 +24,60 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" - -#include <WebKit2/WKString.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { -static bool finished = false; +static bool done; +static bool receivedMessageFromBundle; static void didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo) { - if (WKStringIsEqualToUTF8CString(messageName, "PasteboardNotificationTestDoneMessageName") - && WKStringIsEqualToUTF8CString(static_cast<WKStringRef>(messageBody), "didWriteToPasteboard")) { - NSData* data = [[NSPasteboard generalPasteboard] dataForType:@"AnotherArchivePasteboardType"]; - EXPECT_NE(data, (NSData*)nil); - finished = true; - } + if (WKStringIsEqualToUTF8CString(messageName, "StopLoadingDuringDidFailProvisionalLoadTestDone")) + receivedMessageFromBundle = true; } static void setInjectedBundleClient(WKContextRef context) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = 0; - injectedBundleClient.clientInfo = 0; + injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } -TEST(WebKit2, PasteboardNotifications) +static void didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef, WKErrorRef, WKTypeRef, const void*) { - [[NSPasteboard generalPasteboard] clearContents]; - - WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("PasteboardNotificationsTest")); + // The injected bundle is notified of the failed load first. If we also receive this callback, the test didn't crash. + EXPECT_TRUE(receivedMessageFromBundle); + done = true; +} + +TEST(WebKit2, StopLoadingDuringDidFailProvisionalLoadTest) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextForInjectedBundleTest("StopLoadingDuringDidFailProvisionalLoadTest")); setInjectedBundleClient(context.get()); PlatformWebView webView(context.get()); - WKRetainPtr<WKPreferencesRef> preferences(AdoptWK, WKPreferencesCreate()); - WKPreferencesSetJavaScriptCanAccessClipboard(preferences.get(), true); + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + loaderClient.didFailProvisionalLoadWithErrorForFrame = didFailProvisionalLoadWithErrorForFrame; + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); - WKPageGroupRef pageGroup = WKPageGetPageGroup(webView.page()); - WKPageGroupSetPreferences(pageGroup, preferences.get()); + WKRetainPtr<WKURLRef> url(AdoptWK, Util::URLForNonExistentResource()); + WKPageLoadURL(webView.page(), url.get()); - WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("execCopy", "html")).get()); - Util::run(&finished); + Util::run(&done); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/StopLoadingDuringDidFailProvisionalLoad_bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/StopLoadingDuringDidFailProvisionalLoad_bundle.cpp new file mode 100644 index 000000000..56105522b --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/StopLoadingDuringDidFailProvisionalLoad_bundle.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 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" + +#if WK_HAVE_C_SPI + +#include "InjectedBundleTest.h" +#include "PlatformUtilities.h" +#include <WebKit/WKBundle.h> +#include <WebKit/WKBundleFramePrivate.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundlePagePrivate.h> + +namespace TestWebKitAPI { + +class StopLoadingDuringDidFailProvisionalLoadTest : public InjectedBundleTest { +public: + StopLoadingDuringDidFailProvisionalLoadTest(const std::string& identifier) + : InjectedBundleTest(identifier) + { + } + + virtual void didCreatePage(WKBundleRef, WKBundlePageRef) override; + void didFailProvisionalLoad(WKBundlePageRef, WKBundleFrameRef); + + WKBundleRef m_bundle; +}; + +static InjectedBundleTest::Register<StopLoadingDuringDidFailProvisionalLoadTest> registrar("StopLoadingDuringDidFailProvisionalLoadTest"); + +static void didFailProvisionalLoadWithErrorForFrameCallback(WKBundlePageRef page, WKBundleFrameRef frame, WKErrorRef, WKTypeRef*, const void *clientInfo) +{ + ((StopLoadingDuringDidFailProvisionalLoadTest*)clientInfo)->didFailProvisionalLoad(page, frame); +} + +void StopLoadingDuringDidFailProvisionalLoadTest::didCreatePage(WKBundleRef bundle, WKBundlePageRef page) +{ + m_bundle = bundle; + + WKBundlePageLoaderClientV2 pageLoaderClient; + memset(&pageLoaderClient, 0, sizeof(pageLoaderClient)); + + pageLoaderClient.base.version = 2; + pageLoaderClient.base.clientInfo = this; + pageLoaderClient.didFailProvisionalLoadWithErrorForFrame = didFailProvisionalLoadWithErrorForFrameCallback; + + WKBundlePageSetPageLoaderClient(page, &pageLoaderClient.base); +} + +void StopLoadingDuringDidFailProvisionalLoadTest::didFailProvisionalLoad(WKBundlePageRef page, WKBundleFrameRef) +{ + WKBundlePageStopLoading(page); + WKBundlePostMessage(m_bundle, Util::toWK("StopLoadingDuringDidFailProvisionalLoadTestDone").get(), nullptr); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/TerminateTwice.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/TerminateTwice.cpp index 780ce522f..2e1950860 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/TerminateTwice.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/TerminateTwice.cpp @@ -24,11 +24,17 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" namespace TestWebKitAPI { +// Disabled in debug mode while investigating <https://bugs.webkit.org/show_bug.cgi?id=136012>. +#ifdef NDEBUG + static bool loaded; static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) @@ -41,12 +47,13 @@ TEST(WebKit2, TerminateTwice) WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); WKPageLoadURL(webView.page(), url.get()); @@ -61,5 +68,8 @@ TEST(WebKit2, TerminateTwice) WKPageTerminate(webView.page()); } +#endif + } // namespace TestWebKitAPI +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/TextFieldDidBeginAndEndEditing.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/TextFieldDidBeginAndEndEditing.cpp new file mode 100644 index 000000000..cfe0be254 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/TextFieldDidBeginAndEndEditing.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2015 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" + +#if WK_HAVE_C_SPI && !PLATFORM(MAC) + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" +#include <wtf/StdLibExtras.h> + +namespace TestWebKitAPI { + +struct WebKit2TextFieldBeginAndEditEditingTest : public ::testing::Test { + std::unique_ptr<PlatformWebView> webView; + + WKRetainPtr<WKStringRef> messageName; + + bool didFinishLoad { false }; + bool didReceiveMessage { false }; + + static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef, const void* clientInfo) + { + WebKit2TextFieldBeginAndEditEditingTest& client = *static_cast<WebKit2TextFieldBeginAndEditEditingTest*>(const_cast<void*>(clientInfo)); + client.messageName = messageName; + client.didReceiveMessage = true; + } + + static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void* clientInfo) + { + WebKit2TextFieldBeginAndEditEditingTest& client = *static_cast<WebKit2TextFieldBeginAndEditEditingTest*>(const_cast<void*>(clientInfo)); + client.didFinishLoad = true; + } + + static void setInjectedBundleClient(WKContextRef context, const void* clientInfo) + { + WKContextInjectedBundleClientV1 injectedBundleClient; + memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); + + injectedBundleClient.base.version = 1; + injectedBundleClient.base.clientInfo = clientInfo; + injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; + + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); + } + + static void setPageLoaderClient(WKPageRef page, const void* clientInfo) + { + WKPageLoaderClientV6 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 6; + loaderClient.base.clientInfo = clientInfo; + loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + + WKPageSetPageLoaderClient(page, &loaderClient.base); + } + + static void nullJavaScriptCallback(WKSerializedScriptValueRef, WKErrorRef, void*) + { + } + + void executeJavaScriptAndCheckDidReceiveMessage(const char* javaScriptCode, const char* expectedMessageName) + { + didReceiveMessage = false; + WKPageRunJavaScriptInMainFrame(webView->page(), Util::toWK(javaScriptCode).get(), 0, nullJavaScriptCallback); + Util::run(&didReceiveMessage); + EXPECT_WK_STREQ(expectedMessageName, messageName); + } + + // From ::testing::Test + void SetUp() override + { + WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("TextFieldDidBeginAndEndEditingEventsTest")); + setInjectedBundleClient(context.get(), this); + + webView = std::make_unique<PlatformWebView>(context.get()); + setPageLoaderClient(webView->page(), this); + + didFinishLoad = false; + didReceiveMessage = false; + + WKPageLoadURL(webView->page(), adoptWK(Util::createURLForResource("input-focus-blur", "html")).get()); + Util::run(&didFinishLoad); + } +}; + +TEST_F(WebKit2TextFieldBeginAndEditEditingTest, TextFieldDidBeginAndEndEditingEvents) +{ + executeJavaScriptAndCheckDidReceiveMessage("focusTextField('input')", "DidReceiveTextFieldDidBeginEditing"); + executeJavaScriptAndCheckDidReceiveMessage("blurTextField('input')", "DidReceiveTextFieldDidEndEditing"); +} + +TEST_F(WebKit2TextFieldBeginAndEditEditingTest, TextFieldDidBeginAndEndEditingEventsInReadOnlyField) +{ + executeJavaScriptAndCheckDidReceiveMessage("focusTextField('readonly')", "DidReceiveTextFieldDidBeginEditing"); + executeJavaScriptAndCheckDidReceiveMessage("blurTextField('readonly')", "DidReceiveTextFieldDidEndEditing"); +} + +TEST_F(WebKit2TextFieldBeginAndEditEditingTest, TextFieldDidBeginShouldNotBeDispatchedForAlreadyFocusedField) +{ + executeJavaScriptAndCheckDidReceiveMessage("focusTextField('input'); focusTextField('input')", "DidReceiveTextFieldDidBeginEditing"); + executeJavaScriptAndCheckDidReceiveMessage("blurTextField('input')", "DidReceiveTextFieldDidEndEditing"); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/TextFieldDidBeginAndEndEditing_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/TextFieldDidBeginAndEndEditing_Bundle.cpp new file mode 100644 index 000000000..19898f703 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/TextFieldDidBeginAndEndEditing_Bundle.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015 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" + +#if WK_HAVE_C_SPI && !PLATFORM(MAC) + +#include "InjectedBundleTest.h" + +#include "PlatformUtilities.h" +#include <WebKit/WKBundlePage.h> + +namespace TestWebKitAPI { + +class TextFieldDidBeginAndEndEditingEventsTest : public InjectedBundleTest { +public: + TextFieldDidBeginAndEndEditingEventsTest(const std::string& identifier); + + virtual void didCreatePage(WKBundleRef, WKBundlePageRef); +}; + +static InjectedBundleTest::Register<TextFieldDidBeginAndEndEditingEventsTest> registrar("TextFieldDidBeginAndEndEditingEventsTest"); + +static void textFieldDidBeginEditing(WKBundlePageRef, WKBundleNodeHandleRef inputElement, WKBundleFrameRef, const void*) +{ + WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("DidReceiveTextFieldDidBeginEditing").get(), nullptr); +} + +static void textFieldDidEndEditing(WKBundlePageRef, WKBundleNodeHandleRef inputElement, WKBundleFrameRef, const void*) +{ + WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("DidReceiveTextFieldDidEndEditing").get(), nullptr); +} + +TextFieldDidBeginAndEndEditingEventsTest::TextFieldDidBeginAndEndEditingEventsTest(const std::string& identifier) + : InjectedBundleTest(identifier) +{ +} + +void TextFieldDidBeginAndEndEditingEventsTest::didCreatePage(WKBundleRef bundle, WKBundlePageRef page) +{ + WKBundlePageFormClientV2 formClient; + memset(&formClient, 0, sizeof(formClient)); + + formClient.base.version = 2; + formClient.base.clientInfo = this; + formClient.textFieldDidBeginEditing = textFieldDidBeginEditing; + formClient.textFieldDidEndEditing = textFieldDidEndEditing; + + WKBundlePageSetFormClient(page, &formClient.base); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/UserMedia.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/UserMedia.cpp new file mode 100644 index 000000000..24dd943de --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/UserMedia.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#if WK_HAVE_C_SPI + +#if ENABLE(MEDIA_STREAM) +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" +#include <WebKit/WKRetainPtr.h> +#include <string.h> +#include <vector> + +namespace TestWebKitAPI { + +static bool done; + +void decidePolicyForUserMediaPermissionRequestCallBack(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKUserMediaPermissionRequestRef permissionRequest, const void* /* clientInfo */) +{ + WKRetainPtr<WKArrayRef> audioDeviceUIDs = WKUserMediaPermissionRequestAudioDeviceUIDs(permissionRequest); + WKRetainPtr<WKArrayRef> videoDeviceUIDs = WKUserMediaPermissionRequestVideoDeviceUIDs(permissionRequest); + + if (WKArrayGetSize(videoDeviceUIDs.get()) || WKArrayGetSize(audioDeviceUIDs.get())) { + WKRetainPtr<WKStringRef> videoDeviceUID; + if (WKArrayGetSize(videoDeviceUIDs.get())) + videoDeviceUID = reinterpret_cast<WKStringRef>(WKArrayGetItemAtIndex(videoDeviceUIDs.get(), 0)); + else + videoDeviceUID = WKStringCreateWithUTF8CString(""); + + WKRetainPtr<WKStringRef> audioDeviceUID; + if (WKArrayGetSize(audioDeviceUIDs.get())) + audioDeviceUID = reinterpret_cast<WKStringRef>(WKArrayGetItemAtIndex(audioDeviceUIDs.get(), 0)); + else + audioDeviceUID = WKStringCreateWithUTF8CString(""); + + WKUserMediaPermissionRequestAllow(permissionRequest, videoDeviceUID.get(), audioDeviceUID.get()); + } + + done = true; +} + +TEST(WebKit2, UserMediaBasic) +{ + auto context = adoptWK(WKContextCreate()); + PlatformWebView webView(context.get()); + WKPageUIClientV5 uiClient; + memset(&uiClient, 0, sizeof(uiClient)); + + + uiClient.base.version = 5; + uiClient.decidePolicyForUserMediaPermissionRequest = decidePolicyForUserMediaPermissionRequestCallBack; + + WKPageSetPageUIClient(webView.page(), &uiClient.base); + + done = false; + auto url = adoptWK(Util::createURLForResource("getUserMedia", "html")); + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&done); +} + +} // namespace TestWebKitAPI + +#endif // ENABLE(MEDIA_STREAM) + +#endif // WK_HAVE_C_SPI + diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/UserMessage.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/UserMessage.cpp index bc02dc878..064cbb838 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/UserMessage.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/UserMessage.cpp @@ -24,12 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "Test.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> namespace TestWebKitAPI { @@ -42,7 +43,7 @@ public: } WKRetainPtr<WKContextRef> context; - OwnPtr<PlatformWebView> webView; + std::unique_ptr<PlatformWebView> webView; WKRetainPtr<WKTypeRef> recievedBody; @@ -65,24 +66,26 @@ public: static void setInjectedBundleClient(WKContextRef context, const void* clientInfo) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV1 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = kWKContextInjectedBundleClientCurrentVersion; - injectedBundleClient.clientInfo = clientInfo; + + injectedBundleClient.base.version = 1; + injectedBundleClient.base.clientInfo = clientInfo; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } static void setPageLoaderClient(WKPageRef page, const void* clientInfo) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV3 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = kWKPageLoaderClientCurrentVersion; - loaderClient.clientInfo = clientInfo; + + loaderClient.base.version = 3; + loaderClient.base.clientInfo = clientInfo; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } virtual void SetUp() @@ -90,7 +93,7 @@ public: context = adoptWK(Util::createContextForInjectedBundleTest("UserMessageTest")); setInjectedBundleClient(context.get(), this); - webView = adoptPtr(new PlatformWebView(context.get())); + webView = std::make_unique<PlatformWebView>(context.get()); setPageLoaderClient(webView->page(), this); didFinishLoad = false; @@ -155,3 +158,5 @@ TEST_F(WebKit2UserMessageRoundTripTest, WKString) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/UserMessage_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/UserMessage_Bundle.cpp index 29ede3d83..cec713655 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/UserMessage_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/UserMessage_Bundle.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" @@ -50,3 +53,5 @@ private: static InjectedBundleTest::Register<UserMessageTest> registrar("UserMessageTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKBundleFileHandle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKBundleFileHandle.cpp new file mode 100644 index 000000000..b9a84ff80 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKBundleFileHandle.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2015 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" + +#if WK_HAVE_C_SPI + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" + +namespace TestWebKitAPI { + +static bool done; +static bool loadDone; + +static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef body, const void*) +{ + if (!WKStringIsEqualToUTF8CString(messageName, "SUCCESS")) + FAIL(); + else + SUCCEED(); + + done = true; +} + +static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void*) +{ + loadDone = true; +} + +TEST(WebKit2, WKBundleFileHandle) +{ + WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("WKBundleFileHandleTest")); + + WKContextInjectedBundleClientV0 injectedBundleClient; + memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); + injectedBundleClient.base.version = 0; + injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; + WKContextSetInjectedBundleClient(context.get(), &injectedBundleClient.base); + + PlatformWebView webView(context.get()); + + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + loaderClient.base.version = 0; + loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); + + WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("bundle-file", "html")).get()); + Util::run(&loadDone); + + // Get path to a file. + auto urlToFile = adoptWK(Util::createURLForResource("simple", "html")); + auto pathToFile = adoptWK(WKURLCopyPath(urlToFile.get())); + + WKContextPostMessageToInjectedBundle(context.get(), Util::toWK("TestFile").get(), pathToFile.get()); + + Util::run(&done); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKBundleFileHandle_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKBundleFileHandle_Bundle.cpp new file mode 100644 index 000000000..27d359ba6 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKBundleFileHandle_Bundle.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2015 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" + +#if WK_HAVE_C_SPI + +#include "InjectedBundleTest.h" + +#include "PlatformUtilities.h" +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundleFileHandleRef.h> +#include <WebKit/WKBundleFrame.h> +#include <WebKit/WKBundleScriptWorld.h> + +namespace TestWebKitAPI { + +static WKBundlePageRef loadedPage; + +class WKBundleFileHandleTest : public InjectedBundleTest { +public: + WKBundleFileHandleTest(const std::string& identifier) + : InjectedBundleTest(identifier) + { + } + +private: + virtual void didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody) override + { + if (!WKStringIsEqualToUTF8CString(messageName, "TestFile")) { + WKBundlePostMessage(bundle, Util::toWK("FAIL").get(), Util::toWK("Recieved invalid message").get()); + return; + } + + if (!loadedPage) { + WKBundlePostMessage(bundle, Util::toWK("FAIL").get(), Util::toWK("No loaded page").get()); + return; + } + + if (WKGetTypeID(messageBody) != WKStringGetTypeID()) { + WKBundlePostMessage(bundle, Util::toWK("FAIL").get(), Util::toWK("Message body has invalid type").get()); + return; + } + + WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(loadedPage); + WKBundleScriptWorldRef world = WKBundleScriptWorldNormalWorld(); + + JSGlobalContextRef globalContext = WKBundleFrameGetJavaScriptContextForWorld(mainFrame, world); + + auto fileHandle = adoptWK(WKBundleFileHandleCreateWithPath((WKStringRef)messageBody)); + JSValueRef jsFileHandle = WKBundleFrameGetJavaScriptWrapperForFileForWorld(mainFrame, fileHandle.get(), world); + + JSObjectRef globalObject = JSContextGetGlobalObject(globalContext); + + JSStringRef jsString = JSStringCreateWithUTF8CString("testFile"); + JSValueRef function = JSObjectGetProperty(globalContext, globalObject, jsString, nullptr); + JSStringRelease(jsString); + + JSValueRef result = JSObjectCallAsFunction(globalContext, (JSObjectRef)function, globalObject, 1, &jsFileHandle, nullptr); + + if (JSValueToBoolean(globalContext, result)) + WKBundlePostMessage(bundle, Util::toWK("SUCCESS").get(), nullptr); + else + WKBundlePostMessage(bundle, Util::toWK("FAIL").get(), Util::toWK("Script failed").get()); + } + + virtual void didCreatePage(WKBundleRef bundle, WKBundlePageRef page) override + { + loadedPage = page; + } +}; + +static InjectedBundleTest::Register<WKBundleFileHandleTest> registrar("WKBundleFileHandleTest"); + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKConnection.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKConnection.cpp deleted file mode 100644 index d2782a446..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WKConnection.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#include "PlatformWebView.h" -#include "Test.h" - -namespace TestWebKitAPI { - -// State for part 1 - setting up the connection. -static bool connectionEstablished; -static WKConnectionRef connectionToBundle; - -// State for part 2 - send/recieving messages. -static bool messageReceived; - -// State for part 3 - tearing down the connection. -static bool connectionTornDown; - - -/* WKContextConnectionClient */ -static void didCreateConnection(WKContextRef context, WKConnectionRef connection, const void* clientInfo) -{ - connectionEstablished = true; - - // Store off the conneciton to use. - connectionToBundle = (WKConnectionRef)WKRetain(connection); -} - -/* WKConnectionClient */ -static void connectionDidReceiveMessage(WKConnectionRef connection, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo) -{ - // We only expect to get the "Pong" message. - EXPECT_WK_STREQ(messageName, "PongMessageName"); - EXPECT_WK_STREQ((WKStringRef)messageBody, "PongMessageBody"); - - messageReceived = true; -} - -static void connectionDidClose(WKConnectionRef connection, const void* clientInfo) -{ - connectionTornDown = true; -} - -TEST(WebKit2, WKConnectionTest) -{ - WKRetainPtr<WKContextRef> context(AdoptWK, Util::createContextForInjectedBundleTest("WKConnectionTest")); - - // Set up the context's connection client so that we can access the connection when - // it is created. - WKContextConnectionClient contextConnectionClient; - memset(&contextConnectionClient, 0, sizeof(contextConnectionClient)); - contextConnectionClient.version = kWKContextConnectionClientCurrentVersion; - contextConnectionClient.clientInfo = 0; - contextConnectionClient.didCreateConnection = didCreateConnection; - WKContextSetConnectionClient(context.get(), &contextConnectionClient); - - // Load a simple page to start the WebProcess and establish a connection. - PlatformWebView webView(context.get()); - WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); - WKPageLoadURL(webView.page(), url.get()); - - // Wait until the connection is established. - Util::run(&connectionEstablished); - ASSERT_NOT_NULL(connectionToBundle); - - // Setup a client on the connection so we can listen for messages and - // tear down notifications. - WKConnectionClient connectionClient; - memset(&connectionClient, 0, sizeof(connectionClient)); - connectionClient.version = WKConnectionClientCurrentVersion; - connectionClient.clientInfo = 0; - connectionClient.didReceiveMessage = connectionDidReceiveMessage; - connectionClient.didClose = connectionDidClose; - WKConnectionSetConnectionClient(connectionToBundle, &connectionClient); - - // Post a simple message to the bundle via the connection. - WKConnectionPostMessage(connectionToBundle, Util::toWK("PingMessageName").get(), Util::toWK("PingMessageBody").get()); - - // Wait for the reply. - Util::run(&messageReceived); - - // Terminate the page to force the connection closed. - WKPageTerminate(webView.page()); - - // Wait for the connection to close. - Util::run(&connectionTornDown); - - // This release is to balance the retain in didCreateConnection. - WKRelease(connectionToBundle); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/efl/InjectedBundleController.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKImageCreateCGImageCrash.cpp index c2442bd15..f0d19025f 100644 --- a/Tools/TestWebKitAPI/efl/InjectedBundleController.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKImageCreateCGImageCrash.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Igalia S.L. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,15 +24,18 @@ */ #include "config.h" -#include "InjectedBundleController.h" -#include <wtf/Assertions.h> +#if WK_HAVE_C_SPI + +#include <WebKit/WKImageCG.h> namespace TestWebKitAPI { -void InjectedBundleController::platformInitialize() +TEST(WebKit2, WKImageCreateCGImageCrash) { - WTFInstallReportBacktraceOnCrashHook(); + EXPECT_FALSE(WKImageCreateCGImage(nullptr)); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKPageConfiguration.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKPageConfiguration.cpp new file mode 100644 index 000000000..d041eeaed --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKPageConfiguration.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2015 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" + +#if WK_HAVE_C_SPI + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" + +#include <WebKit/WKWebsiteDataStoreRef.h> + +namespace TestWebKitAPI { + +TEST(WebKit2, WKPageConfigurationEmpty) +{ + WKRetainPtr<WKPageConfigurationRef> configuration = adoptWK(WKPageConfigurationCreate()); + + ASSERT_NULL(WKPageConfigurationGetContext(configuration.get())); + ASSERT_NULL(WKPageConfigurationGetUserContentController(configuration.get())); + ASSERT_NULL(WKPageConfigurationGetPageGroup(configuration.get())); + ASSERT_NULL(WKPageConfigurationGetPreferences(configuration.get())); + ASSERT_NULL(WKPageConfigurationGetRelatedPage(configuration.get())); +} + +static bool didFinishLoad; + +static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) +{ + didFinishLoad = true; +} + +static void setPageLoaderClient(WKPageRef page) +{ + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 0; + loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + + WKPageSetPageLoaderClient(page, &loaderClient.base); +} + +TEST(WebKit2, WKPageConfigurationBasic) +{ + WKRetainPtr<WKPageConfigurationRef> configuration = adoptWK(WKPageConfigurationCreate()); + WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); + WKPageConfigurationSetContext(configuration.get(), context.get()); + + PlatformWebView webView(configuration.get()); + setPageLoaderClient(webView.page()); + + WKRetainPtr<WKPageConfigurationRef> copiedConfiguration = adoptWK(WKPageCopyPageConfiguration(webView.page())); + ASSERT_EQ(context.get(), WKPageConfigurationGetContext(copiedConfiguration.get())); + + WKRetainPtr<WKURLRef> url = adoptWK(Util::createURLForResource("simple", "html")); + WKPageLoadURL(webView.page(), url.get()); + + didFinishLoad = false; + Util::run(&didFinishLoad); +} + +TEST(WebKit2, WKPageConfigurationBasicWithDataStore) +{ + WKRetainPtr<WKPageConfigurationRef> configuration = adoptWK(WKPageConfigurationCreate()); + WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); + WKPageConfigurationSetContext(configuration.get(), context.get()); + WKRetainPtr<WKWebsiteDataStoreRef> websiteDataStore = WKWebsiteDataStoreGetDefaultDataStore(); + WKPageConfigurationSetWebsiteDataStore(configuration.get(), websiteDataStore.get()); + + PlatformWebView webView(configuration.get()); + setPageLoaderClient(webView.page()); + + WKRetainPtr<WKPageConfigurationRef> copiedConfiguration = adoptWK(WKPageCopyPageConfiguration(webView.page())); + ASSERT_EQ(context.get(), WKPageConfigurationGetContext(copiedConfiguration.get())); + ASSERT_EQ(WKWebsiteDataStoreGetDefaultDataStore(), WKPageConfigurationGetWebsiteDataStore(copiedConfiguration.get())); + + WKRetainPtr<WKURLRef> url = adoptWK(Util::createURLForResource("simple", "html")); + WKPageLoadURL(webView.page(), url.get()); + + didFinishLoad = false; + Util::run(&didFinishLoad); +} + +TEST(WebKit2, WKPageConfigurationBasicWithNonPersistentDataStore) +{ + WKRetainPtr<WKPageConfigurationRef> configuration = adoptWK(WKPageConfigurationCreate()); + WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); + WKPageConfigurationSetContext(configuration.get(), context.get()); + WKRetainPtr<WKWebsiteDataStoreRef> websiteDataStore = adoptWK(WKWebsiteDataStoreCreateNonPersistentDataStore()); + WKPageConfigurationSetWebsiteDataStore(configuration.get(), websiteDataStore.get()); + + PlatformWebView webView(configuration.get()); + setPageLoaderClient(webView.page()); + + WKRetainPtr<WKPageConfigurationRef> copiedConfiguration = adoptWK(WKPageCopyPageConfiguration(webView.page())); + ASSERT_EQ(context.get(), WKPageConfigurationGetContext(copiedConfiguration.get())); + ASSERT_EQ(websiteDataStore.get(), WKPageConfigurationGetWebsiteDataStore(copiedConfiguration.get())); + + WKRetainPtr<WKURLRef> url = adoptWK(Util::createURLForResource("simple", "html")); + WKPageLoadURL(webView.page(), url.get()); + + didFinishLoad = false; + Util::run(&didFinishLoad); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKPageCopySessionStateWithFiltering.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKPageCopySessionStateWithFiltering.cpp new file mode 100644 index 000000000..6ce49a13b --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKPageCopySessionStateWithFiltering.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2015 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" + +#if WK_HAVE_C_SPI + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" + +namespace TestWebKitAPI { + +static bool didFinishLoad; +static WKRetainPtr<WKSessionStateRef> sessionStateWithFirstItemRemoved; +static WKRetainPtr<WKSessionStateRef> sessionStateWithAllItemsRemoved; + +static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) +{ + didFinishLoad = true; +} + +static void setPageLoaderClient(WKPageRef page) +{ + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 0; + loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + + WKPageSetPageLoaderClient(page, &loaderClient.base); +} + +static bool filterFirstItemCallback(WKPageRef page, WKStringRef valueType, WKTypeRef value, void* context) +{ + if (!WKStringIsEqual(valueType, WKPageGetSessionBackForwardListItemValueType())) + return true; + + ASSERT(WKGetTypeID(value) == WKBackForwardListItemGetTypeID()); + WKBackForwardListItemRef backForwardListItem = static_cast<WKBackForwardListItemRef>(value); + + WKRetainPtr<WKURLRef> url = adoptWK(WKBackForwardListItemCopyURL(backForwardListItem)); + WKRetainPtr<WKStringRef> path = adoptWK(WKURLCopyLastPathComponent(url.get())); + + return !WKStringIsEqualToUTF8CString(path.get(), "simple.html"); +} + +static bool filterAllItemsCallback(WKPageRef page, WKStringRef valueType, WKTypeRef value, void* context) +{ + return false; +} + +static void createSessionStates(WKContextRef context) +{ + PlatformWebView webView(context); + setPageLoaderClient(webView.page()); + + WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple", "html")).get()); + Util::run(&didFinishLoad); + didFinishLoad = false; + + WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple2", "html")).get()); + Util::run(&didFinishLoad); + didFinishLoad = false; + + WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple3", "html")).get()); + Util::run(&didFinishLoad); + didFinishLoad = false; + + WKPageGoBack(webView.page()); + Util::run(&didFinishLoad); + didFinishLoad = false; + + WKPageGoBack(webView.page()); + Util::run(&didFinishLoad); + didFinishLoad = false; + + // Should be back on simple.html at this point. + + sessionStateWithFirstItemRemoved = adoptWK(static_cast<WKSessionStateRef>(WKPageCopySessionState(webView.page(), reinterpret_cast<void*>(1), filterFirstItemCallback))); + sessionStateWithAllItemsRemoved = adoptWK(static_cast<WKSessionStateRef>(WKPageCopySessionState(webView.page(), reinterpret_cast<void*>(1), filterAllItemsCallback))); +} + +TEST(WebKit2, WKPageCopySessionStateWithFiltering) +{ + WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); + + createSessionStates(context.get()); + + EXPECT_NOT_NULL(sessionStateWithFirstItemRemoved); + PlatformWebView webView1(context.get()); + setPageLoaderClient(webView1.page()); + WKPageRestoreFromSessionState(webView1.page(), sessionStateWithFirstItemRemoved.get()); + Util::run(&didFinishLoad); + didFinishLoad = false; + + WKBackForwardListRef backForwardList1 = WKPageGetBackForwardList(webView1.page()); + EXPECT_EQ(0u, WKBackForwardListGetBackListCount(backForwardList1)); + EXPECT_EQ(1u, WKBackForwardListGetForwardListCount(backForwardList1)); + + EXPECT_NOT_NULL(sessionStateWithAllItemsRemoved); + PlatformWebView webView2(context.get()); + setPageLoaderClient(webView2.page()); + WKPageRestoreFromSessionState(webView2.page(), sessionStateWithAllItemsRemoved.get()); + // Because the session state ends up being empty, nothing is actually loaded. + + WKBackForwardListRef backForwardList2 = WKPageGetBackForwardList(webView2.page()); + EXPECT_EQ(0u, WKBackForwardListGetBackListCount(backForwardList2)); + EXPECT_EQ(0u, WKBackForwardListGetForwardListCount(backForwardList2)); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKPageGetScaleFactorNotZero.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKPageGetScaleFactorNotZero.cpp index 85490de39..929baaa71 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WKPageGetScaleFactorNotZero.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKPageGetScaleFactorNotZero.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" @@ -39,15 +42,16 @@ static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) static void setPageLoaderClient(WKPageRef page) { - WKPageLoaderClient loaderClient; + WKPageLoaderClientV0 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; + + loaderClient.base.version = 0; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(page, &loaderClient); + WKPageSetPageLoaderClient(page, &loaderClient.base); } -static WKRetainPtr<WKDataRef> createSessionState(WKContextRef context) +static WKRetainPtr<WKSessionStateRef> createSessionState(WKContextRef context) { PlatformWebView webView(context); setPageLoaderClient(webView.page()); @@ -56,7 +60,7 @@ static WKRetainPtr<WKDataRef> createSessionState(WKContextRef context) Util::run(&didFinishLoad); didFinishLoad = false; - return adoptWK(WKPageCopySessionState(webView.page(), 0, 0)); + return adoptWK(static_cast<WKSessionStateRef>(WKPageCopySessionState(webView.page(), reinterpret_cast<void*>(1), nullptr))); } TEST(WebKit2, WKPageGetScaleFactorNotZero) @@ -66,13 +70,15 @@ TEST(WebKit2, WKPageGetScaleFactorNotZero) PlatformWebView webView(context.get()); setPageLoaderClient(webView.page()); - WKRetainPtr<WKDataRef> data = createSessionState(context.get()); - EXPECT_NOT_NULL(data); + auto sessionState = createSessionState(context.get()); + EXPECT_NOT_NULL(sessionState); - WKPageRestoreFromSessionState(webView.page(), data.get()); + WKPageRestoreFromSessionState(webView.page(), sessionState.get()); Util::run(&didFinishLoad); EXPECT_TRUE(WKPageGetScaleFactor(webView.page()) == 1.0); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKPageIsPlayingAudio.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKPageIsPlayingAudio.cpp new file mode 100644 index 000000000..1e848133f --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKPageIsPlayingAudio.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2014 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" + +#if WK_HAVE_C_SPI + +#include "PlatformUtilities.h" +#include "PlatformWebView.h" +#include "Test.h" +#include <JavaScriptCore/JSRetainPtr.h> +#include <JavaScriptCore/JavaScriptCore.h> +#include <WebKit/WKSerializedScriptValue.h> +#include <WebKit/WKPagePrivate.h> +#include <WebKit/WKPreferencesRef.h> +#include <WebKit/WKPreferencesRefPrivate.h> + +// This test loads file-with-video.html. It first checks to make sure WKPageIsPlayingAudio() returns +// false for the page. Then it calls a JavaScript method to play the video, waits for +// WKPageUIClient::isPlayingAudioDidChange() to get called, and checks that WKPageIsPlayingAudio() now +// returns true for the page. + +namespace TestWebKitAPI { + +static bool isMSEEnabledChanged; +static bool isMSEEnabled; +static bool didFinishLoad; +static bool isPlayingAudioChanged; + +static void nullJavaScriptCallback(WKSerializedScriptValueRef, WKErrorRef error, void*) +{ +} + +static void isMSEEnabledCallback(WKSerializedScriptValueRef serializedResultValue, WKErrorRef error, void*) +{ + JSGlobalContextRef scriptContext = JSGlobalContextCreate(0); + + JSValueRef resultValue = WKSerializedScriptValueDeserialize(serializedResultValue, scriptContext, 0); + EXPECT_TRUE(JSValueIsBoolean(scriptContext, resultValue)); + + isMSEEnabledChanged = true; + isMSEEnabled = JSValueToBoolean(scriptContext, resultValue); + + JSGlobalContextRelease(scriptContext); +} + +static void didFinishLoadForFrame(WKPageRef page, WKFrameRef, WKTypeRef, const void*) +{ + didFinishLoad = true; +} + +static void isPlayingAudioDidChangeCallback(WKPageRef page, const void*) +{ + isPlayingAudioChanged = true; +} + +static void setUpClients(WKPageRef page) +{ + WKPageLoaderClientV0 loaderClient; + memset(&loaderClient, 0, sizeof(loaderClient)); + + loaderClient.base.version = 0; + loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; + + WKPageSetPageLoaderClient(page, &loaderClient.base); + + WKPageUIClientV5 uiClient; + memset(&uiClient, 0, sizeof(uiClient)); + + uiClient.base.version = 5; + uiClient.isPlayingAudioDidChange = isPlayingAudioDidChangeCallback; + + WKPageSetPageUIClient(page, &uiClient.base); +} + +TEST(WebKit2, WKPageIsPlayingAudio) +{ + WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); + + PlatformWebView webView(context.get()); + setUpClients(webView.page()); + + WKRetainPtr<WKURLRef> url = adoptWK(Util::createURLForResource("file-with-video", "html")); + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&didFinishLoad); + + EXPECT_FALSE(WKPageIsPlayingAudio(webView.page())); + WKPageRunJavaScriptInMainFrame(webView.page(), Util::toWK("playVideo()").get(), 0, nullJavaScriptCallback); + + Util::run(&isPlayingAudioChanged); + EXPECT_TRUE(WKPageIsPlayingAudio(webView.page())); +} + +TEST(WebKit2, MSEIsPlayingAudio) +{ + WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); + + WKRetainPtr<WKPageGroupRef> pageGroup(AdoptWK, WKPageGroupCreateWithIdentifier(Util::toWK("MSEIsPlayingAudioPageGroup").get())); + WKPreferencesRef preferences = WKPageGroupGetPreferences(pageGroup.get()); + WKPreferencesSetMediaSourceEnabled(preferences, true); + WKPreferencesSetFileAccessFromFileURLsAllowed(preferences, true); + + PlatformWebView webView(context.get(), pageGroup.get()); + setUpClients(webView.page()); + + WKRetainPtr<WKURLRef> url = adoptWK(Util::createURLForResource("file-with-mse", "html")); + didFinishLoad = false; + WKPageLoadURL(webView.page(), url.get()); + + Util::run(&didFinishLoad); + + // Bail out of the test early if the platform does not support MSE. + isMSEEnabledChanged = false; + WKPageRunJavaScriptInMainFrame(webView.page(), Util::toWK("window.MediaSource !== undefined").get(), 0, isMSEEnabledCallback); + Util::run(&isMSEEnabledChanged); + if (!isMSEEnabled) + return; + + EXPECT_FALSE(WKPageIsPlayingAudio(webView.page())); + isPlayingAudioChanged = false; + WKPageRunJavaScriptInMainFrame(webView.page(), Util::toWK("playVideo()").get(), 0, nullJavaScriptCallback); + + Util::run(&isPlayingAudioChanged); + EXPECT_TRUE(WKPageIsPlayingAudio(webView.page())); +} + +} // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKPreferences.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKPreferences.cpp index 976e7041b..7971b0b27 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WKPreferences.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKPreferences.cpp @@ -24,9 +24,12 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" -#include <WebKit2/WKPreferencesPrivate.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKPreferencesRefPrivate.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -41,15 +44,15 @@ TEST(WebKit2, WKPreferencesBasic) TEST(WebKit2, WKPreferencesDefaults) { -#if PLATFORM(WIN) - static const char* expectedStandardFontFamily = "Times New Roman"; +#if PLATFORM(GTK) || PLATFORM(EFL) + static const char* expectedStandardFontFamily = "Times"; static const char* expectedFixedFontFamily = "Courier New"; - static const char* expectedSerifFontFamily = "Times New Roman"; - static const char* expectedSansSerifFontFamily = "Arial"; + static const char* expectedSerifFontFamily = "Times"; + static const char* expectedSansSerifFontFamily = "Helvetica"; static const char* expectedCursiveFontFamily = "Comic Sans MS"; - static const char* expectedFantasyFontFamily = "Comic Sans MS"; - static const char* expectedPictographFontFamily = "Times New Roman"; -#elif PLATFORM(MAC) + static const char* expectedFantasyFontFamily = "Impact"; + static const char* expectedPictographFontFamily = "Times"; +#elif WK_HAVE_C_SPI static const char* expectedStandardFontFamily = "Times"; static const char* expectedFixedFontFamily = "Courier"; static const char* expectedSerifFontFamily = "Times"; @@ -57,14 +60,14 @@ TEST(WebKit2, WKPreferencesDefaults) static const char* expectedCursiveFontFamily = "Apple Chancery"; static const char* expectedFantasyFontFamily = "Papyrus"; static const char* expectedPictographFontFamily = "Apple Color Emoji"; -#elif PLATFORM(GTK) || PLATFORM(EFL) +#elif PLATFORM(IOS) static const char* expectedStandardFontFamily = "Times"; - static const char* expectedFixedFontFamily = "Courier New"; + static const char* expectedFixedFontFamily = "Courier"; static const char* expectedSerifFontFamily = "Times"; static const char* expectedSansSerifFontFamily = "Helvetica"; - static const char* expectedCursiveFontFamily = "Comic Sans MS"; - static const char* expectedFantasyFontFamily = "Impact"; - static const char* expectedPictographFontFamily = "Times"; + static const char* expectedCursiveFontFamily = "Snell Roundhand"; + static const char* expectedFantasyFontFamily = "Papyrus"; + static const char* expectedPictographFontFamily = "AppleColorEmoji"; #endif WKPreferencesRef preference = WKPreferencesCreate(); @@ -91,11 +94,7 @@ TEST(WebKit2, WKPreferencesDefaults) EXPECT_FALSE(WKPreferencesGetDeveloperExtrasEnabled(preference)); EXPECT_TRUE(WKPreferencesGetTextAreasAreResizable(preference)); -#if PLATFORM(WIN) - EXPECT_EQ(kWKFontSmoothingLevelWindows, WKPreferencesGetFontSmoothingLevel(preference)); -#else EXPECT_EQ(kWKFontSmoothingLevelMedium, WKPreferencesGetFontSmoothingLevel(preference)); -#endif EXPECT_TRUE(WKPreferencesGetAcceleratedCompositingEnabled(preference)); EXPECT_FALSE(WKPreferencesGetCompositingBordersVisible(preference)); @@ -122,3 +121,5 @@ TEST(WebKit2, WKPreferencesCopying) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/win/WMCloseCallsUIClientClose.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKRetainPtr.cpp index 5fa4b3a2a..860d7d48d 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/win/WMCloseCallsUIClientClose.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKRetainPtr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,33 +24,35 @@ */ #include "config.h" -#include "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> -namespace TestWebKitAPI { +#if WK_HAVE_C_SPI -static bool didReceiveClose; +#include "PlatformUtilities.h" +#include <wtf/HashMap.h> -static void close(WKPageRef, const void*) -{ - didReceiveClose = true; -} +namespace TestWebKitAPI { -TEST(WebKit2, WMCloseCallsUIClientClose) +TEST(WebKit2, WKRetainPtr) { - WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - PlatformWebView webView(context.get()); + WKRetainPtr<WKStringRef> string1 = adoptWK(WKStringCreateWithUTF8CString("a")); + WKRetainPtr<WKStringRef> string2 = adoptWK(WKStringCreateWithUTF8CString("a")); + WKRetainPtr<WKStringRef> string3 = adoptWK(WKStringCreateWithUTF8CString("a")); + WKRetainPtr<WKStringRef> string4 = adoptWK(WKStringCreateWithUTF8CString("a")); - WKPageUIClient uiClient; - memset(&uiClient, 0, sizeof(uiClient)); + HashMap<WKRetainPtr<WKStringRef>, int> map; - uiClient.close = close; - WKPageSetPageUIClient(webView.page(), &uiClient); + map.set(string2, 2); + map.set(string1, 1); - ::SendMessageW(WKViewGetWindow(webView.platformView()), WM_CLOSE, 0, 0); + EXPECT_TRUE(map.contains(string1)); + EXPECT_TRUE(map.contains(string2)); + EXPECT_FALSE(map.contains(string3)); + EXPECT_FALSE(map.contains(string4)); - Util::run(&didReceiveClose); + EXPECT_EQ(1, map.get(string1)); + EXPECT_EQ(2, map.get(string2)); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKString.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKString.cpp index b67235932..b4167be81 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WKString.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKString.cpp @@ -25,6 +25,8 @@ #include "config.h" +#if WK_HAVE_C_SPI + namespace TestWebKitAPI { TEST(WebKit2, WKString) @@ -69,3 +71,5 @@ TEST(WebKit2, WKString) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WKStringJSString.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WKStringJSString.cpp index cdba57de4..8b6e08b9d 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WKStringJSString.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WKStringJSString.cpp @@ -24,7 +24,10 @@ */ #include "config.h" -#include <WebKit2/WKStringPrivate.h> + +#if WK_HAVE_C_SPI + +#include <WebKit/WKStringPrivate.h> #include <JavaScriptCore/JSStringRef.h> namespace TestWebKitAPI { @@ -48,3 +51,5 @@ TEST(WebKit2, WKStringJSString) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WebArchive.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WebArchive.cpp index 0e6b985fb..06d673e21 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WebArchive.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WebArchive.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include <CoreFoundation/CoreFoundation.h> -#include <WebKit2/WKURLCF.h> -#include <WebKit2/WKContextPrivate.h> +#include <WebKit/WKURLCF.h> +#include <WebKit/WKContextPrivate.h> #include <wtf/RetainPtr.h> namespace TestWebKitAPI { @@ -88,11 +91,13 @@ static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messag static void setInjectedBundleClient(WKContextRef context) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } static void didFinishLoadForFrame(WKPageRef page, WKFrameRef, WKTypeRef, const void*) @@ -107,12 +112,13 @@ TEST(WebKit2, WebArchive) PlatformWebView webView(context.get()); - WKPageLoaderClient loaderClient; + WKPageLoaderClientV3 loaderClient; memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = kWKPageLoaderClientCurrentVersion; + loaderClient.base.version = 3; loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); + + WKPageSetPageLoaderClient(webView.page(), &loaderClient.base); WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple", "html")).get()); @@ -125,3 +131,5 @@ TEST(WebKit2, WebArchive) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WebArchive_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WebArchive_Bundle.cpp index f58859517..11109fee0 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WebArchive_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WebArchive_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKBundleFrame.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKBundleFrame.h> namespace TestWebKitAPI { @@ -62,3 +65,5 @@ void WebArchiveTest::didReceiveMessage(WKBundleRef bundle, WKStringRef messageNa } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WebCoreStatisticsWithNoWebProcess.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WebCoreStatisticsWithNoWebProcess.cpp index f71f186b7..ff5eef04d 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WebCoreStatisticsWithNoWebProcess.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WebCoreStatisticsWithNoWebProcess.cpp @@ -24,8 +24,11 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" -#include "test.h" +#include "Test.h" namespace TestWebKitAPI { @@ -48,3 +51,5 @@ TEST(WebKit2, WebCoreStatisticsWithNoWebProcess) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WebKit2.pro b/Tools/TestWebKitAPI/Tests/WebKit2/WebKit2.pro deleted file mode 100644 index 4a93643fc..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WebKit2.pro +++ /dev/null @@ -1,63 +0,0 @@ -TEMPLATE = app -TARGET = tst_webkit2 - -SOURCES += \ - AboutBlankLoad.cpp \ - DocumentStartUserScriptAlertCrash.cpp \ - DOMWindowExtensionBasic.cpp \ - DOMWindowExtensionNoCache.cpp \ - DocumentStartUserScriptAlertCrash.cpp \ - EvaluateJavaScript.cpp \ - FailedLoad.cpp \ - Find.cpp \ - FrameMIMETypeHTML.cpp \ - FrameMIMETypePNG.cpp \ - GetInjectedBundleInitializationUserDataCallback.cpp \ - HitTestResultNodeHandle.cpp \ - InjectedBundleBasic.cpp \ - InjectedBundleFrameHitTest.cpp \ - InjectedBundleInitializationUserDataCallbackWins.cpp \ - LoadAlternateHTMLStringWithNonDirectoryURL.cpp \ - LoadCanceledNoServerRedirectCallback.cpp \ - LoadPageOnCrash.cpp \ - MouseMoveAfterCrash.cpp \ - PageLoadBasic.cpp \ - PageLoadDidChangeLocationWithinPageForFrame.cpp \ - PageVisibilityState.cpp \ - ParentFrame.cpp \ - PreventEmptyUserAgent.cpp \ - PrivateBrowsingPushStateNoHistoryCallback.cpp \ - ReloadPageAfterCrash.cpp \ - ResizeWindowAfterCrash.cpp \ - ResponsivenessTimerDoesntFireEarly.cpp \ - TerminateTwice.cpp \ - UserMessage.cpp \ - WillSendSubmitEvent.cpp \ - WKConnection.cpp \ - WKString.cpp \ - WKStringJSString.cpp \ - WKURL.cpp - -FAILING_SOURCES = \ - CanHandleRequest.cpp \ - -FAILING_SOURCES += ShouldGoToBackForwardListItem.cpp # Only stalls in flickable mode. -FAILING_SOURCES += SpacebarScrolling.cpp # Only fails in flickable mode. - -SOURCES += $$FAILING_SOURCES - -# Tests skipped because they crash, stall or do not compile. -SKIPPED_SOURCES = \ - CookieManager.cpp \ - DownloadDecideDestinationCrash.cpp \ - ForceRepaint.cpp \ - NewFirstVisuallyNonEmptyLayout.cpp \ - NewFirstVisuallyNonEmptyLayoutFails.cpp \ - NewFirstVisuallyNonEmptyLayoutForImages.cpp \ - NewFirstVisuallyNonEmptyLayoutFrames.cpp \ - RestoreSessionStateContainingFormData.cpp \ - WebCoreStatisticsWithNoWebProcess.cpp - -include(../../TestWebKitAPI.pri) - -DEFINES += APITEST_SOURCE_DIR=\\\"$$PWD\\\" diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WillLoad.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WillLoad.cpp index beeb8007f..83d63ab18 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WillLoad.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WillLoad.cpp @@ -24,12 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "Test.h" #include "PlatformUtilities.h" #include "PlatformWebView.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> namespace TestWebKitAPI { @@ -41,7 +42,7 @@ public: } WKRetainPtr<WKContextRef> context; - OwnPtr<PlatformWebView> webView; + std::unique_ptr<PlatformWebView> webView; WKRetainPtr<WKStringRef> messageName; WKRetainPtr<WKTypeRef> messageBody; @@ -56,13 +57,14 @@ public: static void setInjectedBundleClient(WKContextRef context, const void* clientInfo) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV1 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.version = kWKContextInjectedBundleClientCurrentVersion; - injectedBundleClient.clientInfo = clientInfo; + + injectedBundleClient.base.version = 1; + injectedBundleClient.base.clientInfo = clientInfo; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } virtual void SetUp() @@ -70,7 +72,7 @@ public: context = adoptWK(Util::createContextForInjectedBundleTest("WillLoadTest")); setInjectedBundleClient(context.get(), this); - webView = adoptPtr(new PlatformWebView(context.get())); + webView = std::make_unique<PlatformWebView>(context.get()); didReceiveMessage = false; } @@ -178,7 +180,7 @@ TEST_F(WebKit2WillLoadTest, WKPageLoadHTMLStringWithUserData) WKPageLoadHTMLStringWithUserData(webView->page(), htmlString.get(), baseURL.get(), userData.get()); - testWillLoadDataRequestReturnValues(baseURL.get(), Util::toWK("text/html").get(), Util::toWK("utf-16").get(), 0, userData.get()); + testWillLoadDataRequestReturnValues(baseURL.get(), Util::toWK("text/html").get(), Util::toWK("latin1").get(), 0, userData.get()); } TEST_F(WebKit2WillLoadTest, WKPageLoadHTMLString) @@ -188,7 +190,7 @@ TEST_F(WebKit2WillLoadTest, WKPageLoadHTMLString) WKPageLoadHTMLString(webView->page(), htmlString.get(), baseURL.get()); - testWillLoadDataRequestReturnValues(baseURL.get(), Util::toWK("text/html").get(), Util::toWK("utf-16").get(), 0, 0); + testWillLoadDataRequestReturnValues(baseURL.get(), Util::toWK("text/html").get(), Util::toWK("latin1").get(), 0, 0); } TEST_F(WebKit2WillLoadTest, WKPageLoadAlternateHTMLStringWithUserData) @@ -201,7 +203,7 @@ TEST_F(WebKit2WillLoadTest, WKPageLoadAlternateHTMLStringWithUserData) WKPageLoadAlternateHTMLStringWithUserData(webView->page(), htmlString.get(), baseURL.get(), unreachableURL.get(), userData.get()); - testWillLoadDataRequestReturnValues(baseURL.get(), Util::toWK("text/html").get(), Util::toWK("utf-16").get(), unreachableURL.get(), userData.get()); + testWillLoadDataRequestReturnValues(baseURL.get(), Util::toWK("text/html").get(), Util::toWK("latin1").get(), unreachableURL.get(), userData.get()); } TEST_F(WebKit2WillLoadTest, WKPageLoadAlternateHTMLString) @@ -213,7 +215,7 @@ TEST_F(WebKit2WillLoadTest, WKPageLoadAlternateHTMLString) WKPageLoadAlternateHTMLString(webView->page(), htmlString.get(), baseURL.get(), unreachableURL.get()); - testWillLoadDataRequestReturnValues(baseURL.get(), Util::toWK("text/html").get(), Util::toWK("utf-16").get(), unreachableURL.get(), 0); + testWillLoadDataRequestReturnValues(baseURL.get(), Util::toWK("text/html").get(), Util::toWK("latin1").get(), unreachableURL.get(), 0); } TEST_F(WebKit2WillLoadTest, WKPageLoadPlainTextStringWithUserData) @@ -224,7 +226,7 @@ TEST_F(WebKit2WillLoadTest, WKPageLoadPlainTextStringWithUserData) WKPageLoadPlainTextStringWithUserData(webView->page(), plaintTextString.get(), userData.get()); WKRetainPtr<WKURLRef> blankURL = adoptWK(WKURLCreateWithUTF8CString("about:blank")); - testWillLoadDataRequestReturnValues(blankURL.get(), Util::toWK("text/plain").get(), Util::toWK("utf-16").get(), 0, userData.get()); + testWillLoadDataRequestReturnValues(blankURL.get(), Util::toWK("text/plain").get(), Util::toWK("latin1").get(), 0, userData.get()); } TEST_F(WebKit2WillLoadTest, WKPageLoadPlainTextString) @@ -234,7 +236,9 @@ TEST_F(WebKit2WillLoadTest, WKPageLoadPlainTextString) WKPageLoadPlainTextString(webView->page(), plaintTextString.get()); WKRetainPtr<WKURLRef> blankURL = adoptWK(WKURLCreateWithUTF8CString("about:blank")); - testWillLoadDataRequestReturnValues(blankURL.get(), Util::toWK("text/plain").get(), Util::toWK("utf-16").get(), 0, 0); + testWillLoadDataRequestReturnValues(blankURL.get(), Util::toWK("text/plain").get(), Util::toWK("latin1").get(), 0, 0); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WillLoad_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WillLoad_Bundle.cpp index 039349bd5..091e5a942 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WillLoad_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WillLoad_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKBundlePage.h> +#include <WebKit/WKRetainPtr.h> namespace TestWebKitAPI { @@ -44,41 +47,43 @@ private: { WKRetainPtr<WKMutableDictionaryRef> messageBody = adoptWK(WKMutableDictionaryCreate()); - WKDictionaryAddItem(messageBody.get(), Util::toWK("URLRequestReturn").get(), request); - WKDictionaryAddItem(messageBody.get(), Util::toWK("UserDataReturn").get(), userData); + WKDictionarySetItem(messageBody.get(), Util::toWK("URLRequestReturn").get(), request); + WKDictionarySetItem(messageBody.get(), Util::toWK("UserDataReturn").get(), userData); - WKBundlePostMessage(InjectedBundleController::shared().bundle(), Util::toWK("WillLoadURLRequestReturn").get(), messageBody.get()); + WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("WillLoadURLRequestReturn").get(), messageBody.get()); } static void willLoadDataRequest(WKBundlePageRef page, WKURLRequestRef request, WKDataRef data, WKStringRef MIMEType, WKStringRef encodingName, WKURLRef unreachableURL, WKTypeRef userData, const void *clientInfo) { WKRetainPtr<WKMutableDictionaryRef> messageBody = adoptWK(WKMutableDictionaryCreate()); - WKDictionaryAddItem(messageBody.get(), Util::toWK("URLRequestReturn").get(), request); - WKDictionaryAddItem(messageBody.get(), Util::toWK("DataReturn").get(), data); - WKDictionaryAddItem(messageBody.get(), Util::toWK("MIMETypeReturn").get(), MIMEType); - WKDictionaryAddItem(messageBody.get(), Util::toWK("EncodingNameReturn").get(), encodingName); - WKDictionaryAddItem(messageBody.get(), Util::toWK("UnreachableURLReturn").get(), unreachableURL); - WKDictionaryAddItem(messageBody.get(), Util::toWK("UserDataReturn").get(), userData); + WKDictionarySetItem(messageBody.get(), Util::toWK("URLRequestReturn").get(), request); + WKDictionarySetItem(messageBody.get(), Util::toWK("DataReturn").get(), data); + WKDictionarySetItem(messageBody.get(), Util::toWK("MIMETypeReturn").get(), MIMEType); + WKDictionarySetItem(messageBody.get(), Util::toWK("EncodingNameReturn").get(), encodingName); + WKDictionarySetItem(messageBody.get(), Util::toWK("UnreachableURLReturn").get(), unreachableURL); + WKDictionarySetItem(messageBody.get(), Util::toWK("UserDataReturn").get(), userData); - WKBundlePostMessage(InjectedBundleController::shared().bundle(), Util::toWK("WillLoadDataRequestReturn").get(), messageBody.get()); + WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("WillLoadDataRequestReturn").get(), messageBody.get()); } - virtual void didCreatePage(WKBundleRef, WKBundlePageRef bundlePage) OVERRIDE + virtual void didCreatePage(WKBundleRef, WKBundlePageRef bundlePage) override { - WKBundlePageLoaderClient pageLoaderClient; + WKBundlePageLoaderClientV6 pageLoaderClient; memset(&pageLoaderClient, 0, sizeof(pageLoaderClient)); - pageLoaderClient.version = 6; - pageLoaderClient.clientInfo = this; + pageLoaderClient.base.version = 6; + pageLoaderClient.base.clientInfo = this; pageLoaderClient.willLoadURLRequest = willLoadURLRequest; pageLoaderClient.willLoadDataRequest = willLoadDataRequest; - WKBundlePageSetPageLoaderClient(bundlePage, &pageLoaderClient); + WKBundlePageSetPageLoaderClient(bundlePage, &pageLoaderClient.base); } }; static InjectedBundleTest::Register<WillLoadTest> registrar("WillLoadTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent.cpp index 1058cc1f3..951aaf005 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent.cpp @@ -24,6 +24,9 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "PlatformUtilities.h" #include "PlatformWebView.h" #include "Test.h" @@ -57,11 +60,13 @@ static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messag static void setInjectedBundleClient(WKContextRef context) { - WKContextInjectedBundleClient injectedBundleClient; + WKContextInjectedBundleClientV0 injectedBundleClient; memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); + + injectedBundleClient.base.version = 0; injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); + WKContextSetInjectedBundleClient(context, &injectedBundleClient.base); } TEST(WebKit2, WillSendSubmitEvent) @@ -75,3 +80,5 @@ TEST(WebKit2, WillSendSubmitEvent) } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent_Bundle.cpp index 7bbbcaf10..fa7d2a9a7 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2/WillSendSubmitEvent_Bundle.cpp @@ -24,10 +24,13 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" -#include <WebKit2/WKBundlePage.h> +#include <WebKit/WKBundlePage.h> namespace TestWebKitAPI { @@ -42,7 +45,7 @@ static InjectedBundleTest::Register<WillSendSubmitEventTest> registrar("WillSend static void willSendSubmitEvent(WKBundlePageRef, WKBundleNodeHandleRef, WKBundleFrameRef, WKBundleFrameRef, WKDictionaryRef values, const void*) { - WKBundlePostMessage(InjectedBundleController::shared().bundle(), Util::toWK("DidReceiveWillSendSubmitEvent").get(), values); + WKBundlePostMessage(InjectedBundleController::singleton().bundle(), Util::toWK("DidReceiveWillSendSubmitEvent").get(), values); } WillSendSubmitEventTest::WillSendSubmitEventTest(const std::string& identifier) @@ -52,14 +55,16 @@ WillSendSubmitEventTest::WillSendSubmitEventTest(const std::string& identifier) void WillSendSubmitEventTest::didCreatePage(WKBundleRef bundle, WKBundlePageRef page) { - WKBundlePageFormClient formClient; + WKBundlePageFormClientV1 formClient; memset(&formClient, 0, sizeof(formClient)); - formClient.version = 1; - formClient.clientInfo = this; + formClient.base.version = 1; + formClient.base.clientInfo = this; formClient.willSendSubmitEvent = willSendSubmitEvent; - WKBundlePageSetFormClient(page, &formClient); + WKBundlePageSetFormClient(page, &formClient.base); } } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/all-content-in-one-iframe.html b/Tools/TestWebKitAPI/Tests/WebKit2/all-content-in-one-iframe.html new file mode 100644 index 000000000..6f45cbd6b --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/all-content-in-one-iframe.html @@ -0,0 +1 @@ +<iframe src="lots-of-text.html"></iframe> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/bundle-file.html b/Tools/TestWebKitAPI/Tests/WebKit2/bundle-file.html new file mode 100644 index 000000000..f426ebdb0 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/bundle-file.html @@ -0,0 +1,16 @@ +<html> +<head> + <script> + function testFile(file) + { + if (!(file instanceof File)) + return false; + + return true; + } + </script> +</head> +<body> + File test. +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/close-from-within-create-page.html b/Tools/TestWebKitAPI/Tests/WebKit2/close-from-within-create-page.html new file mode 100644 index 000000000..51c7981c1 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/close-from-within-create-page.html @@ -0,0 +1,16 @@ +<html> +<script> +function runTest() +{ + if (document.location.search === "?opened-window") { + alert(window.sessionStorage['storageKey']) + return; + } + + window.sessionStorage['storageKey'] = 'value'; + window.open("close-from-within-create-page.html?opened-window"); +} +</script> +<body onload="runTest()"> +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/custom-protocol-sync-xhr.html b/Tools/TestWebKitAPI/Tests/WebKit2/custom-protocol-sync-xhr.html index 8a98f33e9..6cf00b6ca 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2/custom-protocol-sync-xhr.html +++ b/Tools/TestWebKitAPI/Tests/WebKit2/custom-protocol-sync-xhr.html @@ -1,6 +1,6 @@ <script> var request = new XMLHttpRequest(); - request.open('GET', 'test://test', false); + request.open('GET', 'http://test', false); request.send(null); window._testResult = request.responseText; </script>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp deleted file mode 100644 index 552b38c4d..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/efl/WKViewClientWebProcessCallbacks.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2013 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 THE COPYRIGHT HOLDERS ``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 HOLDERS 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 "ewk_view_private.h" -#include "PlatformUtilities.h" -#include "PlatformWebView.h" -#include "Test.h" -#include "WKView.h" -#include <WebKit2/WKRetainPtr.h> - -namespace TestWebKitAPI { - -struct TestStatesData { - TestStatesData(WKViewRef view, WKURLRef url) - : view(view) - , url(url) - , didFinishLoad(false) - , didCrash(false) - , didRelaunch(false) - { - } - - WKViewRef view; - WKURLRef url; - bool didFinishLoad; - bool didCrash; - bool didRelaunch; -}; - -static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void* clientInfo) -{ - TestStatesData* states = const_cast<TestStatesData*>(static_cast<const TestStatesData*>(clientInfo)); - states->didFinishLoad = true; -} - -static void setPageLoaderClient(WKPageRef page, const void* clientInfo) -{ - WKPageLoaderClient loaderClient; - memset(&loaderClient, 0, sizeof(loaderClient)); - - loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - loaderClient.clientInfo = clientInfo; - - WKPageSetPageLoaderClient(page, &loaderClient); -} - -void webProcessCrashed(WKViewRef view, WKURLRef url, const void* clientInfo) -{ - TestStatesData* states = const_cast<TestStatesData*>(static_cast<const TestStatesData*>(clientInfo)); - - EXPECT_EQ(states->view, view); - EXPECT_TRUE(WKURLIsEqual(url, states->url)); - - states->didCrash = true; -} - -void webProcessDidRelaunch(WKViewRef view, const void* clientInfo) -{ - TestStatesData* states = const_cast<TestStatesData*>(static_cast<const TestStatesData*>(clientInfo)); - - EXPECT_EQ(states->view, view); - - states->didRelaunch = true; -} - -static void setViewClient(WKViewRef view, const void* clientInfo) -{ - WKViewClient viewClient; - memset(&viewClient, 0, sizeof(WKViewClient)); - - viewClient.version = kWKViewClientCurrentVersion; - viewClient.clientInfo = clientInfo; - viewClient.webProcessCrashed = webProcessCrashed; - viewClient.webProcessDidRelaunch = webProcessDidRelaunch; - - WKViewSetViewClient(view, &viewClient); -} - -TEST(WebKit2, WKViewClientWebProcessCallbacks) -{ - WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("WKViewClientWebProcessCallbacksTest")); - WKRetainPtr<WKURLRef> url(AdoptWK, Util::createURLForResource("simple", "html")); - - PlatformWebView view(context.get()); - WKViewRef wkView = EWKViewGetWKView(view.platformView()); - - TestStatesData states = TestStatesData(wkView, url.get()); - - setPageLoaderClient(view.page(), &states); - setViewClient(wkView, &states); - - WKPageLoadURL(view.page(), url.get()); - Util::run(&states.didFinishLoad); - - WKContextPostMessageToInjectedBundle(context.get(), Util::toWK("Crash").get(), 0); - Util::run(&states.didCrash); - - WKPageReload(view.page()); - Util::run(&states.didRelaunch); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/file-with-mse.html b/Tools/TestWebKitAPI/Tests/WebKit2/file-with-mse.html new file mode 100644 index 000000000..413eed6e8 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/file-with-mse.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> +<head> + <script> + var source; + var request; + + function playVideo() + { + request = new XMLHttpRequest(); + request.responseType = 'arraybuffer'; + request.open('GET', 'test-mse.mp4', true); + request.addEventListener('load', load); + request.send(); + } + + function load(event) + { + source = new MediaSource(); + source.addEventListener('sourceopen', sourceopen); + var video = document.getElementById('test-video'); + video.src = URL.createObjectURL(source); + } + + function sourceopen(event) + { + var sourceBuffer = source.addSourceBuffer('video/mp4;codecs="avc1.4D4001,mp4a.40.2"'); + sourceBuffer.appendBuffer(request.response); + sourceBuffer.addEventListener('updateend', updateend); + } + + function updateend(event) + { + document.getElementById('test-video').play(); + } + </script> +</head> +<body> + <p> + <video id="test-video" controls></video> + </p> + <p> + <button onclick="playVideo()">Play video</button> + </p> +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/file-with-video.html b/Tools/TestWebKitAPI/Tests/WebKit2/file-with-video.html new file mode 100644 index 000000000..aa2259a0f --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/file-with-video.html @@ -0,0 +1,18 @@ +<html> +<head> + <script> + function playVideo() + { + document.getElementById("test-video").play(); + } + </script> +</head> +<body> + <p> + <video id="test-video" src="test.mp4" controls></video> + </p> + <p> + <button onclick="playVideo()">Play Video</button> + </p> +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/geolocationGetCurrentPosition.html b/Tools/TestWebKitAPI/Tests/WebKit2/geolocationGetCurrentPosition.html new file mode 100644 index 000000000..099f51536 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/geolocationGetCurrentPosition.html @@ -0,0 +1,3 @@ +<script> +navigator.geolocation.getCurrentPosition(function() { }); +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/geolocationGetCurrentPositionWithHighAccuracy.html b/Tools/TestWebKitAPI/Tests/WebKit2/geolocationGetCurrentPositionWithHighAccuracy.html new file mode 100644 index 000000000..26a314858 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/geolocationGetCurrentPositionWithHighAccuracy.html @@ -0,0 +1,3 @@ +<script> +navigator.geolocation.getCurrentPosition(function() { }, function() {}, { enableHighAccuracy:true }); +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/geolocationWatchPosition.html b/Tools/TestWebKitAPI/Tests/WebKit2/geolocationWatchPosition.html new file mode 100644 index 000000000..24788b780 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/geolocationWatchPosition.html @@ -0,0 +1,3 @@ +<script> +navigator.geolocation.watchPosition(function() { }); +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/geolocationWatchPositionWithHighAccuracy.html b/Tools/TestWebKitAPI/Tests/WebKit2/geolocationWatchPositionWithHighAccuracy.html new file mode 100644 index 000000000..aba98fce7 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/geolocationWatchPositionWithHighAccuracy.html @@ -0,0 +1,3 @@ +<script> +navigator.geolocation.watchPosition(function() { }, function() {}, { enableHighAccuracy:true }); +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/getUserMedia.html b/Tools/TestWebKitAPI/Tests/WebKit2/getUserMedia.html new file mode 100644 index 000000000..e54f853bf --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/getUserMedia.html @@ -0,0 +1,14 @@ +<script> +function gotUserMedia(mediaStream) +{ + console.log("Got user media"); +} + +function userMediaError(error) +{ + console.log(error); +} + +var options = { audio: false, video: true}; +navigator.webkitGetUserMedia(options, gotUserMedia, userMediaError); +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/input-focus-blur.html b/Tools/TestWebKitAPI/Tests/WebKit2/input-focus-blur.html new file mode 100644 index 000000000..c06439e66 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/input-focus-blur.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<body> +<input id="input" type="text"> +<input id="readonly" type="text" readonly> +<script> +function focusTextField(id) +{ + document.getElementById(id).focus(); +} + +function blurTextField(id) +{ + document.getElementById(id).blur(); +} +</script> +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/mac/GetBackingScaleFactor.mm b/Tools/TestWebKitAPI/Tests/WebKit2/mac/GetBackingScaleFactor.mm deleted file mode 100644 index ea770519a..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/mac/GetBackingScaleFactor.mm +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - */ - -#import "config.h" - -#import "PlatformUtilities.h" -#import "SyntheticBackingScaleFactorWindow.h" -#import "Test.h" -#import <WebKit2/WKViewPrivate.h> -#import <wtf/RetainPtr.h> - -namespace TestWebKitAPI { - -static bool messageReceived; -static double backingScaleFactor; - -static void didReceiveMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody, const void*) -{ - messageReceived = true; - EXPECT_WK_STREQ("DidGetBackingScaleFactor", messageName); - ASSERT_NOT_NULL(messageBody); - EXPECT_EQ(WKDoubleGetTypeID(), WKGetTypeID(messageBody)); - backingScaleFactor = WKDoubleGetValue(static_cast<WKDoubleRef>(messageBody)); -} - -static void setInjectedBundleClient(WKContextRef context) -{ - WKContextInjectedBundleClient injectedBundleClient; - memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); - injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle; - WKContextSetInjectedBundleClient(context, &injectedBundleClient); -} - -static RetainPtr<SyntheticBackingScaleFactorWindow> createWindow() -{ - RetainPtr<SyntheticBackingScaleFactorWindow> window = adoptNS([[SyntheticBackingScaleFactorWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]); - [window.get() setReleasedWhenClosed:NO]; - return window; -} - -TEST(WebKit2, GetBackingScaleFactor) -{ - WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("GetBackingScaleFactorTest")); - setInjectedBundleClient(context.get()); - RetainPtr<WKView> view = adoptNS([[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) contextRef:context.get() pageGroupRef:0]); - - RetainPtr<SyntheticBackingScaleFactorWindow> window1 = createWindow(); - [window1.get() setBackingScaleFactor:1]; - - [[window1.get() contentView] addSubview:view.get()]; - WKContextPostMessageToInjectedBundle(context.get(), Util::toWK("GetBackingScaleFactor").get(), 0); - Util::run(&messageReceived); - messageReceived = false; - EXPECT_EQ(1, backingScaleFactor); - - RetainPtr<SyntheticBackingScaleFactorWindow> window2 = createWindow(); - [window2.get() setBackingScaleFactor:2]; - - [[window2.get() contentView] addSubview:view.get()]; - WKContextPostMessageToInjectedBundle(context.get(), Util::toWK("GetBackingScaleFactor").get(), 0); - Util::run(&messageReceived); - messageReceived = false; - EXPECT_EQ(2, backingScaleFactor); - - WKPageSetCustomBackingScaleFactor(view.get().pageRef, 3); - WKContextPostMessageToInjectedBundle(context.get(), Util::toWK("GetBackingScaleFactor").get(), 0); - Util::run(&messageReceived); - messageReceived = false; - EXPECT_EQ(3, backingScaleFactor); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/mac/GetBackingScaleFactor_Bundle.mm b/Tools/TestWebKitAPI/Tests/WebKit2/mac/GetBackingScaleFactor_Bundle.mm deleted file mode 100644 index b8bceab48..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/mac/GetBackingScaleFactor_Bundle.mm +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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. - */ - -#import "config.h" - -#import "InjectedBundleTest.h" -#import "PlatformUtilities.h" -#import <WebKit2/WKBundlePage.h> -#import <assert.h> - -namespace TestWebKitAPI { - -class GetBackingScaleFactorTest : public InjectedBundleTest { -public: - GetBackingScaleFactorTest(const std::string&); - -private: - virtual void didCreatePage(WKBundleRef, WKBundlePageRef); - virtual void didReceiveMessage(WKBundleRef, WKStringRef messageName, WKTypeRef messageBody); - - WKBundlePageRef m_page; -}; - -static InjectedBundleTest::Register<GetBackingScaleFactorTest> registrar("GetBackingScaleFactorTest"); - -GetBackingScaleFactorTest::GetBackingScaleFactorTest(const std::string& identifier) - : InjectedBundleTest(identifier) - , m_page(0) -{ -} - -void GetBackingScaleFactorTest::didCreatePage(WKBundleRef, WKBundlePageRef page) -{ - assert(!m_page); - m_page = page; -} - -void GetBackingScaleFactorTest::didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody) -{ - if (!WKStringIsEqualToUTF8CString(messageName, "GetBackingScaleFactor")) - return; - - WKRetainPtr<WKDoubleRef> backingScaleFactor = adoptWK(WKDoubleCreate(WKBundlePageGetBackingScaleFactor(m_page))); - WKBundlePostMessage(bundle, Util::toWK("DidGetBackingScaleFactor").get(), backingScaleFactor.get()); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/modal-alerts-in-new-about-blank-window.html b/Tools/TestWebKitAPI/Tests/WebKit2/modal-alerts-in-new-about-blank-window.html new file mode 100644 index 000000000..f76cb650b --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/modal-alerts-in-new-about-blank-window.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<script> + +var newWindow = window.open("about:blank"); +newWindow.alert("Testing alert"); +newWindow.confirm("Testing confirm"); +newWindow.prompt("Testing prompt", "Default text"); + +</script> +</head> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/mouse-button-listener.html b/Tools/TestWebKitAPI/Tests/WebKit2/mouse-button-listener.html new file mode 100644 index 000000000..1fdbb1a95 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/mouse-button-listener.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<script> + var mouseButton = -1; + var menuType = "none"; + + function mouseDownHandler(event) + { + mouseButton = event.button; + event.preventDefault(); + } + + function pressedMouseButton() + { + return mouseButton; + } + + function contextMenuHandler(event) + { + menuType = "context"; + event.preventDefault(); + } + + function displayedMenu() + { + return menuType; + } + + addEventListener("mousedown", mouseDownHandler); + addEventListener("contextmenu", contextMenuHandler); +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/open-and-close-window.html b/Tools/TestWebKitAPI/Tests/WebKit2/open-and-close-window.html new file mode 100644 index 000000000..6ac778a9e --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/open-and-close-window.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> +<head> +<script> +if (document.location.search === "?close-window") + window.close(); +else + window.open("open-and-close-window.html?close-window"); +</script> +</head> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/should-open-external-schemes.html b/Tools/TestWebKitAPI/Tests/WebKit2/should-open-external-schemes.html new file mode 100644 index 000000000..299e4d66a --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/should-open-external-schemes.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<script> +function navigateToTelURL() +{ + window.location.href = "tel:+1 (408) 996-1010"; +} + +function navigateToTelURLInZeroTimer() +{ + window.setTimeout(navigateToTelURL, 0); +} + +function navigateToTelURLInNestedZeroTimer() +{ + window.setTimeout(navigateToTelURLInZeroTimer, 0); +} +</script> +</head> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/simple2.html b/Tools/TestWebKitAPI/Tests/WebKit2/simple2.html new file mode 100644 index 000000000..1dcbfddd2 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/simple2.html @@ -0,0 +1,5 @@ +<html> +<body> + Second simple HTML file. +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/simple3.html b/Tools/TestWebKitAPI/Tests/WebKit2/simple3.html new file mode 100644 index 000000000..786516e89 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/simple3.html @@ -0,0 +1,5 @@ +<html> +<body> + Third simple HTML file. +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/test-mse.mp4 b/Tools/TestWebKitAPI/Tests/WebKit2/test-mse.mp4 Binary files differnew file mode 100644 index 000000000..901c907e0 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/test-mse.mp4 diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/test.mp4 b/Tools/TestWebKitAPI/Tests/WebKit2/test.mp4 Binary files differnew file mode 100644 index 000000000..d278c8ad8 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/test.mp4 diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/webfont.html b/Tools/TestWebKitAPI/Tests/WebKit2/webfont.html new file mode 100644 index 000000000..008edd098 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2/webfont.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> +<style> +@font-face { + font-family: "WebFont"; + src: url("Ahem.ttf") format("truetype"); +} +</style> +</head> +<body> +<div style="font: 100px 'WebFont';">Hello</div> +This tests passes if there is no Web Process crash. +</body> +</html>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/win/DoNotCopyANullCFURLResponse.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/win/DoNotCopyANullCFURLResponse.cpp deleted file mode 100644 index 44a5b30d0..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/win/DoNotCopyANullCFURLResponse.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKURLResponseCF.h> -#include <wtf/RetainPtr.h> - -namespace TestWebKitAPI { - -TEST(WebKit2, DoNotCopyANullCFURLResponse) -{ - // Neither of these calls should cause a crash. - WKRetainPtr<WKURLResponseRef> nullWKResponse(AdoptWK, WKURLResponseCreateWithCFURLResponse(0)); - RetainPtr<CFURLResponseRef> nullCFResponse = adoptCF(WKURLResponseCopyCFURLResponse(kCFAllocatorDefault, nullWKResponse.get())); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/win/ResizeViewWhileHidden.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/win/ResizeViewWhileHidden.cpp deleted file mode 100644 index 32c8a0762..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/win/ResizeViewWhileHidden.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <WebKit2/WKRetainPtr.h> - -namespace TestWebKitAPI { - -static bool didFinishLoad; - -static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) -{ - didFinishLoad = true; -} - -static void setPageLoaderClient(WKPageRef page) -{ - WKPageLoaderClient loaderClient; - memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - - WKPageSetPageLoaderClient(page, &loaderClient); -} - -static void flushMessages(WKPageRef page) -{ - // In order to ensure all pending messages have been handled by the UI and web processes, we - // load a URL and wait for the load to finish. - - setPageLoaderClient(page); - - WKPageLoadURL(page, adoptWK(Util::createURLForResource("simple", "html")).get()); - Util::run(&didFinishLoad); - didFinishLoad = false; - - WKPageSetPageLoaderClient(page, 0); -} - -static bool timerFired; -static void CALLBACK timerCallback(HWND hwnd, UINT, UINT_PTR timerID, DWORD) -{ - ::KillTimer(hwnd, timerID); - timerFired = true; -} - -static void runForDuration(double seconds) -{ - ::SetTimer(0, 0, seconds * 1000, timerCallback); - Util::run(&timerFired); - timerFired = false; -} - -static void waitForBackingStoreUpdate(WKPageRef page) -{ - // Wait for the web process to handle the changes we just made, to perform a display (which - // happens on a timer), and to tell the UI process about the display (which updates the backing - // store). - // FIXME: It would be much less fragile (and maybe faster) to have an explicit way to wait - // until the backing store is updated. - runForDuration(0.5); - flushMessages(page); -} - -TEST(WebKit2, ResizeViewWhileHidden) -{ - WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - PlatformWebView webView(context.get()); - - HWND window = WKViewGetWindow(webView.platformView()); - - RECT originalRect; - ::GetClientRect(window, &originalRect); - RECT newRect = originalRect; - ::InflateRect(&newRect, 1, 1); - - // Show the WKView and resize it so that the WKView's backing store will be created. Ideally - // we'd have some more explicit way of forcing the backing store to be created. - ::ShowWindow(window, SW_SHOW); - webView.resizeTo(newRect.right - newRect.left, newRect.bottom - newRect.top); - - waitForBackingStoreUpdate(webView.page()); - - // Resize the window while hidden and show it again so that it will update its backing store at - // the new size. - ::ShowWindow(window, SW_HIDE); - webView.resizeTo(originalRect.right - originalRect.left, originalRect.bottom - originalRect.top); - ::ShowWindow(window, SW_SHOW); - - // Force the WKView to paint to try to trigger <http://webkit.org/b/54142>. - ::SendMessage(window, WM_PAINT, 0, 0); - - // In Debug builds without the fix for <http://webkit.org/b/54141>, the web process will assert - // at this point. - // FIXME: It would be good to have a way to check that our behavior is correct in Release - // builds, too! - waitForBackingStoreUpdate(webView.page()); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2/win/TranslateMessageGeneratesWMChar.cpp b/Tools/TestWebKitAPI/Tests/WebKit2/win/TranslateMessageGeneratesWMChar.cpp deleted file mode 100644 index 844499cd6..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2/win/TranslateMessageGeneratesWMChar.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#include "PlatformWebView.h" -#include "WindowMessageObserver.h" -#include <WebKit2/WKRetainPtr.h> - -namespace TestWebKitAPI { - -static bool didSeeWMChar; -static bool didNotHandleKeyEventCalled; - -static void didNotHandleKeyEventCallback(WKPageRef, WKNativeEventPtr event, const void*) -{ - if (event->message != WM_KEYDOWN) - return; - - // Don't call TranslateMessage() here so a WM_CHAR isn't generated. - didNotHandleKeyEventCalled = true; -} - -static void runAndWatchForWMChar(bool* done) -{ - while (!*done) { - MSG msg; - BOOL result = ::GetMessageW(&msg, 0, 0, 0); - if (!result || result == -1) - break; - - if (msg.message == WM_CHAR) - didSeeWMChar = true; - - if (Util::shouldTranslateMessage(msg)) - ::TranslateMessage(&msg); - - ::DispatchMessage(&msg); - } -} - -TEST(WebKit2, TranslateMessageGeneratesWMChar) -{ - WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - PlatformWebView webView(context.get()); - - webView.simulateAKeyDown(); - - // WebKit should call TranslateMessage() on the WM_KEYDOWN message to generate the WM_CHAR message. - runAndWatchForWMChar(&didSeeWMChar); - - didSeeWMChar = false; - - WKPageUIClient uiClient; - memset(&uiClient, 0, sizeof(uiClient)); - - uiClient.didNotHandleKeyEvent = didNotHandleKeyEventCallback; - WKPageSetPageUIClient(webView.page(), &uiClient); - - webView.simulateAKeyDown(); - - runAndWatchForWMChar(&didNotHandleKeyEventCalled); - - // WebKit should not have called TranslateMessage() on the WM_KEYDOWN message since we installed a didNotHandleKeyEvent callback. - EXPECT_FALSE(didSeeWMChar); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/mac/SyntheticBackingScaleFactorWindow.h b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.h index e83e653df..9d5b5d433 100644 --- a/Tools/TestWebKitAPI/mac/SyntheticBackingScaleFactorWindow.h +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,8 +23,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -@interface SyntheticBackingScaleFactorWindow : NSWindow { - CGFloat _backingScaleFactor; -} -- (void)setBackingScaleFactor:(CGFloat)scaleFactor; +@protocol ContentFilteringProtocol <NSObject> +- (void)checkIfPlatformFrameworksAreLoaded:(void (^)(BOOL parentalControlsLoaded, BOOL networkExtensionLoaded))completionHandler; @end diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.html new file mode 100644 index 000000000..a48eabb65 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ContentFiltering.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> +PASS +</body> +</html> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBMultiProcess-1.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBMultiProcess-1.html new file mode 100644 index 000000000..e3e8552a5 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBMultiProcess-1.html @@ -0,0 +1,46 @@ +<script> + +var request = window.indexedDB.deleteDatabase("IndexedDBMultiProcess"); +request.onsuccess = function(e) +{ + continueTest(); +} +request.onerror = function(e) +{ + // Unexpected error + window.webkit.messageHandlers.testHandler.postMessage('Error opening database'); +} + +function continueTest() +{ + var request = window.indexedDB.open("IndexedDBMultiProcess", 2); + + request.onsuccess = function() + { + window.webkit.messageHandlers.testHandler.postMessage('Success'); + } + + request.onerror = function() + { + // Unexpected error + window.webkit.messageHandlers.testHandler.postMessage('Error'); + } + + request.onupgradeneeded = function(event) + { + window.webkit.messageHandlers.testHandler.postMessage('UpgradeNeeded'); + + var store = event.target.result.createObjectStore("TestObjectStore"); + + event.target.transaction.oncomplete = function() { + window.webkit.messageHandlers.testHandler.postMessage('Transaction complete'); + } + + event.target.transaction.onerror = function() { + window.webkit.messageHandlers.testHandler.postMessage('Transaction errored!'); + } + + store.put("bar", "foo"); + } +} +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBMultiProcess-2.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBMultiProcess-2.html new file mode 100644 index 000000000..3e4e2d7da --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBMultiProcess-2.html @@ -0,0 +1,32 @@ +<script> + +var request = window.indexedDB.open("IndexedDBMultiProcess", 2); + +request.onsuccess = function(event) +{ + var req = event.target.result.transaction("TestObjectStore").objectStore("TestObjectStore").get("foo"); + + req.onsuccess = function(event) + { + window.webkit.messageHandlers.testHandler.postMessage('Value of foo: ' + req.result); + } + + req.onerror = function(event) + { + // Unexpected error + window.webkit.messageHandlers.testHandler.postMessage('Unexpected error'); + } +} + +request.onerror = function() +{ + // Unexpected error + window.webkit.messageHandlers.testHandler.postMessage('Unexpected error'); +} + +request.onupgradeneeded = function(event) +{ + // Unexpected upgrade needed + window.webkit.messageHandlers.testHandler.postMessage('Unexpected UpgradeNeeded'); +} +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBPersistence-1.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBPersistence-1.html new file mode 100644 index 000000000..62a1baf6f --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBPersistence-1.html @@ -0,0 +1,35 @@ +<script> + +var request = window.indexedDB.deleteDatabase("IndexedDBPersistence"); +request.onsuccess = function(e) +{ + continueTest(); +} +request.onerror = function(e) +{ + // Unexpected error + window.webkit.messageHandlers.testHandler.postMessage('Error'); +} + +function continueTest() +{ + var request = window.indexedDB.open("IndexedDBPersistence", 2); + + request.onsuccess = function() + { + window.webkit.messageHandlers.testHandler.postMessage('Success'); + + } + request.onerror = function() + { + // Unexpected error + window.webkit.messageHandlers.testHandler.postMessage('Error'); + } + request.onupgradeneeded = function(event) + { + window.webkit.messageHandlers.testHandler.postMessage('UpgradeNeeded'); + + event.target.result.createObjectStore("TestObjectStore"); + } +} +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBPersistence-2.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBPersistence-2.html new file mode 100644 index 000000000..d8ab125f2 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexedDBPersistence-2.html @@ -0,0 +1,22 @@ +<script> + +var request = window.indexedDB.open("IndexedDBPersistence"); + +request.onsuccess = function(event) +{ + window.webkit.messageHandlers.testHandler.postMessage(event.target.result.version + " " + event.target.result.objectStoreNames[0]); +} + +request.onerror = function() +{ + // Unexpected error + window.webkit.messageHandlers.testHandler.postMessage('Unexpected Error'); +} + +request.onupgradeneeded = function() +{ + // Unexpected error + window.webkit.messageHandlers.testHandler.postMessage('Unexpected UpgradeNeeded'); +} + +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LocalStorageNullEntries.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LocalStorageNullEntries.html new file mode 100644 index 000000000..9878f36ac --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LocalStorageNullEntries.html @@ -0,0 +1,6 @@ +<script> + +window.localStorage.key(0); +window.webkit.messageHandlers.testHandler.postMessage('DONE'); + +</script> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LocalStorageNullEntries.localstorage b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LocalStorageNullEntries.localstorage Binary files differnew file mode 100644 index 000000000..0b41b25c7 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LocalStorageNullEntries.localstorage diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LocalStorageNullEntries.localstorage-shm b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LocalStorageNullEntries.localstorage-shm Binary files differnew file mode 100644 index 000000000..fe9ac2845 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/LocalStorageNullEntries.localstorage-shm diff --git a/Tools/TestWebKitAPI/mac/SyntheticBackingScaleFactorWindow.m b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.h index 555cf985c..b72826817 100644 --- a/Tools/TestWebKitAPI/mac/SyntheticBackingScaleFactorWindow.m +++ b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/RemoteObjectRegistry.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,34 +23,26 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#import "config.h" -#import "SyntheticBackingScaleFactorWindow.h" +#import <WebKit/WKFoundation.h> -@implementation SyntheticBackingScaleFactorWindow +#if WK_API_ENABLED -- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation -{ - self = [super initWithContentRect:contentRect styleMask:windowStyle backing:bufferingType defer:deferCreation]; - if (!self) - return nil; +#import <WebKit/_WKRemoteObjectInterface.h> - _backingScaleFactor = 1; - return self; -} +@protocol RemoteObjectProtocol <NSObject> -- (void)setBackingScaleFactor:(CGFloat)scaleFactor -{ - _backingScaleFactor = scaleFactor; -} +- (void)sayHello:(NSString *)hello; +- (void)sayHello:(NSString *)hello completionHandler:(void (^)(NSString *))completionHandler; +- (void)selectionAndClickInformationForClickAtPoint:(NSValue *)pointValue completionHandler:(void (^)(NSDictionary *))completionHandler; -- (CGFloat)backingScaleFactor -{ - return _backingScaleFactor; -} +@end -- (CGFloat)userSpaceScaleFactor +static inline _WKRemoteObjectInterface *remoteObjectInterface() { - return _backingScaleFactor; -} + _WKRemoteObjectInterface *interface = [_WKRemoteObjectInterface remoteObjectInterfaceWithProtocol:@protocol(RemoteObjectProtocol)]; -@end + [interface setClasses:[NSSet setWithObjects:[NSDictionary class], [NSURL class], nil] forSelector:@selector(selectionAndClickInformationForClickAtPoint:completionHandler:) argumentIndex:0 ofReply:YES]; + + return interface; +} +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/AccessibilityTestServer.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/AccessibilityTestServer.cpp new file mode 100644 index 000000000..165fcfb6e --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/AccessibilityTestServer.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + +static void loadChangedCallback(WebKitWebView*, WebKitLoadEvent loadEvent, gpointer) +{ + // Send a message to the parent process when we're ready. + if (loadEvent == WEBKIT_LOAD_FINISHED) + g_print("OK"); +} + +int main(int argc, char** argv) +{ + // Make sure that the ATK bridge is loaded. + g_setenv("GTK_MODULES", "atk-bridge", TRUE); + + gtk_init(&argc, &argv); + + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + webkit_web_view_load_html(webView, + "<html>" + " <body>" + " <h1>This is a test</h1>" + " <p>This is a paragraph with some plain text.</p>" + " <p>This paragraph contains <a href=\"http://www.webkitgtk.org\">a link</a> in the middle.</p>" + " </body>" + "</html>", + 0); + + GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(webView)); + gtk_widget_show_all(window); + + g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), 0); + g_signal_connect(webView, "load-changed", G_CALLBACK(loadChangedCallback), 0); + + gtk_main(); +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/AutocleanupsTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/AutocleanupsTest.cpp new file mode 100644 index 000000000..a20cbfd73 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/AutocleanupsTest.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebProcessTest.h" +#include <webkit2/webkit-web-extension.h> + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC + +class AutocleanupsTest : public WebProcessTest { +public: + static std::unique_ptr<WebProcessTest> create() { return std::unique_ptr<WebProcessTest>(new AutocleanupsTest()); } + +private: + bool testWebProcessAutocleanups(WebKitWebPage* webPage) + { + // Transfer none + g_autoptr(WebKitWebPage) page = WEBKIT_WEB_PAGE(g_object_ref(G_OBJECT(webPage))); + g_assert(WEBKIT_IS_WEB_PAGE(page)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(page)); + + // Transfer none + g_autoptr(WebKitDOMDocument) document = WEBKIT_DOM_DOCUMENT(g_object_ref(G_OBJECT(webkit_web_page_get_dom_document(page)))); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + // Transfer full + g_autoptr(WebKitDOMDOMWindow) window = webkit_dom_document_get_default_view(document); + g_assert(WEBKIT_DOM_IS_DOM_WINDOW(window)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(window)); + + // Transfer full + g_autoptr(WebKitDOMRange) range = webkit_dom_document_create_range(document); + g_assert(WEBKIT_DOM_IS_RANGE(range)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(range)); + + return true; + } + + bool runTest(const char* testName, WebKitWebPage* page) override + { + if (!strcmp(testName, "web-process-autocleanups")) + return testWebProcessAutocleanups(page); + + g_assert_not_reached(); + return false; + } +}; + +static void __attribute__((constructor)) registerTests() +{ + REGISTER_TEST(AutocleanupsTest, "Autocleanups/web-process-autocleanups"); +} + +#endif // G_DEFINE_AUTOPTR_CLEANUP_FUNC diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt new file mode 100644 index 000000000..b0b473962 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt @@ -0,0 +1,135 @@ +set(TEST_LIBRARY_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/WebKit2GtkAPITests) +set(TEST_BINARY_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/TestWebKitAPI/WebKit2Gtk) +set(TEST_RESOURCES_DIR ${TEST_BINARY_DIR}/resources) +file(MAKE_DIRECTORY ${TEST_RESOURCES_DIR}) + +add_definitions( + -DWEBKIT_TEST_PLUGIN_DIR="${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugins" + -DWEBKIT_EXEC_PATH="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" + -DWEBKIT_SRC_DIR="${CMAKE_SOURCE_DIR}" + -DWEBKIT_TEST_WEB_EXTENSIONS_DIR="${TEST_LIBRARY_DIR}" + -DWEBKIT_INJECTED_BUNDLE_PATH="${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" +) + +include_directories( + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/Source + ${CMAKE_SOURCE_DIR}/Source/WTF + ${DERIVED_SOURCES_DIR} + ${DERIVED_SOURCES_WEBKIT2GTK_DIR} + ${FORWARDING_HEADERS_DIR} + ${FORWARDING_HEADERS_WEBKIT2GTK_DIR} + ${FORWARDING_HEADERS_WEBKIT2GTK_EXTENSION_DIR} + ${TOOLS_DIR}/TestWebKitAPI/gtk/WebKit2Gtk +) + +include_directories(SYSTEM + ${ATSPI_INCLUDE_DIRS} + ${GLIB_INCLUDE_DIRS} + ${GSTREAMER_INCLUDE_DIRS} + ${GTK3_INCLUDE_DIRS} + ${GTK_UNIX_PRINT_INCLUDE_DIRS} + ${LIBSOUP_INCLUDE_DIRS} +) + +add_library(WebKit2APITestCore STATIC + ${TOOLS_DIR}/TestWebKitAPI/gtk/WebKit2Gtk/LoadTrackingTest.cpp + ${TOOLS_DIR}/TestWebKitAPI/gtk/WebKit2Gtk/WebKitTestBus.cpp + ${TOOLS_DIR}/TestWebKitAPI/gtk/WebKit2Gtk/WebKitTestServer.cpp + ${TOOLS_DIR}/TestWebKitAPI/gtk/WebKit2Gtk/TestMain.cpp + ${TOOLS_DIR}/TestWebKitAPI/gtk/WebKit2Gtk/WebViewTest.cpp +) +target_link_libraries(WebKit2APITestCore WebKit2) + +add_custom_command( + OUTPUT ${TEST_RESOURCES_DIR}/webkit2gtk-tests-resources.gresource + DEPENDS resources/webkit2gtk-tests.gresource.xml + resources/link-title.js + COMMAND glib-compile-resources + --target=${TEST_RESOURCES_DIR}/webkit2gtk-tests-resources.gresource + --sourcedir=${CMAKE_SOURCE_DIR} + ${CMAKE_CURRENT_LIST_DIR}/resources/webkit2gtk-tests.gresource.xml +) + +add_custom_target(test-gresource-bundle + DEPENDS ${TEST_RESOURCES_DIR}/webkit2gtk-tests-resources.gresource +) + +macro(ADD_WK2_TEST_WEB_EXTENSION extension_name) + add_library(${extension_name} MODULE ${ARGN}) + add_dependencies(${extension_name} WebKit2) + set_property( + TARGET ${extension_name} + APPEND + PROPERTY COMPILE_DEFINITIONS WEBKIT2_COMPILATION + ) + set_target_properties(${extension_name} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${TEST_LIBRARY_DIR} + ) + target_link_libraries(${extension_name} + JavaScriptCore + WebKit2 + ${GLIB_LIBRARIES} + ) +endmacro() + +macro(ADD_WK2_TEST test_name) + add_executable(${test_name} ${ARGN}) + add_dependencies(${test_name} + test-gresource-bundle + WebExtensionTest + ) + target_link_libraries(${test_name} + JavaScriptCore + WebKit2 + WebKit2APITestCore + ${ATSPI_LIBRARIES} + ${GLIB_LIBRARIES} + ${GTK3_LIBRARIES} + ${GTK_UNIX_PRINT_LIBRARIES} + ${LIBSOUP_LIBRARIES} + ) + set_target_properties(${test_name} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${TEST_BINARY_DIR} + ) +endmacro() + +ADD_WK2_TEST_WEB_EXTENSION(WebExtensionTest WebExtensionTest.cpp) +ADD_WK2_TEST_WEB_EXTENSION(WebProcessTest AutocleanupsTest.cpp DOMNodeTest.cpp DOMNodeFilterTest.cpp DOMXPathNSResolverTest.cpp FrameTest.cpp WebProcessTest.cpp EditorTest.cpp) + +ADD_WK2_TEST(InspectorTestServer InspectorTestServer.cpp) +ADD_WK2_TEST(TestAuthentication TestAuthentication.cpp) +ADD_WK2_TEST(TestAutocleanups TestAutocleanups.cpp) +ADD_WK2_TEST(TestBackForwardList TestBackForwardList.cpp) +ADD_WK2_TEST(TestContextMenu TestContextMenu.cpp) +ADD_WK2_TEST(TestCookieManager TestCookieManager.cpp) +ADD_WK2_TEST(TestDOMNode TestDOMNode.cpp) +ADD_WK2_TEST(TestDOMNodeFilter TestDOMNodeFilter.cpp) +ADD_WK2_TEST(TestDOMXPathNSResolver TestDOMXPathNSResolver.cpp) +ADD_WK2_TEST(TestDownloads TestDownloads.cpp) +ADD_WK2_TEST(TestWebKitFaviconDatabase TestWebKitFaviconDatabase.cpp) +ADD_WK2_TEST(TestWebKitFindController TestWebKitFindController.cpp) +ADD_WK2_TEST(TestFrame TestFrame.cpp) +ADD_WK2_TEST(TestInspector TestInspector.cpp) +ADD_WK2_TEST(TestInspectorServer TestInspectorServer.cpp) +ADD_WK2_TEST(TestLoaderClient TestLoaderClient.cpp) +ADD_WK2_TEST(TestMultiprocess TestMultiprocess.cpp) +ADD_WK2_TEST(TestPrinting TestPrinting.cpp) +ADD_WK2_TEST(TestResources TestResources.cpp) +ADD_WK2_TEST(TestSSL TestSSL.cpp) +ADD_WK2_TEST(TestUIClient TestUIClient.cpp) +ADD_WK2_TEST(TestWebExtensions TestWebExtensions.cpp) +ADD_WK2_TEST(TestWebKitPolicyClient TestWebKitPolicyClient.cpp) +ADD_WK2_TEST(TestWebKitSettings TestWebKitSettings.cpp) +ADD_WK2_TEST(TestWebKitVersion TestWebKitVersion.cpp) +ADD_WK2_TEST(TestWebViewEditor TestWebViewEditor.cpp) +ADD_WK2_TEST(TestWebKitWebContext TestWebKitWebContext.cpp) +ADD_WK2_TEST(TestWebKitWebView TestWebKitWebView.cpp) +ADD_WK2_TEST(TestWebKitUserContentManager TestWebKitUserContentManager.cpp) +ADD_WK2_TEST(TestEditor TestEditor.cpp) +ADD_WK2_TEST(TestConsoleMessage TestConsoleMessage.cpp) + +if (ATSPI_FOUND) + ADD_WK2_TEST(AccessibilityTestServer AccessibilityTestServer.cpp) + ADD_WK2_TEST(TestWebKitAccessibility TestWebKitAccessibility.cpp) +endif () diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMDOMWindowTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMDOMWindowTest.cpp new file mode 100644 index 000000000..fc8cefb52 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMDOMWindowTest.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebProcessTest.h" +#include <gio/gio.h> +#include <webkit2/webkit-web-extension.h> +#include <wtf/RunLoop.h> + +class WebKitDOMDOMWindowTest; +static gboolean loadedCallback(WebKitDOMDOMWindow*, WebKitDOMEvent*, WebKitDOMDOMWindowTest*); +static gboolean clickedCallback(WebKitDOMDOMWindow*, WebKitDOMEvent*, WebKitDOMDOMWindowTest*); + +class WebKitDOMDOMWindowTest : public WebProcessTest { +public: + static std::unique_ptr<WebProcessTest> create() { return std::make_unique<WebKitDOMDOMWindowTest>(); } + +private: + guint64 webPageFromArgs(GVariant* args) + { + GVariantIter iter; + g_variant_iter_init(&iter, args); + + const char* key; + GVariant* value; + while (g_variant_iter_loop(&iter, "{&sv}", &key, &value)) { + if (!strcmp(key, "pageID") && g_variant_classify(value) == G_VARIANT_CLASS_UINT64) + return g_variant_get_uint64(value); + } + + g_assert_not_reached(); + return 0; + } + + bool testSignals(WebKitWebExtension* extension, GVariant* args) + { + notify("ready", ""); + + WebKitWebPage* page = webkit_web_extension_get_page(extension, webPageFromArgs(args)); + g_assert(WEBKIT_IS_WEB_PAGE(page)); + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + + WebKitDOMDOMWindow* domWindow = webkit_dom_document_get_default_view(document); + g_assert(domWindow); + + // The "load" WebKitDOMDOMWindow signal is issued before this test is + // called. There's no way to capture it here. We simply assume that + // the document is loaded and notify the uiprocess accordingly + // notify("loaded", ""); + + webkit_dom_event_target_add_event_listener( + WEBKIT_DOM_EVENT_TARGET(domWindow), + "load", + G_CALLBACK(loadedCallback), + false, + this); + + // loadedCallback() will stop this loop + RunLoop::run(); + + document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + + WebKitDOMElement* element = webkit_dom_document_get_element_by_id(document, "test"); + g_assert(element); + + webkit_dom_event_target_add_event_listener( + WEBKIT_DOM_EVENT_TARGET(element), + "click", + G_CALLBACK(clickedCallback), + false, + this); + + // The "click" action will be issued in the uiprocess and that will + // trigger the dom event here. + // clickedCallback() will stop this loop + RunLoop::run(); + + return true; + } + + bool testDispatchEvent(WebKitWebExtension* extension, GVariant* args) + { + notify("ready", ""); + + WebKitWebPage* page = webkit_web_extension_get_page(extension, webPageFromArgs(args)); + g_assert(WEBKIT_IS_WEB_PAGE(page)); + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + + WebKitDOMDOMWindow* domWindow = webkit_dom_document_get_default_view(document); + g_assert(domWindow); + + // The "load" WebKitDOMDOMWindow signal is issued before this test is + // called. There's no way to capture it here. We simply assume that + // the document is loaded and notify the uiprocess accordingly + // notify("loaded", ""); + + webkit_dom_event_target_add_event_listener( + WEBKIT_DOM_EVENT_TARGET(domWindow), + "load", + G_CALLBACK(loadedCallback), + false, + this); + + // loadedCallback() will stop this loop + RunLoop::run(); + + document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + + WebKitDOMElement* element = webkit_dom_document_get_element_by_id(document, "test"); + g_assert(element); + + WebKitDOMEvent* event = webkit_dom_document_create_event(document, "MouseEvent", 0); + g_assert(event); + g_assert(WEBKIT_DOM_IS_EVENT(event)); + g_assert(WEBKIT_DOM_IS_MOUSE_EVENT(event)); + + glong clientX, clientY; + clientX = webkit_dom_element_get_client_left(element); + clientY = webkit_dom_element_get_client_top(element); + + webkit_dom_event_target_add_event_listener( + WEBKIT_DOM_EVENT_TARGET(element), + "click", + G_CALLBACK(clickedCallback), + false, + this); + + webkit_dom_mouse_event_init_mouse_event(WEBKIT_DOM_MOUSE_EVENT(event), + "click", TRUE, TRUE, + domWindow, 0, 0, 0, clientX, clientY, + FALSE, FALSE, FALSE, FALSE, + 1, WEBKIT_DOM_EVENT_TARGET(element)); + + webkit_dom_event_target_dispatch_event(WEBKIT_DOM_EVENT_TARGET(element), event, 0); + + // clickedCallback() will stop this loop + RunLoop::run(); + + return true; + } + + bool testGetComputedStyle(WebKitWebExtension* extension, GVariant* args) + { + WebKitWebPage* page = webkit_web_extension_get_page(extension, webPageFromArgs(args)); + g_assert(WEBKIT_IS_WEB_PAGE(page)); + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + WebKitDOMDOMWindow* domWindow = webkit_dom_document_get_default_view(document); + g_assert(domWindow); + WebKitDOMElement* element = webkit_dom_document_get_element_by_id(document, "test"); + g_assert(element); + g_assert(WEBKIT_DOM_IS_ELEMENT(element)); + WebKitDOMCSSStyleDeclaration* cssStyle = webkit_dom_dom_window_get_computed_style(domWindow, element, 0); + gchar* fontSize = webkit_dom_css_style_declaration_get_property_value(cssStyle, "font-size"); + g_assert_cmpstr(fontSize, ==, "16px"); + + return true; + } + + virtual bool runTest(const char* testName, WebKitWebExtension* extension, GVariant* args) + { + if (!strcmp(testName, "signals")) + return testSignals(extension, args); + if (!strcmp(testName, "dispatch-event")) + return testDispatchEvent(extension, args); + if (!strcmp(testName, "get-computed-style")) + return testGetComputedStyle(extension, args); + + g_assert_not_reached(); + return false; + } +}; + +static void __attribute__((constructor)) registerTests() +{ + REGISTER_TEST(WebKitDOMDOMWindowTest, "WebKitDOMDOMWindow/signals"); + REGISTER_TEST(WebKitDOMDOMWindowTest, "WebKitDOMDOMWindow/dispatch-event"); + REGISTER_TEST(WebKitDOMDOMWindowTest, "WebKitDOMDOMWindow/get-computed-style"); +} + +static gboolean loadedCallback(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, WebKitDOMDOMWindowTest* test) +{ + test->notify("loaded", ""); + + // Stop the loop and let testSignals() or testDispatchEvent() continue its course + RunLoop::current().stop(); + + return FALSE; +} + +static gboolean clickedCallback(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, WebKitDOMDOMWindowTest* test) +{ + test->notify("clicked", ""); + test->notify("finish", ""); + + // Stop the loop and let testSignals() or testDispatchEvent() continue its course + RunLoop::current().stop(); + + return FALSE; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeFilterTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeFilterTest.cpp new file mode 100644 index 000000000..0f18d1f31 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeFilterTest.cpp @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebProcessTest.h" +#include <gio/gio.h> +#include <webkit2/webkit-web-extension.h> +#include <wtf/glib/GUniquePtr.h> + +typedef struct _WebKitNodeFilter { + GObject parent; +} WebKitNodeFilter; + +typedef struct _WebKitNodeFilterClass { + GObjectClass parentClass; +} WebKitNodeFilterClass; + +static short webkitNodeFilterAcceptNode(WebKitDOMNodeFilter*, WebKitDOMNode* node) +{ + // Filter out input elements. + return WEBKIT_DOM_IS_HTML_INPUT_ELEMENT(node) ? WEBKIT_DOM_NODE_FILTER_REJECT : WEBKIT_DOM_NODE_FILTER_ACCEPT; +} + +static void webkitNodeFilterDOMNodeFilterIfaceInit(WebKitDOMNodeFilterIface* iface) +{ + iface->accept_node = webkitNodeFilterAcceptNode; +} + +G_DEFINE_TYPE_WITH_CODE(WebKitNodeFilter, webkit_node_filter, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(WEBKIT_DOM_TYPE_NODE_FILTER, webkitNodeFilterDOMNodeFilterIfaceInit)) + +static void webkit_node_filter_init(WebKitNodeFilter*) +{ +} + +static void webkit_node_filter_class_init(WebKitNodeFilterClass*) +{ +} + +static const char* expectedNodesAll[] = { "HTML", "HEAD", "TITLE", "#text", "BODY", "INPUT", "INPUT", "BR" }; +static const char* expectedNodesNoInput[] = { "HTML", "HEAD", "TITLE", "#text", "BODY", "BR" }; +static const char* expectedElementsNoInput[] = { "HTML", "HEAD", "TITLE", "BODY", "BR" }; + +class WebKitDOMNodeFilterTest : public WebProcessTest { +public: + static std::unique_ptr<WebProcessTest> create() { return std::unique_ptr<WebProcessTest>(new WebKitDOMNodeFilterTest()); } + +private: + bool testTreeWalker(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + WebKitDOMElement* root = webkit_dom_document_get_element_by_id(document, "root"); + g_assert(WEBKIT_DOM_IS_NODE(root)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(root)); + + // No filter. + GRefPtr<WebKitDOMTreeWalker> walker = adoptGRef(webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr)); + g_assert(WEBKIT_DOM_IS_TREE_WALKER(walker.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(walker.get())); + g_assert(!webkit_dom_tree_walker_get_filter(walker.get())); + + unsigned i = 0; + for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker.get()), ++i) { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesAll)); + GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); + g_assert_cmpstr(nodeName.get(), ==, expectedNodesAll[i]); + } + g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedNodesAll)); + + // Input elements filter. + GRefPtr<WebKitDOMNodeFilter> filter = adoptGRef(static_cast<WebKitDOMNodeFilter*>(g_object_new(webkit_node_filter_get_type(), nullptr))); + walker = adoptGRef(webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, filter.get(), FALSE, nullptr)); + g_assert(WEBKIT_DOM_IS_TREE_WALKER(walker.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(filter.get())); + g_assert(webkit_dom_tree_walker_get_filter(walker.get()) == filter.get()); + + i = 0; + for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker.get()), ++i) { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesNoInput)); + GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); + g_assert_cmpstr(nodeName.get(), ==, expectedNodesNoInput[i]); + } + g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedNodesNoInput)); + + // Show only elements, reusing the input filter. + walker = adoptGRef(webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ELEMENT, filter.get(), FALSE, nullptr)); + g_assert(WEBKIT_DOM_IS_TREE_WALKER(walker.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(walker.get())); + g_assert(webkit_dom_tree_walker_get_filter(walker.get()) == filter.get()); + + i = 0; + for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker.get()), ++i) { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedElementsNoInput)); + GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); + g_assert_cmpstr(nodeName.get(), ==, expectedElementsNoInput[i]); + } + g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedElementsNoInput)); + + return true; + } + + bool testNodeIterator(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + WebKitDOMElement* root = webkit_dom_document_get_element_by_id(document, "root"); + g_assert(WEBKIT_DOM_IS_NODE(root)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(root)); + + // No filter. + GRefPtr<WebKitDOMNodeIterator> iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr)); + g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get())); + g_assert(!webkit_dom_node_iterator_get_filter(iter.get())); + + unsigned i = 0; + while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter.get(), nullptr)) { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesAll)); + GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); + g_assert_cmpstr(nodeName.get(), ==, expectedNodesAll[i]); + i++; + } + g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedNodesAll)); + + // Input elements filter. + GRefPtr<WebKitDOMNodeFilter> filter = adoptGRef(static_cast<WebKitDOMNodeFilter*>(g_object_new(webkit_node_filter_get_type(), nullptr))); + iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, filter.get(), FALSE, nullptr)); + g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get())); + g_assert(webkit_dom_node_iterator_get_filter(iter.get()) == filter.get()); + + i = 0; + while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter.get(), nullptr)) { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesNoInput)); + GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); + g_assert_cmpstr(nodeName.get(), ==, expectedNodesNoInput[i]); + i++; + } + g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedNodesNoInput)); + + // Show only elements, reusing the input filter. + iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ELEMENT, filter.get(), FALSE, nullptr)); + g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get())); + g_assert(webkit_dom_node_iterator_get_filter(iter.get()) == filter.get()); + + i = 0; + while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter.get(), nullptr)) { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedElementsNoInput)); + GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node)); + g_assert_cmpstr(nodeName.get(), ==, expectedElementsNoInput[i]); + i++; + } + g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedElementsNoInput)); + + return true; + } + + bool runTest(const char* testName, WebKitWebPage* page) override + { + if (!strcmp(testName, "tree-walker")) + return testTreeWalker(page); + if (!strcmp(testName, "node-iterator")) + return testNodeIterator(page); + + g_assert_not_reached(); + return false; + } +}; + +static void __attribute__((constructor)) registerTests() +{ + REGISTER_TEST(WebKitDOMNodeFilterTest, "WebKitDOMNodeFilter/tree-walker"); + REGISTER_TEST(WebKitDOMNodeFilterTest, "WebKitDOMNodeFilter/node-iterator"); +} + + diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeTest.cpp new file mode 100644 index 000000000..9d57b42d2 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMNodeTest.cpp @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebProcessTest.h" +#include <gio/gio.h> +#include <webkit2/webkit-web-extension.h> +#include <wtf/glib/GUniquePtr.h> + +class WebKitDOMNodeTest : public WebProcessTest { +public: + static std::unique_ptr<WebProcessTest> create() { return std::unique_ptr<WebKitDOMNodeTest>(new WebKitDOMNodeTest()); } + +private: + bool testHierarchyNavigation(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + WebKitDOMHTMLHeadElement* head = webkit_dom_document_get_head(document); + g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(head)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(head)); + + // Title, head's child. + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(head))); + GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(head))); + g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); + g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1); + WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), 0); + g_assert(WEBKIT_DOM_IS_HTML_TITLE_ELEMENT(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + + // Body, Head sibling. + node = webkit_dom_node_get_next_sibling(WEBKIT_DOM_NODE(head)); + g_assert(WEBKIT_DOM_IS_HTML_BODY_ELEMENT(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + WebKitDOMHTMLBodyElement* body = WEBKIT_DOM_HTML_BODY_ELEMENT(node); + + // There is no third sibling + g_assert(!webkit_dom_node_get_next_sibling(node)); + + // Body's previous sibling is Head. + node = webkit_dom_node_get_previous_sibling(WEBKIT_DOM_NODE(body)); + g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + + // Body has 3 children. + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); + list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); + g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); + unsigned long length = webkit_dom_node_list_get_length(list.get()); + g_assert_cmpint(length, ==, 3); + + // The three of them are P tags. + for (unsigned long i = 0; i < length; i++) { + node = webkit_dom_node_list_item(list.get(), i); + g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + } + + // Go backwards + unsigned i; + for (i = 0; node; node = webkit_dom_node_get_previous_sibling(node), i++) { } + g_assert_cmpint(i, ==, 3); + + return true; + } + + bool testInsertion(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + WebKitDOMHTMLElement* body = webkit_dom_document_get_body(document); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(body)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(body)); + + // Body shouldn't have any children at this point. + g_assert(!webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); + + // The value of a non-existent attribute should be null, not an empty string + g_assert(!webkit_dom_html_body_element_get_background(WEBKIT_DOM_HTML_BODY_ELEMENT(body))); + + // Insert one P element. + WebKitDOMElement* p = webkit_dom_document_create_element(document, "P", 0); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(p)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p)); + webkit_dom_node_append_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), 0); + + // Now it should have one, the same that we inserted. + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); + GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); + g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); + g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1); + WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), 0); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node)); + + // Replace the P tag with a DIV tag. + WebKitDOMElement* div = webkit_dom_document_create_element(document, "DIV", 0); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(div)); + webkit_dom_node_replace_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(p), 0); + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); + list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); + g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); + g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1); + node = webkit_dom_node_list_item(list.get(), 0); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node)); + + // Now remove the tag. + webkit_dom_node_remove_child(WEBKIT_DOM_NODE(body), node, 0); + list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); + g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); + g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 0); + + // Test insert before. If refChild is null, insert newChild as last element of parent. + div = webkit_dom_document_create_element(document, "DIV", 0); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(div)); + webkit_dom_node_insert_before(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), 0, 0); + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); + list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); + g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); + g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 1); + node = webkit_dom_node_list_item(list.get(), 0); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node)); + + // Now insert a 'p' before 'div'. + p = webkit_dom_document_create_element(document, "P", 0); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(p)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p)); + webkit_dom_node_insert_before(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), WEBKIT_DOM_NODE(div), 0); + g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body))); + list = adoptGRef(webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body))); + g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); + g_assert_cmpint(webkit_dom_node_list_get_length(list.get()), ==, 2); + node = webkit_dom_node_list_item(list.get(), 0); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node)); + node = webkit_dom_node_list_item(list.get(), 1); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node)); + + return true; + } + + bool testTagNamesNodeList(WebKitWebPage* page) + { + static const char* expectedTagNames[] = { "HTML", "HEAD", "BODY", "VIDEO", "SOURCE", "VIDEO", "SOURCE", "INPUT" }; + + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + GRefPtr<WebKitDOMNodeList> list = adoptGRef(webkit_dom_document_query_selector_all(document, "*", nullptr)); + g_assert(WEBKIT_DOM_IS_NODE_LIST(list.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(list.get())); + gulong nodeCount = webkit_dom_node_list_get_length(list.get()); + g_assert_cmpuint(nodeCount, ==, G_N_ELEMENTS(expectedTagNames)); + for (unsigned i = 0; i < nodeCount; i++) { + WebKitDOMNode* node = webkit_dom_node_list_item(list.get(), i); + g_assert(WEBKIT_DOM_IS_NODE(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + GUniquePtr<char> tagName(webkit_dom_node_get_node_name(node)); + g_assert_cmpstr(tagName.get(), ==, expectedTagNames[i]); + } + + return true; + } + + bool testTagNamesHTMLCollection(WebKitWebPage* page) + { + static const char* expectedTagNames[] = { "HTML", "HEAD", "BODY", "VIDEO", "SOURCE", "VIDEO", "SOURCE", "INPUT" }; + + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + GRefPtr<WebKitDOMHTMLCollection> collection = adoptGRef(webkit_dom_document_get_elements_by_tag_name_as_html_collection(document, "*")); + g_assert(WEBKIT_DOM_IS_HTML_COLLECTION(collection.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(collection.get())); + gulong nodeCount = webkit_dom_html_collection_get_length(collection.get()); + g_assert_cmpuint(nodeCount, ==, G_N_ELEMENTS(expectedTagNames)); + for (unsigned i = 0; i < nodeCount; i++) { + WebKitDOMNode* node = webkit_dom_html_collection_item(collection.get(), i); + g_assert(WEBKIT_DOM_IS_NODE(node)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node)); + GUniquePtr<char> tagName(webkit_dom_node_get_node_name(node)); + g_assert_cmpstr(tagName.get(), ==, expectedTagNames[i]); + } + + return true; + } + + bool testDOMCache(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + // DOM objects already in the document should be automatically handled by the cache. + WebKitDOMElement* div = webkit_dom_document_get_element_by_id(document, "container"); + g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(div)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(div)); + + // Get the same elment twice should return the same pointer. + g_assert(div == webkit_dom_document_get_element_by_id(document, "container")); + + // A new DOM object created that is derived from Node should be automatically handled by the cache. + WebKitDOMElement* p = webkit_dom_document_create_element(document, "P", nullptr); + g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(p)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p)); + + // A new DOM object created that isn't derived from Node should be manually handled. + GRefPtr<WebKitDOMNodeIterator> iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr)); + g_assert(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get())); + + // We can also manually handle a DOM object handled by the cache. + GRefPtr<WebKitDOMElement> p2 = adoptGRef(webkit_dom_document_create_element(document, "P", nullptr)); + g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(p2.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p2.get())); + + // Manually handling a DOM object owned by the cache shouldn't crash when the cache has more than one reference. + GRefPtr<WebKitDOMElement> p3 = adoptGRef(webkit_dom_document_create_element(document, "P", nullptr)); + g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(p3.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(p3.get())); + webkit_dom_node_append_child(WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(p3.get()), nullptr); + + // DOM objects removed from the document are also correctly handled by the cache. + WebKitDOMElement* a = webkit_dom_document_create_element(document, "A", nullptr); + g_assert(WEBKIT_DOM_IS_ELEMENT(a)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(a)); + webkit_dom_node_remove_child(WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(a), nullptr); + + return true; + } + + bool runTest(const char* testName, WebKitWebPage* page) override + { + if (!strcmp(testName, "hierarchy-navigation")) + return testHierarchyNavigation(page); + if (!strcmp(testName, "insertion")) + return testInsertion(page); + if (!strcmp(testName, "tag-names-node-list")) + return testTagNamesNodeList(page); + if (!strcmp(testName, "tag-names-html-collection")) + return testTagNamesHTMLCollection(page); + if (!strcmp(testName, "dom-cache")) + return testDOMCache(page); + + g_assert_not_reached(); + return false; + } +}; + +static void __attribute__((constructor)) registerTests() +{ + REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/hierarchy-navigation"); + REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/insertion"); + REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/tag-names-node-list"); + REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/tag-names-html-collection"); + REGISTER_TEST(WebKitDOMNodeTest, "WebKitDOMNode/dom-cache"); +} + + diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMXPathNSResolverTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMXPathNSResolverTest.cpp new file mode 100644 index 000000000..110677e41 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/DOMXPathNSResolverTest.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebProcessTest.h" +#include <gio/gio.h> +#include <webkit2/webkit-web-extension.h> +#include <wtf/glib/GUniquePtr.h> + +typedef struct _WebKitXPathNSResolver { + GObject parent; +} WebKitXPathNSResolver; + +typedef struct _WebKitXPathNSResolverClass { + GObjectClass parentClass; +} WebKitXPathNSResolverClass; + +static char* webkitXPathNSResolverLookupNamespaceURI(WebKitDOMXPathNSResolver* resolver, const char* prefix) +{ + if (!g_strcmp0(prefix, "foo")) + return g_strdup("http://www.example.com"); + + return nullptr; +} + +static void webkitXPathNSResolverDOMXPathNSResolverIfaceInit(WebKitDOMXPathNSResolverIface* iface) +{ + iface->lookup_namespace_uri = webkitXPathNSResolverLookupNamespaceURI; +} + +G_DEFINE_TYPE_WITH_CODE(WebKitXPathNSResolver, webkit_xpath_ns_resolver, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(WEBKIT_DOM_TYPE_XPATH_NS_RESOLVER, webkitXPathNSResolverDOMXPathNSResolverIfaceInit)) + +static void webkit_xpath_ns_resolver_init(WebKitXPathNSResolver*) +{ +} + +static void webkit_xpath_ns_resolver_class_init(WebKitXPathNSResolverClass*) +{ +} + +class WebKitDOMXPathNSResolverTest : public WebProcessTest { +public: + static std::unique_ptr<WebProcessTest> create() { return std::unique_ptr<WebProcessTest>(new WebKitDOMXPathNSResolverTest()); } + +private: + void evaluateFooChildTextAndCheckResult(WebKitDOMDocument* document, WebKitDOMXPathNSResolver* resolver) + { + WebKitDOMElement* documentElement = webkit_dom_document_get_document_element(document); + g_assert(WEBKIT_DOM_IS_ELEMENT(documentElement)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(documentElement)); + + GRefPtr<WebKitDOMXPathResult> result = adoptGRef(webkit_dom_document_evaluate(document, "foo:child/text()", WEBKIT_DOM_NODE(documentElement), resolver, WEBKIT_DOM_XPATH_RESULT_ORDERED_NODE_ITERATOR_TYPE, nullptr, nullptr)); + g_assert(WEBKIT_DOM_IS_XPATH_RESULT(result.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(result.get())); + + WebKitDOMNode* nodeResult = webkit_dom_xpath_result_iterate_next(result.get(), nullptr); + g_assert(WEBKIT_DOM_IS_NODE(nodeResult)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(nodeResult)); + + GUniquePtr<char> nodeValue(webkit_dom_node_get_node_value(nodeResult)); + g_assert_cmpstr(nodeValue.get(), ==, "SUCCESS"); + } + + bool testXPathNSResolverNative(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + GRefPtr<WebKitDOMXPathNSResolver> resolver = adoptGRef(webkit_dom_document_create_ns_resolver(document, WEBKIT_DOM_NODE(webkit_dom_document_get_document_element(document)))); + g_assert(WEBKIT_DOM_IS_XPATH_NS_RESOLVER(resolver.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(resolver.get())); + evaluateFooChildTextAndCheckResult(document, resolver.get()); + + return true; + } + + bool testXPathNSResolverCustom(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document)); + + GRefPtr<WebKitDOMXPathNSResolver> resolver = adoptGRef(WEBKIT_DOM_XPATH_NS_RESOLVER(g_object_new(webkit_xpath_ns_resolver_get_type(), nullptr))); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(resolver.get())); + evaluateFooChildTextAndCheckResult(document, resolver.get()); + + return true; + } + + bool runTest(const char* testName, WebKitWebPage* page) override + { + if (!strcmp(testName, "native")) + return testXPathNSResolverNative(page); + if (!strcmp(testName, "custom")) + return testXPathNSResolverCustom(page); + + g_assert_not_reached(); + return false; + } +}; + +static void __attribute__((constructor)) registerTests() +{ + REGISTER_TEST(WebKitDOMXPathNSResolverTest, "WebKitDOMXPathNSResolver/native"); + REGISTER_TEST(WebKitDOMXPathNSResolverTest, "WebKitDOMXPathNSResolver/custom"); +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/EditorTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/EditorTest.cpp new file mode 100644 index 000000000..873344271 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/EditorTest.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2015 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebProcessTest.h" +#include <webkit2/webkit-web-extension.h> + +#define WEBKIT_DOM_USE_UNSTABLE_API +#include <webkitdom/WebKitDOMDOMSelection.h> +#include <webkitdom/WebKitDOMDOMWindowUnstable.h> + +class WebKitWebEditorTest : public WebProcessTest { +public: + static std::unique_ptr<WebProcessTest> create() { return std::unique_ptr<WebProcessTest>(new WebKitWebEditorTest()); } + +private: + static void selectionChangedCallback(bool* selectionChanged) + { + *selectionChanged = true; + } + + void testSelectionSelectAll(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + + webkit_dom_document_exec_command(document, "SelectAll", false, ""); + } + + void testSelectionCollapse(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + GRefPtr<WebKitDOMDOMWindow> domWindow = adoptGRef(webkit_dom_document_get_default_view(document)); + g_assert(WEBKIT_DOM_IS_DOM_WINDOW(domWindow.get())); + GRefPtr<WebKitDOMDOMSelection> domSelection = adoptGRef(webkit_dom_dom_window_get_selection(domWindow.get())); + g_assert(WEBKIT_DOM_IS_DOM_SELECTION(domSelection.get())); + + webkit_dom_dom_selection_collapse_to_start(domSelection.get(), nullptr); + } + + void testSelectionModifyMove(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + GRefPtr<WebKitDOMDOMWindow> domWindow = adoptGRef(webkit_dom_document_get_default_view(document)); + g_assert(WEBKIT_DOM_IS_DOM_WINDOW(domWindow.get())); + GRefPtr<WebKitDOMDOMSelection> domSelection = adoptGRef(webkit_dom_dom_window_get_selection(domWindow.get())); + g_assert(WEBKIT_DOM_IS_DOM_SELECTION(domSelection.get())); + + webkit_dom_dom_selection_modify(domSelection.get(), "move", "forward", "character"); + } + + void testSelectionModifyExtend(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + GRefPtr<WebKitDOMDOMWindow> domWindow = adoptGRef(webkit_dom_document_get_default_view(document)); + g_assert(WEBKIT_DOM_IS_DOM_WINDOW(domWindow.get())); + GRefPtr<WebKitDOMDOMSelection> domSelection = adoptGRef(webkit_dom_dom_window_get_selection(domWindow.get())); + g_assert(WEBKIT_DOM_IS_DOM_SELECTION(domSelection.get())); + + webkit_dom_dom_selection_modify(domSelection.get(), "extend", "forward", "word"); + } + + void testSelectionUnselect(WebKitWebPage* page) + { + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + g_assert(WEBKIT_DOM_IS_DOCUMENT(document)); + + webkit_dom_document_exec_command(document, "Unselect", false, ""); + } + + bool runTest(const char* testName, WebKitWebPage* page) override + { + if (!strcmp(testName, "selection-changed")) { + bool selectionChanged = false; + + WebKitWebEditor* editor = webkit_web_page_get_editor(page); + g_assert(WEBKIT_IS_WEB_EDITOR(editor)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(editor)); + g_signal_connect_swapped(editor, "selection-changed", G_CALLBACK(selectionChangedCallback), &selectionChanged); + + testSelectionSelectAll(page); + g_assert(selectionChanged); + + selectionChanged = false; + testSelectionCollapse(page); + g_assert(selectionChanged); + + selectionChanged = false; + testSelectionModifyMove(page); + g_assert(selectionChanged); + + selectionChanged = false; + testSelectionModifyExtend(page); + g_assert(selectionChanged); + + selectionChanged = false; + testSelectionUnselect(page); + g_assert(selectionChanged); + + return true; + } + + g_assert_not_reached(); + return false; + } +}; + +static void __attribute__((constructor)) registerTests() +{ + REGISTER_TEST(WebKitWebEditorTest, "WebKitWebEditor/selection-changed"); +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/FrameTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/FrameTest.cpp new file mode 100644 index 000000000..a32d3e52f --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/FrameTest.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebProcessTest.h" +#include <gio/gio.h> +#include <webkit2/webkit-web-extension.h> + +class WebKitFrameTest : public WebProcessTest { +public: + static std::unique_ptr<WebProcessTest> create() { return std::unique_ptr<WebProcessTest>(new WebKitFrameTest()); } + +private: + bool testMainFrame(WebKitWebPage* page) + { + WebKitFrame* frame = webkit_web_page_get_main_frame(page); + g_assert(WEBKIT_IS_FRAME(frame)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(frame)); + g_assert(webkit_frame_is_main_frame(frame)); + + return true; + } + + bool testURI(WebKitWebPage* page) + { + WebKitFrame* frame = webkit_web_page_get_main_frame(page); + g_assert(WEBKIT_IS_FRAME(frame)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(frame)); + g_assert_cmpstr(webkit_web_page_get_uri(page), ==, webkit_frame_get_uri(frame)); + + return true; + } + + bool testJavaScriptContext(WebKitWebPage* page) + { + WebKitFrame* frame = webkit_web_page_get_main_frame(page); + g_assert(WEBKIT_IS_FRAME(frame)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(frame)); + g_assert(webkit_frame_get_javascript_global_context(frame)); + + return true; + } + + bool runTest(const char* testName, WebKitWebPage* page) override + { + if (!strcmp(testName, "main-frame")) + return testMainFrame(page); + if (!strcmp(testName, "uri")) + return testURI(page); + if (!strcmp(testName, "javascript-context")) + return testJavaScriptContext(page); + + g_assert_not_reached(); + return false; + } +}; + +static void __attribute__((constructor)) registerTests() +{ + REGISTER_TEST(WebKitFrameTest, "WebKitFrame/main-frame"); + REGISTER_TEST(WebKitFrameTest, "WebKitFrame/uri"); + REGISTER_TEST(WebKitFrameTest, "WebKitFrame/javascript-context"); +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/InspectorTestServer.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/InspectorTestServer.cpp new file mode 100644 index 000000000..f13b043df --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/InspectorTestServer.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2012 Samsung Electronics Ltd. 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 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 <gtk/gtk.h> +#include <webkit2/webkit2.h> + +static void loadChangedCallback(WebKitWebView*, WebKitLoadEvent loadEvent, gpointer) +{ + // Send a message to the parent process when we're ready. + if (loadEvent == WEBKIT_LOAD_FINISHED) + g_print("OK"); +} + +int main(int argc, char** argv) +{ + gtk_init(&argc, &argv); + + // Overwrite WEBKIT_INSPECTOR_SERVER variable with default value. + g_setenv("WEBKIT_INSPECTOR_SERVER", "127.0.0.1:2999", TRUE); + + WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + webkit_settings_set_enable_developer_extras(webkit_web_view_get_settings(webView), TRUE); + webkit_web_view_load_html(webView, + "<html><body><p>WebKitGTK+ Inspector Test Server</p></body></html>", + "http://127.0.0.1:2999/"); + + GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(webView)); + gtk_widget_show_all(window); + + g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), 0); + g_signal_connect(webView, "load-changed", G_CALLBACK(loadChangedCallback), 0); + + gtk_main(); +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestAuthentication.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestAuthentication.cpp new file mode 100644 index 000000000..0d0e0765d --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestAuthentication.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "LoadTrackingTest.h" +#include "WebKitTestServer.h" +#include <wtf/glib/GRefPtr.h> + +static WebKitTestServer* kServer; + +class AuthenticationTest: public LoadTrackingTest { +public: + MAKE_GLIB_TEST_FIXTURE(AuthenticationTest); + + AuthenticationTest() + { + g_signal_connect(m_webView, "authenticate", G_CALLBACK(runAuthenticationCallback), this); + } + + ~AuthenticationTest() + { + g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + static int authenticationRetries; + static bool authenticationCancelledReceived; + + void loadURI(const char* uri) + { + // Reset the retry count of the fake server when a page is loaded. + authenticationRetries = 0; + authenticationCancelledReceived = false; + LoadTrackingTest::loadURI(uri); + } + + static gboolean runAuthenticationCallback(WebKitWebView*, WebKitAuthenticationRequest* request, AuthenticationTest* test) + { + g_signal_connect(request, "cancelled", G_CALLBACK(authenticationCancelledCallback), test); + test->runAuthentication(request); + return TRUE; + } + + static void authenticationCancelledCallback(WebKitAuthenticationRequest*, AuthenticationTest*) + { + authenticationCancelledReceived = true; + } + + void runAuthentication(WebKitAuthenticationRequest* request) + { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + m_authenticationRequest = request; + g_main_loop_quit(m_mainLoop); + } + + WebKitAuthenticationRequest* waitForAuthenticationRequest() + { + g_main_loop_run(m_mainLoop); + return m_authenticationRequest.get(); + } + +private: + GRefPtr<WebKitAuthenticationRequest> m_authenticationRequest; +}; + +int AuthenticationTest::authenticationRetries = 0; +bool AuthenticationTest::authenticationCancelledReceived = false; + +static const char authTestUsername[] = "username"; +static const char authTestPassword[] = "password"; +static const char authExpectedSuccessTitle[] = "WebKit2Gtk+ Authentication test"; +static const char authExpectedFailureTitle[] = "401 Authorization Required"; +static const char authExpectedAuthorization[] = "Basic dXNlcm5hbWU6cGFzc3dvcmQ="; // Base64 encoding of "username:password". +static const char authSuccessHTMLString[] = + "<html>" + "<head><title>WebKit2Gtk+ Authentication test</title></head>" + "<body></body></html>"; +static const char authFailureHTMLString[] = + "<html>" + "<head><title>401 Authorization Required</title></head>" + "<body></body></html>"; + +static void testWebViewAuthenticationRequest(AuthenticationTest* test, gconstpointer) +{ + // Test authentication request getters match soup authentication header. + test->loadURI(kServer->getURIForPath("/auth-test.html").data()); + WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); + g_assert_cmpstr(webkit_authentication_request_get_host(request), ==, soup_uri_get_host(kServer->baseURI())); + g_assert_cmpuint(webkit_authentication_request_get_port(request), ==, soup_uri_get_port(kServer->baseURI())); + g_assert_cmpstr(webkit_authentication_request_get_realm(request), ==, "my realm"); + g_assert(webkit_authentication_request_get_scheme(request) == WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC); + g_assert(!webkit_authentication_request_is_for_proxy(request)); + g_assert(!webkit_authentication_request_is_retry(request)); +} + +static void testWebViewAuthenticationCancel(AuthenticationTest* test, gconstpointer) +{ + // Test cancel. + test->loadURI(kServer->getURIForPath("/auth-test.html").data()); + WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); + webkit_authentication_request_cancel(request); + // Server doesn't ask for new credentials. + test->waitUntilLoadFinished(); + + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + + g_assert_error(test->m_error.get(), WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED); +} + +static void testWebViewAuthenticationLoadCancelled(AuthenticationTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/auth-test.html").data()); + test->waitForAuthenticationRequest(); + webkit_web_view_stop_loading(test->m_webView); + // Expect empty page. + test->waitUntilLoadFinished(); + g_assert(test->authenticationCancelledReceived); + + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + + g_assert_error(test->m_error.get(), WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED); +} + +static void testWebViewAuthenticationFailure(AuthenticationTest* test, gconstpointer) +{ + // Test authentication failures. + test->loadURI(kServer->getURIForPath("/auth-test.html").data()); + WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); + g_assert(!webkit_authentication_request_is_retry(request)); + WebKitCredential* credential = webkit_credential_new(authTestUsername, "wrongpassword", WEBKIT_CREDENTIAL_PERSISTENCE_NONE); + webkit_authentication_request_authenticate(request, credential); + webkit_credential_free(credential); + // Expect a second authentication request. + request = test->waitForAuthenticationRequest(); + g_assert(webkit_authentication_request_is_retry(request)); + // Test second failure. + credential = webkit_credential_new(authTestUsername, "wrongpassword2", WEBKIT_CREDENTIAL_PERSISTENCE_NONE); + webkit_authentication_request_authenticate(request, credential); + webkit_credential_free(credential); + // Expect authentication failed page. + test->waitUntilLoadFinished(); + + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, authExpectedFailureTitle); +} + +static void testWebViewAuthenticationNoCredential(AuthenticationTest* test, gconstpointer) +{ + // Test continue without credentials. + test->loadURI(kServer->getURIForPath("/auth-test.html").data()); + WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); + webkit_authentication_request_authenticate(request, 0); + // Server doesn't ask for new credentials. + test->waitUntilLoadFinished(); + + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, authExpectedFailureTitle); +} + +static void testWebViewAuthenticationStorage(AuthenticationTest* test, gconstpointer) +{ + // Enable private browsing before authentication request to test that credentials can't be saved. + webkit_settings_set_enable_private_browsing(webkit_web_view_get_settings(test->m_webView), TRUE); + test->loadURI(kServer->getURIForPath("/auth-test.html").data()); + WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); + g_assert(!webkit_authentication_request_get_proposed_credential(request)); + g_assert(!webkit_authentication_request_can_save_credentials(request)); + + // If WebKit has been compiled with libsecret, and private browsing is disabled + // then check that credentials can be saved. +#if ENABLE(CREDENTIAL_STORAGE) + webkit_settings_set_enable_private_browsing(webkit_web_view_get_settings(test->m_webView), FALSE); + test->loadURI(kServer->getURIForPath("/auth-test.html").data()); + request = test->waitForAuthenticationRequest(); + g_assert(!webkit_authentication_request_get_proposed_credential(request)); + g_assert(webkit_authentication_request_can_save_credentials(request)); +#endif +} + +static void testWebViewAuthenticationSuccess(AuthenticationTest* test, gconstpointer) +{ + // Test correct authentication. + test->loadURI(kServer->getURIForPath("/auth-test.html").data()); + WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); + WebKitCredential* credential = webkit_credential_new(authTestUsername, authTestPassword, WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION); + webkit_authentication_request_authenticate(request, credential); + webkit_credential_free(credential); + test->waitUntilLoadFinished(); + + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, authExpectedSuccessTitle); + + // Test loading the same (authorized) page again. + test->loadURI(kServer->getURIForPath("/auth-test.html").data()); + // There is no authentication challenge. + test->waitUntilLoadFinished(); + + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, authExpectedSuccessTitle); +} + +static void testWebViewAuthenticationEmptyRealm(AuthenticationTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/empty-realm.html").data()); + WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); + WebKitCredential* credential = webkit_credential_new(authTestUsername, authTestPassword, WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION); + webkit_authentication_request_authenticate(request, credential); + webkit_credential_free(credential); + test->waitUntilLoadFinished(); + + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, authExpectedSuccessTitle); +} + +static void serverCallback(SoupServer*, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, void*) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + if (!strcmp(path, "/auth-test.html") || !strcmp(path, "/empty-realm.html")) { + const char* authorization = soup_message_headers_get_one(message->request_headers, "Authorization"); + // Require authentication. + if (!g_strcmp0(authorization, authExpectedAuthorization)) { + // Successful authentication. + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, authSuccessHTMLString, strlen(authSuccessHTMLString)); + AuthenticationTest::authenticationRetries = 0; + } else if (++AuthenticationTest::authenticationRetries < 3) { + // No or invalid authorization header provided by the client, request authentication twice then fail. + soup_message_set_status(message, SOUP_STATUS_UNAUTHORIZED); + if (!strcmp(path, "/empty-realm.html")) + soup_message_headers_append(message->response_headers, "WWW-Authenticate", "Basic"); + else + soup_message_headers_append(message->response_headers, "WWW-Authenticate", "Basic realm=\"my realm\""); + // Include a failure message in case the user attempts to proceed without authentication. + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, authFailureHTMLString, strlen(authFailureHTMLString)); + } else { + // Authentication not successful, display a "401 Authorization Required" page. + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, authFailureHTMLString, strlen(authFailureHTMLString)); + } + } else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); + + soup_message_body_complete(message->response_body); +} + +void beforeAll() +{ + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + + AuthenticationTest::add("WebKitWebView", "authentication-request", testWebViewAuthenticationRequest); + AuthenticationTest::add("WebKitWebView", "authentication-cancel", testWebViewAuthenticationCancel); + AuthenticationTest::add("WebKitWebView", "authentication-load-cancelled", testWebViewAuthenticationLoadCancelled); + AuthenticationTest::add("WebKitWebView", "authentication-success", testWebViewAuthenticationSuccess); + AuthenticationTest::add("WebKitWebView", "authentication-failure", testWebViewAuthenticationFailure); + AuthenticationTest::add("WebKitWebView", "authentication-no-credential", testWebViewAuthenticationNoCredential); + AuthenticationTest::add("WebKitWebView", "authentication-storage", testWebViewAuthenticationStorage); + AuthenticationTest::add("WebKitWebView", "authentication-empty-realm", testWebViewAuthenticationEmptyRealm); +} + +void afterAll() +{ + delete kServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestAutocleanups.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestAutocleanups.cpp new file mode 100644 index 000000000..3265182de --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestAutocleanups.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebViewTest.h" +#include <webkit2/webkit2.h> + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC + +static void testUIProcessAutocleanups(WebViewTest* test, gconstpointer) +{ + // Sanity-check a couple UI process API autocleanups that are easy to test.... + g_autoptr(WebKitWebContext) context = webkit_web_context_new(); + g_assert(WEBKIT_IS_WEB_CONTEXT(context)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(context)); + + g_autoptr(WebKitWebsiteDataManager) manager = webkit_website_data_manager_new(nullptr); + g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(context)); + + g_autoptr(WebKitUserScript) userScript = webkit_user_script_new("", + WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START, + nullptr, nullptr); + g_assert(userScript); + // Not a GObject, so just checking that this doesn't crash.... +} + +static void testWebProcessAutocleanups(WebViewTest* test, gconstpointer) +{ + static const char* testHTML = "<html><body></body></html>"; + test->loadHtml(testHTML, nullptr); + test->waitUntilLoadFinished(); + + g_assert(test->runWebProcessTest("Autocleanups", "web-process-autocleanups")); +} + +void beforeAll() +{ + WebViewTest::add("Autocleanups", "ui-process-autocleanups", testUIProcessAutocleanups); + WebViewTest::add("Autocleanups", "web-process-autocleanups", testWebProcessAutocleanups); +} + +void afterAll() +{ +} + +#endif // G_DEFINE_AUTOPTR_CLEANUP_FUNC diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestBackForwardList.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestBackForwardList.cpp new file mode 100644 index 000000000..fd2fbf5f2 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestBackForwardList.cpp @@ -0,0 +1,417 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebKitTestServer.h" +#include "WebViewTest.h" +#include <gtk/gtk.h> +#include <libsoup/soup.h> +#include <string.h> +#include <webkit2/webkit2.h> + +// Back forward list limit is 100 by default. +static const int kBackForwardListLimit = 100; + +static WebKitTestServer* kServer; + +static void serverCallback(SoupServer* server, SoupMessage* msg, const char* path, GHashTable* query, SoupClientContext* context, gpointer data) +{ + if (msg->method != SOUP_METHOD_GET) { + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + if (g_str_has_suffix(path, "favicon.ico")) { + soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); + return; + } + + soup_message_set_status(msg, SOUP_STATUS_OK); + + char* body = g_strdup_printf("<html><title>%s</title><body>%s</body></html>", path + 1, path + 1); + soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, body, strlen(body)); + + soup_message_body_complete(msg->response_body); +} + +class BackForwardListTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(BackForwardListTest); + + enum { + Backward, + Forward + }; + + enum { + CurrentItem = 1 << 0, + AddedItem = 1 << 1, + RemovedItems = 1 << 2 + }; + + static void checkItem(WebKitBackForwardListItem* item, const char* title, const char* uri, const char* originalURI) + { + g_assert(item); + g_assert_cmpstr(webkit_back_forward_list_item_get_uri(item), ==, uri); + g_assert_cmpstr(webkit_back_forward_list_item_get_title(item), == , title); + g_assert_cmpstr(webkit_back_forward_list_item_get_original_uri(item), ==, originalURI); + } + + static void checkItemIndex(WebKitBackForwardList* list) + { + g_assert(webkit_back_forward_list_get_nth_item(list, -1) == webkit_back_forward_list_get_back_item(list)); + g_assert(webkit_back_forward_list_get_nth_item(list, 0) == webkit_back_forward_list_get_current_item(list)); + g_assert(webkit_back_forward_list_get_nth_item(list, 1) == webkit_back_forward_list_get_forward_item(list)); + } + + static void checkList(WebKitBackForwardList* list, unsigned type, WebKitBackForwardListItem** items, unsigned nItems) + { + GList* listItems = type == BackForwardListTest::Backward ? webkit_back_forward_list_get_back_list(list) : + webkit_back_forward_list_get_forward_list(list); + g_assert(listItems); + + unsigned i = 0; + for (GList* listItem = listItems; listItem; listItem = g_list_next(listItem), i++) { + g_assert_cmpuint(i, <, nItems); + g_assert(listItem->data == items[i]); + } + g_list_free(listItems); + } + + static void backForwardListChanged(WebKitBackForwardList* list, WebKitBackForwardListItem* addedItem, GList* removedItems, BackForwardListTest* test) + { + test->m_hasChanged = true; + + if (test->m_changedFlags & BackForwardListTest::AddedItem) { + g_assert(WEBKIT_IS_BACK_FORWARD_LIST_ITEM(addedItem)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(addedItem)); + } else + g_assert(!addedItem); + + if (test->m_changedFlags & BackForwardListTest::RemovedItems) { + g_assert(removedItems); + for (GList* iter = removedItems; iter; iter = iter->next) { + g_assert(WEBKIT_IS_BACK_FORWARD_LIST_ITEM(iter->data)); + if (test->m_expectedRemovedItems) + g_assert(g_list_find(test->m_expectedRemovedItems, iter->data)); + } + + } else + g_assert(!removedItems); + } + + BackForwardListTest() + : m_list(webkit_web_view_get_back_forward_list(m_webView)) + , m_changedFlags(0) + , m_hasChanged(false) + , m_expectedRemovedItems(0) + { + g_signal_connect(m_list, "changed", G_CALLBACK(backForwardListChanged), this); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_list)); + } + + ~BackForwardListTest() + { + g_signal_handlers_disconnect_matched(m_list, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + void waitUntilLoadFinished() + { + m_hasChanged = false; + WebViewTest::waitUntilLoadFinished(); + g_assert(m_hasChanged); + } + + void waitUntilLoadFinishedAndCheckRemovedItems(GList* removedItems) + { + m_expectedRemovedItems = removedItems; + waitUntilLoadFinished(); + m_expectedRemovedItems = 0; + } + + WebKitBackForwardList* m_list; + unsigned long m_changedFlags; + bool m_hasChanged; + GList* m_expectedRemovedItems; +}; + +static void testBackForwardListNavigation(BackForwardListTest* test, gconstpointer) +{ + WebKitBackForwardListItem* items[1]; + + g_assert(!webkit_web_view_can_go_back(test->m_webView)); + g_assert(!webkit_web_view_can_go_forward(test->m_webView)); + + g_assert_cmpuint(webkit_back_forward_list_get_length(test->m_list), ==, 0); + g_assert(!webkit_back_forward_list_get_current_item(test->m_list)); + g_assert(!webkit_back_forward_list_get_back_item(test->m_list)); + g_assert(!webkit_back_forward_list_get_forward_item(test->m_list)); + BackForwardListTest::checkItemIndex(test->m_list); + g_assert(!webkit_back_forward_list_get_back_list(test->m_list)); + g_assert(!webkit_back_forward_list_get_forward_list(test->m_list)); + + CString uriPage1 = kServer->getURIForPath("/Page1"); + test->m_changedFlags = BackForwardListTest::CurrentItem | BackForwardListTest::AddedItem; + test->loadURI(uriPage1.data()); + test->waitUntilLoadFinished(); + + g_assert(!webkit_web_view_can_go_back(test->m_webView)); + g_assert(!webkit_web_view_can_go_forward(test->m_webView)); + + g_assert_cmpuint(webkit_back_forward_list_get_length(test->m_list), ==, 1); + WebKitBackForwardListItem* itemPage1 = webkit_back_forward_list_get_current_item(test->m_list); + BackForwardListTest::checkItem(itemPage1, "Page1", uriPage1.data(), uriPage1.data()); + g_assert(!webkit_back_forward_list_get_back_item(test->m_list)); + g_assert(!webkit_back_forward_list_get_forward_item(test->m_list)); + BackForwardListTest::checkItemIndex(test->m_list); + g_assert(!webkit_back_forward_list_get_back_list(test->m_list)); + g_assert(!webkit_back_forward_list_get_forward_list(test->m_list)); + + CString uriPage2 = kServer->getURIForPath("/Page2"); + test->m_changedFlags = BackForwardListTest::CurrentItem | BackForwardListTest::AddedItem; + test->loadURI(uriPage2.data()); + test->waitUntilLoadFinished(); + + g_assert(webkit_web_view_can_go_back(test->m_webView)); + g_assert(!webkit_web_view_can_go_forward(test->m_webView)); + + g_assert_cmpuint(webkit_back_forward_list_get_length(test->m_list), ==, 2); + WebKitBackForwardListItem* itemPage2 = webkit_back_forward_list_get_current_item(test->m_list); + BackForwardListTest::checkItem(itemPage2, "Page2", uriPage2.data(), uriPage2.data()); + g_assert(webkit_back_forward_list_get_back_item(test->m_list) == itemPage1); + g_assert(!webkit_back_forward_list_get_forward_item(test->m_list)); + BackForwardListTest::checkItemIndex(test->m_list); + items[0] = itemPage1; + BackForwardListTest::checkList(test->m_list, BackForwardListTest::Backward, items, 1); + g_assert(!webkit_back_forward_list_get_forward_list(test->m_list)); + + test->m_changedFlags = BackForwardListTest::CurrentItem; + test->goBack(); + test->waitUntilLoadFinished(); + + g_assert(!webkit_web_view_can_go_back(test->m_webView)); + g_assert(webkit_web_view_can_go_forward(test->m_webView)); + + g_assert_cmpuint(webkit_back_forward_list_get_length(test->m_list), ==, 2); + g_assert(itemPage1 == webkit_back_forward_list_get_current_item(test->m_list)); + BackForwardListTest::checkItem(webkit_back_forward_list_get_current_item(test->m_list), "Page1", uriPage1.data(), uriPage1.data()); + g_assert(!webkit_back_forward_list_get_back_item(test->m_list)); + g_assert(webkit_back_forward_list_get_forward_item(test->m_list) == itemPage2); + BackForwardListTest::checkItemIndex(test->m_list); + g_assert(!webkit_back_forward_list_get_back_list(test->m_list)); + items[0] = itemPage2; + BackForwardListTest::checkList(test->m_list, BackForwardListTest::Forward, items, 1); + + test->m_changedFlags = BackForwardListTest::CurrentItem; + test->goForward(); + test->waitUntilLoadFinished(); + + g_assert(webkit_web_view_can_go_back(test->m_webView)); + g_assert(!webkit_web_view_can_go_forward(test->m_webView)); + + g_assert_cmpuint(webkit_back_forward_list_get_length(test->m_list), ==, 2); + g_assert(itemPage2 == webkit_back_forward_list_get_current_item(test->m_list)); + BackForwardListTest::checkItem(webkit_back_forward_list_get_current_item(test->m_list), "Page2", uriPage2.data(), uriPage2.data()); + g_assert(webkit_back_forward_list_get_back_item(test->m_list) == itemPage1); + g_assert(!webkit_back_forward_list_get_forward_item(test->m_list)); + BackForwardListTest::checkItemIndex(test->m_list); + items[0] = itemPage1; + BackForwardListTest::checkList(test->m_list, BackForwardListTest::Backward, items, 1); + g_assert(!webkit_back_forward_list_get_forward_list(test->m_list)); + + test->m_changedFlags = BackForwardListTest::CurrentItem; + test->goToBackForwardListItem(itemPage1); + test->waitUntilLoadFinished(); + + g_assert(itemPage1 == webkit_back_forward_list_get_current_item(test->m_list)); +} + +static void testBackForwardListLimitAndCache(BackForwardListTest* test, gconstpointer) +{ + for (int i = 0; i < kBackForwardListLimit; i++) { + GUniquePtr<char> path(g_strdup_printf("/Page%d", i)); + test->m_changedFlags = BackForwardListTest::CurrentItem | BackForwardListTest::AddedItem; + test->loadURI(kServer->getURIForPath(path.get()).data()); + test->waitUntilLoadFinished(); + } + + g_assert_cmpuint(webkit_back_forward_list_get_length(test->m_list), ==, kBackForwardListLimit); + WebKitBackForwardListItem* itemPageFirst = webkit_back_forward_list_get_nth_item(test->m_list, -(kBackForwardListLimit - 1)); + GUniquePtr<GList> removedItems(g_list_prepend(0, itemPageFirst)); + + GUniquePtr<char> path(g_strdup_printf("/Page%d", kBackForwardListLimit)); + test->m_changedFlags = BackForwardListTest::CurrentItem | BackForwardListTest::AddedItem | BackForwardListTest::RemovedItems; + test->loadURI(kServer->getURIForPath(path.get()).data()); + test->waitUntilLoadFinishedAndCheckRemovedItems(removedItems.get()); + + g_assert_cmpuint(webkit_back_forward_list_get_length(test->m_list), ==, kBackForwardListLimit); +} + +static void testWebKitWebViewSessionState(BackForwardListTest* test, gconstpointer) +{ + WebKitWebViewSessionState* state = webkit_web_view_get_session_state(test->m_webView); + g_assert(state); + GRefPtr<WebKitWebView> view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitBackForwardList* bfList = webkit_web_view_get_back_forward_list(view.get()); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 0); + webkit_web_view_restore_session_state(view.get(), state); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 0); + GRefPtr<GBytes> data = adoptGRef(webkit_web_view_session_state_serialize(state)); + g_assert(data); + state = webkit_web_view_session_state_new(data.get()); + g_assert(state); + view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + bfList = webkit_web_view_get_back_forward_list(view.get()); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 0); + webkit_web_view_restore_session_state(view.get(), state); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 0); + webkit_web_view_session_state_unref(state); + + CString uriPage1 = kServer->getURIForPath("/Page1"); + test->m_changedFlags = BackForwardListTest::CurrentItem | BackForwardListTest::AddedItem; + test->loadURI(uriPage1.data()); + test->waitUntilLoadFinished(); + + CString uriPage2 = kServer->getURIForPath("/Page2"); + test->m_changedFlags = BackForwardListTest::CurrentItem | BackForwardListTest::AddedItem; + test->loadURI(uriPage2.data()); + test->waitUntilLoadFinished(); + + CString uriPage3 = kServer->getURIForPath("/Page3"); + test->m_changedFlags = BackForwardListTest::CurrentItem | BackForwardListTest::AddedItem; + test->loadURI(uriPage3.data()); + test->waitUntilLoadFinished(); + + test->m_changedFlags = BackForwardListTest::CurrentItem; + test->goBack(); + test->waitUntilLoadFinished(); + + state = webkit_web_view_get_session_state(test->m_webView); + g_assert(state); + + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 0); + webkit_web_view_restore_session_state(view.get(), state); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 3); + + BackForwardListTest::checkItem(webkit_back_forward_list_get_nth_item(bfList, -1), "Page1", uriPage1.data(), uriPage1.data()); + BackForwardListTest::checkItem(webkit_back_forward_list_get_current_item(bfList), "Page2", uriPage2.data(), uriPage2.data()); + BackForwardListTest::checkItem(webkit_back_forward_list_get_nth_item(bfList, 1), "Page3", uriPage3.data(), uriPage3.data()); + + data = adoptGRef(webkit_web_view_session_state_serialize(state)); + g_assert(data); + webkit_web_view_session_state_unref(state); + state = webkit_web_view_session_state_new(data.get()); + g_assert(state); + + view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + bfList = webkit_web_view_get_back_forward_list(view.get()); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 0); + webkit_web_view_restore_session_state(view.get(), state); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 3); + webkit_web_view_session_state_unref(state); + + BackForwardListTest::checkItem(webkit_back_forward_list_get_nth_item(bfList, -1), "Page1", uriPage1.data(), uriPage1.data()); + BackForwardListTest::checkItem(webkit_back_forward_list_get_current_item(bfList), "Page2", uriPage2.data(), uriPage2.data()); + BackForwardListTest::checkItem(webkit_back_forward_list_get_nth_item(bfList, 1), "Page3", uriPage3.data(), uriPage3.data()); + + static const char* invalidSessionData = "invalid session data"; + data = adoptGRef(g_bytes_new_static(invalidSessionData, strlen(invalidSessionData))); + g_assert(!webkit_web_view_session_state_new(data.get())); +} + +static void testWebKitWebViewSessionStateWithFormData(BackForwardListTest* test, gconstpointer) +{ + GUniquePtr<char> htmlPath(g_build_filename(Test::getResourcesDir(Test::WebKit2Resources).data(), "simple-form.html", nullptr)); + GUniquePtr<char> htmlURL(g_filename_to_uri(htmlPath.get(), nullptr, nullptr)); + test->m_changedFlags = BackForwardListTest::CurrentItem | BackForwardListTest::AddedItem; + test->loadURI(htmlURL.get()); + test->waitUntilLoadFinished(); + + webkit_web_view_run_javascript(test->m_webView, "submitForm();", nullptr, nullptr, nullptr); + test->waitUntilLoadFinished(); + + WebKitWebViewSessionState* state = webkit_web_view_get_session_state(test->m_webView); + g_assert(state); + GRefPtr<WebKitWebView> view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebKitBackForwardList* bfList = webkit_web_view_get_back_forward_list(view.get()); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 0); + webkit_web_view_restore_session_state(view.get(), state); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 2); + GRefPtr<GBytes> data = adoptGRef(webkit_web_view_session_state_serialize(state)); + g_assert(data); + state = webkit_web_view_session_state_new(data.get()); + g_assert(state); + view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + bfList = webkit_web_view_get_back_forward_list(view.get()); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 0); + webkit_web_view_restore_session_state(view.get(), state); + g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 2); + webkit_web_view_session_state_unref(state); +} + +static void viewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent, GMainLoop* mainLoop) +{ + if (loadEvent == WEBKIT_LOAD_FINISHED) + g_main_loop_quit(mainLoop); +} + +static void testWebKitWebViewNavigationAfterSessionRestore(BackForwardListTest* test, gconstpointer) +{ + // This test checks that a normal load after a session restore with a BackForard list having + // forward items doesn't produce any runtime critical warning. See https://bugs.webkit.org/show_bug.cgi?id=153233. + GRefPtr<WebKitWebView> view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_signal_connect(view.get(), "load-changed", G_CALLBACK(viewLoadChanged), test->m_mainLoop); + + webkit_web_view_load_uri(view.get(), kServer->getURIForPath("/Page1").data()); + g_main_loop_run(test->m_mainLoop); + webkit_web_view_load_uri(view.get(), kServer->getURIForPath("/Page2").data()); + g_main_loop_run(test->m_mainLoop); + webkit_web_view_load_uri(view.get(), kServer->getURIForPath("/Page3").data()); + g_main_loop_run(test->m_mainLoop); + webkit_web_view_go_back(view.get()); + g_main_loop_run(test->m_mainLoop); + + WebKitWebViewSessionState* state = webkit_web_view_get_session_state(view.get()); + webkit_web_view_restore_session_state(test->m_webView, state); + webkit_web_view_session_state_unref(state); + + // A normal load after a session restore should remove the forward list, add the new item and update the current one. + test->m_changedFlags = BackForwardListTest::CurrentItem | BackForwardListTest::AddedItem | BackForwardListTest::RemovedItems; + test->loadURI(kServer->getURIForPath("/Page4").data()); + test->waitUntilLoadFinished(); +} + +void beforeAll() +{ + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + + BackForwardListTest::add("BackForwardList", "navigation", testBackForwardListNavigation); + BackForwardListTest::add("BackForwardList", "list-limit-and-cache", testBackForwardListLimitAndCache); + BackForwardListTest::add("WebKitWebView", "session-state", testWebKitWebViewSessionState); + BackForwardListTest::add("WebKitWebView", "session-state-with-form-data", testWebKitWebViewSessionStateWithFormData); + BackForwardListTest::add("WebKitWebView", "navigation-after-session-restore", testWebKitWebViewNavigationAfterSessionRestore); +} + +void afterAll() +{ + delete kServer; +} + diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestConsoleMessage.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestConsoleMessage.cpp new file mode 100644 index 000000000..10dd8ca44 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestConsoleMessage.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebViewTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + +class ConsoleMessageTest : public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(ConsoleMessageTest); + + // This should be keep in sync with the public enums in WebKitConsoleMessage.h. + enum class MessageSource { JavaScript, Network, ConsoleAPI, Security, Other }; + enum class MessageLevel { Info, Log, Warning, Error, Debug }; + struct ConsoleMessage { + bool operator==(const ConsoleMessage& other) + { + return source == other.source + && level == other.level + && message == other.message + && lineNumber == other.lineNumber + && sourceID == other.sourceID; + } + + MessageSource source; + MessageLevel level; + CString message; + unsigned lineNumber; + CString sourceID; + }; + + static void consoleMessageReceivedCallback(WebKitUserContentManager*, WebKitJavascriptResult* message, ConsoleMessageTest* test) + { + g_assert(message); + GUniquePtr<char> messageString(WebViewTest::javascriptResultToCString(message)); + GRefPtr<GVariant> variant = g_variant_parse(G_VARIANT_TYPE("(uusus)"), messageString.get(), nullptr, nullptr, nullptr); + g_assert(variant.get()); + + unsigned source, level, lineNumber; + const char* messageText; + const char* sourceID; + g_variant_get(variant.get(), "(uu&su&s)", &source, &level, &messageText, &lineNumber, &sourceID); + test->m_consoleMessage = { static_cast<ConsoleMessageTest::MessageSource>(source), static_cast<ConsoleMessageTest::MessageLevel>(level), messageText, lineNumber, sourceID }; + + g_main_loop_quit(test->m_mainLoop); + } + + ConsoleMessageTest() + : WebViewTest(webkit_user_content_manager_new()) + { + WebKitUserContentManager* manager = webkit_web_view_get_user_content_manager(m_webView); + webkit_user_content_manager_register_script_message_handler(manager, "console"); + g_signal_connect(manager, "script-message-received::console", G_CALLBACK(consoleMessageReceivedCallback), this); + } + + ~ConsoleMessageTest() + { + WebKitUserContentManager* manager = webkit_web_view_get_user_content_manager(m_webView); + g_signal_handlers_disconnect_matched(manager, G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this); + webkit_user_content_manager_unregister_script_message_handler(manager, "console"); + } + + void waitUntilConsoleMessageReceived() + { + g_main_loop_run(m_mainLoop); + } + + ConsoleMessage m_consoleMessage; +}; + +static void testWebKitConsoleMessageConsoleAPI(ConsoleMessageTest* test, gconstpointer) +{ + ConsoleMessageTest::ConsoleMessage referenceMessage = { ConsoleMessageTest::MessageSource::ConsoleAPI, ConsoleMessageTest::MessageLevel::Log, "Log Console Message", 1, "http://foo.com/bar" }; + test->loadHtml("<html><body onload='console.log(\"Log Console Message\");'></body></html>", "http://foo.com/bar"); + test->waitUntilConsoleMessageReceived(); + g_assert(test->m_consoleMessage == referenceMessage); + + referenceMessage.level = ConsoleMessageTest::MessageLevel::Info; + referenceMessage.message = "Info Console Message"; + test->loadHtml("<html><body onload='console.info(\"Info Console Message\");'></body></html>", "http://foo.com/bar"); + test->waitUntilConsoleMessageReceived(); + g_assert(test->m_consoleMessage == referenceMessage); + + referenceMessage.level = ConsoleMessageTest::MessageLevel::Warning; + referenceMessage.message = "Warning Console Message"; + test->loadHtml("<html><body onload='console.warn(\"Warning Console Message\");'></body></html>", "http://foo.com/bar"); + test->waitUntilConsoleMessageReceived(); + g_assert(test->m_consoleMessage == referenceMessage); + + referenceMessage.level = ConsoleMessageTest::MessageLevel::Error; + referenceMessage.message = "Error Console Message"; + test->loadHtml("<html><body onload='console.error(\"Error Console Message\");'></body></html>", "http://foo.com/bar"); + test->waitUntilConsoleMessageReceived(); + g_assert(test->m_consoleMessage == referenceMessage); + + referenceMessage.level = ConsoleMessageTest::MessageLevel::Debug; + referenceMessage.message = "Debug Console Message"; + test->loadHtml("<html><body onload='console.debug(\"Debug Console Message\");'></body></html>", "http://foo.com/bar"); + test->waitUntilConsoleMessageReceived(); + g_assert(test->m_consoleMessage == referenceMessage); +} + +static void testWebKitConsoleMessageJavaScriptException(ConsoleMessageTest* test, gconstpointer) +{ + ConsoleMessageTest::ConsoleMessage referenceMessage = { ConsoleMessageTest::MessageSource::JavaScript, ConsoleMessageTest::MessageLevel::Error, + "ReferenceError: Can't find variable: foo", 1, "http://foo.com/bar" }; + test->loadHtml("<html><body onload='foo()'></body></html>", "http://foo.com/bar"); + test->waitUntilConsoleMessageReceived(); + g_assert(test->m_consoleMessage == referenceMessage); +} + +static void testWebKitConsoleMessageNetworkError(ConsoleMessageTest* test, gconstpointer) +{ + ConsoleMessageTest::ConsoleMessage referenceMessage = { ConsoleMessageTest::MessageSource::Network, ConsoleMessageTest::MessageLevel::Error, + "Failed to load resource: Error opening file: No such file or directory", 0, "file:///foo/not-found.css" }; + test->loadHtml("<html><head><link rel='stylesheet' href='not-found.css' type='text/css'></head><body></body></html>", "file:///foo/bar"); + test->waitUntilConsoleMessageReceived(); + g_assert(test->m_consoleMessage == referenceMessage); +} + +static void testWebKitConsoleMessageSecurityError(ConsoleMessageTest* test, gconstpointer) +{ + ConsoleMessageTest::ConsoleMessage referenceMessage = { ConsoleMessageTest::MessageSource::Security, ConsoleMessageTest::MessageLevel::Error, + "Not allowed to load local resource: file:///foo/bar/source.png", 1, "http://foo.com/bar" }; + test->loadHtml("<html><body><img src=\"file:///foo/bar/source.png\"/></body></html>", "http://foo.com/bar"); + test->waitUntilConsoleMessageReceived(); + g_assert(test->m_consoleMessage == referenceMessage); +} + +void beforeAll() +{ + ConsoleMessageTest::add("WebKitConsoleMessage", "console-api", testWebKitConsoleMessageConsoleAPI); + ConsoleMessageTest::add("WebKitConsoleMessage", "js-exception", testWebKitConsoleMessageJavaScriptException); + ConsoleMessageTest::add("WebKitConsoleMessage", "network-error", testWebKitConsoleMessageNetworkError); + ConsoleMessageTest::add("WebKitConsoleMessage", "security-error", testWebKitConsoleMessageSecurityError); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp new file mode 100644 index 000000000..e08ec799d --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestContextMenu.cpp @@ -0,0 +1,1043 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebViewTest.h" +#include <wtf/Vector.h> +#include <wtf/glib/GRefPtr.h> + +class ContextMenuTest: public WebViewTest { +public: + enum ContextMenuItemStateFlags { + Visible = 1 << 0, + Enabled = 1 << 1, + Checked = 1 << 2 + }; + + void checkContextMenuEvent(GdkEvent* event) + { + g_assert(event); + g_assert_cmpint(event->type, ==, GDK_BUTTON_PRESS); + g_assert_cmpint(event->button.button, ==, 3); + g_assert_cmpint(event->button.x, ==, m_menuPositionX); + g_assert_cmpint(event->button.y, ==, m_menuPositionY); + } + + static gboolean contextMenuCallback(WebKitWebView* webView, WebKitContextMenu* contextMenu, GdkEvent* event, WebKitHitTestResult* hitTestResult, ContextMenuTest* test) + { + g_assert(WEBKIT_IS_CONTEXT_MENU(contextMenu)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(contextMenu)); + test->checkContextMenuEvent(event); + g_assert(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(hitTestResult)); + + return test->contextMenu(contextMenu, event, hitTestResult); + } + + static void contextMenuDismissedCallback(WebKitWebView*, ContextMenuTest* test) + { + test->contextMenuDismissed(); + } + + ContextMenuTest() + : m_menuPositionX(0) + , m_menuPositionY(0) + { + g_signal_connect(m_webView, "context-menu", G_CALLBACK(contextMenuCallback), this); + g_signal_connect(m_webView, "context-menu-dismissed", G_CALLBACK(contextMenuDismissedCallback), this); + } + + ~ContextMenuTest() + { + g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + virtual bool contextMenu(WebKitContextMenu*, GdkEvent*, WebKitHitTestResult*) = 0; + + virtual void contextMenuDismissed() + { + quitMainLoop(); + } + + GtkMenu* getPopupMenu() + { + GUniquePtr<GList> toplevels(gtk_window_list_toplevels()); + for (GList* iter = toplevels.get(); iter; iter = g_list_next(iter)) { + if (!GTK_IS_WINDOW(iter->data)) + continue; + + GtkWidget* child = gtk_bin_get_child(GTK_BIN(iter->data)); + if (!GTK_IS_MENU(child)) + continue; + + if (gtk_menu_get_attach_widget(GTK_MENU(child)) == GTK_WIDGET(m_webView)) + return GTK_MENU(child); + } + g_assert_not_reached(); + return 0; + } + + void checkActionState(GtkAction* action, unsigned state) + { + if (state & Visible) + g_assert(gtk_action_get_visible(action)); + else + g_assert(!gtk_action_get_visible(action)); + + if (state & Enabled) + g_assert(gtk_action_get_sensitive(action)); + else + g_assert(!gtk_action_get_sensitive(action)); + + if (GTK_IS_TOGGLE_ACTION(action)) { + if (state & Checked) + g_assert(gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action))); + else + g_assert(!gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action))); + } + } + + GList* checkCurrentItemIsStockActionAndGetNext(GList* items, WebKitContextMenuAction stockAction, unsigned state) + { + g_assert(items); + g_assert(WEBKIT_IS_CONTEXT_MENU_ITEM(items->data)); + + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(items->data); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(item)); + + GtkAction* action = webkit_context_menu_item_get_action(item); + g_assert(GTK_IS_ACTION(action)); + + g_assert_cmpint(webkit_context_menu_item_get_stock_action(item), ==, stockAction); + + checkActionState(action, state); + + return g_list_next(items); + } + + GList* checkCurrentItemIsCustomActionAndGetNext(GList* items, const char* label, unsigned state) + { + g_assert(items); + g_assert(WEBKIT_IS_CONTEXT_MENU_ITEM(items->data)); + + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(items->data); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(item)); + + GtkAction* action = webkit_context_menu_item_get_action(item); + g_assert(GTK_IS_ACTION(action)); + + g_assert_cmpint(webkit_context_menu_item_get_stock_action(item), ==, WEBKIT_CONTEXT_MENU_ACTION_CUSTOM); + g_assert_cmpstr(gtk_action_get_label(action), ==, label); + + checkActionState(action, state); + + return g_list_next(items); + } + + GList* checkCurrentItemIsSubMenuAndGetNext(GList* items, const char* label, unsigned state, GList** subMenuIter) + { + g_assert(items); + g_assert(WEBKIT_IS_CONTEXT_MENU_ITEM(items->data)); + + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(items->data); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(item)); + + GtkAction* action = webkit_context_menu_item_get_action(item); + g_assert(GTK_IS_ACTION(action)); + + g_assert_cmpstr(gtk_action_get_label(action), ==, label); + checkActionState(action, state); + + WebKitContextMenu* subMenu = webkit_context_menu_item_get_submenu(item); + g_assert(WEBKIT_IS_CONTEXT_MENU(subMenu)); + if (subMenuIter) + *subMenuIter = webkit_context_menu_get_items(subMenu); + + return g_list_next(items); + } + + GList* checkCurrentItemIsSeparatorAndGetNext(GList* items) + { + g_assert(items); + g_assert(WEBKIT_IS_CONTEXT_MENU_ITEM(items->data)); + + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(items->data); + g_assert(webkit_context_menu_item_is_separator(item)); + + return g_list_next(items); + } + + static gboolean doRightClickIdleCallback(ContextMenuTest* test) + { + test->clickMouseButton(test->m_menuPositionX, test->m_menuPositionY, 3); + return FALSE; + } + + void showContextMenuAtPositionAndWaitUntilFinished(int x, int y) + { + m_menuPositionX = x; + m_menuPositionY = y; + g_idle_add(reinterpret_cast<GSourceFunc>(doRightClickIdleCallback), this); + g_main_loop_run(m_mainLoop); + } + + void showContextMenuAndWaitUntilFinished() + { + showContextMenuAtPositionAndWaitUntilFinished(0, 0); + } + + static gboolean simulateEscKeyIdleCallback(ContextMenuTest* test) + { + test->keyStroke(GDK_KEY_Escape); + return FALSE; + } + + void dismissContextMenuAndWaitUntilFinished() + { + g_idle_add(reinterpret_cast<GSourceFunc>(simulateEscKeyIdleCallback), this); + g_main_loop_run(m_mainLoop); + } + + double m_menuPositionX; + double m_menuPositionY; +}; + +class ContextMenuDefaultTest: public ContextMenuTest { +public: + MAKE_GLIB_TEST_FIXTURE(ContextMenuDefaultTest); + + enum DefaultMenuType { + Navigation, + Link, + Image, + LinkImage, + Video, + Audio, + Editable, + Selection + }; + + ContextMenuDefaultTest() + : m_expectedMenuType(Navigation) + { + } + + bool contextMenu(WebKitContextMenu* contextMenu, GdkEvent* event, WebKitHitTestResult* hitTestResult) + { + GList* iter = webkit_context_menu_get_items(contextMenu); + + switch (m_expectedMenuType) { + case Navigation: + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_GO_BACK, Visible); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_GO_FORWARD, Visible); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_STOP, Visible); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_RELOAD, Visible | Enabled); + break; + case Link: + g_assert(webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_OPEN_LINK, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_OPEN_LINK_IN_NEW_WINDOW, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_LINK_TO_DISK, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY_LINK_TO_CLIPBOARD, Visible | Enabled); + break; + case Image: + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_OPEN_IMAGE_IN_NEW_WINDOW, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_IMAGE_TO_DISK, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY_IMAGE_TO_CLIPBOARD, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY_IMAGE_URL_TO_CLIPBOARD, Visible | Enabled); + break; + case LinkImage: + g_assert(webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_OPEN_LINK, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_OPEN_LINK_IN_NEW_WINDOW, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_LINK_TO_DISK, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY_LINK_TO_CLIPBOARD, Visible | Enabled); + iter = checkCurrentItemIsSeparatorAndGetNext(iter); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_OPEN_IMAGE_IN_NEW_WINDOW, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_IMAGE_TO_DISK, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY_IMAGE_TO_CLIPBOARD, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY_IMAGE_URL_TO_CLIPBOARD, Visible | Enabled); + break; + case Video: + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_MEDIA_PLAY, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_MEDIA_MUTE, Visible); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_TOGGLE_MEDIA_CONTROLS, Visible | Enabled | Checked); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_TOGGLE_MEDIA_LOOP, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_ENTER_VIDEO_FULLSCREEN, Visible | Enabled); + iter = checkCurrentItemIsSeparatorAndGetNext(iter); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY_VIDEO_LINK_TO_CLIPBOARD, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_OPEN_VIDEO_IN_NEW_WINDOW, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_VIDEO_TO_DISK, Visible | Enabled); + break; + case Audio: + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_MEDIA_PLAY, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_MEDIA_MUTE, Visible); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_TOGGLE_MEDIA_CONTROLS, Visible | Enabled | Checked); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_TOGGLE_MEDIA_LOOP, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_ENTER_VIDEO_FULLSCREEN, Visible); + iter = checkCurrentItemIsSeparatorAndGetNext(iter); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY_AUDIO_LINK_TO_CLIPBOARD, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_OPEN_AUDIO_IN_NEW_WINDOW, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_AUDIO_TO_DISK, Visible | Enabled); + break; + case Editable: + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_CUT, Visible); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY, Visible); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_PASTE, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_DELETE, Visible); + iter = checkCurrentItemIsSeparatorAndGetNext(iter); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_SELECT_ALL, Visible | Enabled); + iter = checkCurrentItemIsSeparatorAndGetNext(iter); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_UNICODE, Visible | Enabled); + break; + case Selection: + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_selection(hitTestResult)); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_COPY, Visible | Enabled); + break; + default: + g_assert_not_reached(); + } + + if (webkit_settings_get_enable_developer_extras(webkit_web_view_get_settings(m_webView))) { + iter = checkCurrentItemIsSeparatorAndGetNext(iter); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT, Visible | Enabled); + } + g_assert(!iter); + + quitMainLoop(); + + return true; + } + + DefaultMenuType m_expectedMenuType; +}; + +static void testContextMenuDefaultMenu(ContextMenuDefaultTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + + const char* linksHTML = + "<html><head>" + " <script>" + " window.onload = function () {" + " window.getSelection().removeAllRanges();" + " var select_range = document.createRange();" + " select_range.selectNodeContents(document.getElementById('text_to_select'));" + " window.getSelection().addRange(select_range);" + " }" + " </script>" + "</head><body>" + " <a style='position:absolute; left:1; top:1' href='http://www.webkitgtk.org' title='WebKitGTK+ Title'>WebKitGTK+ Website</a>" + " <img style='position:absolute; left:1; top:10' src='0xdeadbeef' width=5 height=5></img>" + " <a style='position:absolute; left:1; top:20' href='http://www.webkitgtk.org/logo' title='WebKitGTK+ Logo'><img src='0xdeadbeef' width=5 height=5></img></a>" + " <input style='position:absolute; left:1; top:30' size='10'></input>" + " <video style='position:absolute; left:1; top:50' width='300' height='300' controls='controls' preload='none'><source src='movie.ogg' type='video/ogg' /></video>" + " <audio style='position:absolute; left:1; top:60' width='50' height='20' controls='controls' preload='none'><source src='track.mp3' type='audio/mp3' /></audio>" + " <p style='position:absolute; left:1; top:90' id='text_to_select'>Lorem ipsum.</p>" + "</body></html>"; + test->loadHtml(linksHTML, "file:///"); + test->waitUntilLoadFinished(); + + // Context menu for selection. + // This test should always be the first because any other click removes the selection. + test->m_expectedMenuType = ContextMenuDefaultTest::Selection; + test->showContextMenuAtPositionAndWaitUntilFinished(2, 115); + + // Context menu for document. + test->m_expectedMenuType = ContextMenuDefaultTest::Navigation; + test->showContextMenuAtPositionAndWaitUntilFinished(0, 0); + + // Context menu for link. + test->m_expectedMenuType = ContextMenuDefaultTest::Link; + test->showContextMenuAtPositionAndWaitUntilFinished(1, 1); + + // Context menu for image. + test->m_expectedMenuType = ContextMenuDefaultTest::Image; + test->showContextMenuAtPositionAndWaitUntilFinished(1, 10); + + // Enable developer extras now, so that inspector element + // will be shown in the default context menu. + webkit_settings_set_enable_developer_extras(webkit_web_view_get_settings(test->m_webView), TRUE); + + // Context menu for image link. + test->m_expectedMenuType = ContextMenuDefaultTest::LinkImage; + test->showContextMenuAtPositionAndWaitUntilFinished(1, 20); + + // Context menu for video. + test->m_expectedMenuType = ContextMenuDefaultTest::Video; + test->showContextMenuAtPositionAndWaitUntilFinished(1, 50); + + // Context menu for audio. + test->m_expectedMenuType = ContextMenuDefaultTest::Audio; + test->showContextMenuAtPositionAndWaitUntilFinished(1, 60); + + // Context menu for editable. + test->m_expectedMenuType = ContextMenuDefaultTest::Editable; + test->showContextMenuAtPositionAndWaitUntilFinished(5, 35); +} + +class ContextMenuCustomTest: public ContextMenuTest { +public: + MAKE_GLIB_TEST_FIXTURE(ContextMenuCustomTest); + + ContextMenuCustomTest() + : m_itemToActivateLabel(0) + , m_activated(false) + , m_toggled(false) + { + } + + bool contextMenu(WebKitContextMenu* contextMenu, GdkEvent*, WebKitHitTestResult* hitTestResult) + { + // Append our custom item to the default menu. + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new(m_action.get())); + quitMainLoop(); + + return false; + } + + GtkMenuItem* getMenuItem(GtkMenu* menu, const gchar* itemLabel) + { + GUniquePtr<GList> items(gtk_container_get_children(GTK_CONTAINER(menu))); + for (GList* iter = items.get(); iter; iter = g_list_next(iter)) { + GtkMenuItem* child = GTK_MENU_ITEM(iter->data); + if (g_str_equal(itemLabel, gtk_menu_item_get_label(child))) + return child; + } + g_assert_not_reached(); + return 0; + } + + void activateMenuItem() + { + g_assert(m_itemToActivateLabel); + GtkMenu* menu = getPopupMenu(); + GtkMenuItem* item = getMenuItem(menu, m_itemToActivateLabel); + gtk_menu_shell_activate_item(GTK_MENU_SHELL(menu), GTK_WIDGET(item), TRUE); + m_itemToActivateLabel = 0; + } + + static gboolean activateMenuItemIdleCallback(gpointer userData) + { + ContextMenuCustomTest* test = static_cast<ContextMenuCustomTest*>(userData); + test->activateMenuItem(); + return FALSE; + } + + void activateCustomMenuItemAndWaitUntilActivated(const char* actionLabel) + { + m_activated = m_toggled = false; + m_itemToActivateLabel = actionLabel; + g_idle_add(activateMenuItemIdleCallback, this); + g_main_loop_run(m_mainLoop); + } + + void toggleCustomMenuItemAndWaitUntilToggled(const char* actionLabel) + { + activateCustomMenuItemAndWaitUntilActivated(actionLabel); + } + + static void actionActivatedCallback(GtkAction*, ContextMenuCustomTest* test) + { + test->m_activated = true; + } + + static void actionToggledCallback(GtkAction*, ContextMenuCustomTest* test) + { + test->m_toggled = true; + } + + void setAction(GtkAction* action) + { + m_action = action; + if (GTK_IS_TOGGLE_ACTION(action)) + g_signal_connect(action, "toggled", G_CALLBACK(actionToggledCallback), this); + else + g_signal_connect(action, "activate", G_CALLBACK(actionActivatedCallback), this); + } + + GRefPtr<GtkAction> m_action; + const char* m_itemToActivateLabel; + bool m_activated; + bool m_toggled; +}; + +static void testContextMenuPopulateMenu(ContextMenuCustomTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + + test->loadHtml("<html><body>WebKitGTK+ Context menu tests</body></html>", "file:///"); + test->waitUntilLoadFinished(); + + // Create a custom menu item. + GRefPtr<GtkAction> action = adoptGRef(gtk_action_new("WebKitGTK+CustomAction", "Custom _Action", 0, 0)); + test->setAction(action.get()); + test->showContextMenuAndWaitUntilFinished(); + test->activateCustomMenuItemAndWaitUntilActivated(gtk_action_get_label(action.get())); + g_assert(test->m_activated); + g_assert(!test->m_toggled); + + // Create a custom toggle menu item. + GRefPtr<GtkAction> toggleAction = adoptGRef(GTK_ACTION(gtk_toggle_action_new("WebKitGTK+CustomToggleAction", "Custom _Toggle Action", 0, 0))); + test->setAction(toggleAction.get()); + test->showContextMenuAndWaitUntilFinished(); + test->toggleCustomMenuItemAndWaitUntilToggled(gtk_action_get_label(toggleAction.get())); + g_assert(!test->m_activated); + g_assert(test->m_toggled); +} + +class ContextMenuCustomFullTest: public ContextMenuTest { +public: + MAKE_GLIB_TEST_FIXTURE(ContextMenuCustomFullTest); + + bool contextMenu(WebKitContextMenu* contextMenu, GdkEvent*, WebKitHitTestResult*) + { + // Clear proposed menu and build our own. + webkit_context_menu_remove_all(contextMenu); + g_assert_cmpint(webkit_context_menu_get_n_items(contextMenu), ==, 0); + + // Add actions from stock. + webkit_context_menu_prepend(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_GO_BACK)); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_GO_FORWARD)); + webkit_context_menu_insert(contextMenu, webkit_context_menu_item_new_separator(), 2); + + // Add custom actions. + GRefPtr<GtkAction> action = adoptGRef(gtk_action_new("WebKitGTK+CustomAction", "Custom _Action", 0, 0)); + gtk_action_set_sensitive(action.get(), FALSE); + webkit_context_menu_insert(contextMenu, webkit_context_menu_item_new(action.get()), -1); + GRefPtr<GtkAction> toggleAction = adoptGRef(GTK_ACTION(gtk_toggle_action_new("WebKitGTK+CustomToggleAction", "Custom _Toggle Action", 0, 0))); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(toggleAction.get()), TRUE); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new(toggleAction.get())); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); + + // Add a submenu. + GRefPtr<WebKitContextMenu> subMenu = adoptGRef(webkit_context_menu_new()); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(subMenu.get())); + webkit_context_menu_insert(subMenu.get(), webkit_context_menu_item_new_from_stock_action_with_label(WEBKIT_CONTEXT_MENU_ACTION_STOP, "Stop Load"), 0); + webkit_context_menu_insert(subMenu.get(), webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_RELOAD), -1); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_with_submenu("Load options", subMenu.get())); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); + + // Move Load submenu before custom actions. + webkit_context_menu_move_item(contextMenu, webkit_context_menu_last(contextMenu), 3); + webkit_context_menu_move_item(contextMenu, webkit_context_menu_last(contextMenu), 3); + + // If last item is a separator, remove it. + if (webkit_context_menu_item_is_separator(webkit_context_menu_last(contextMenu))) + webkit_context_menu_remove(contextMenu, webkit_context_menu_last(contextMenu)); + + // Check the menu. + GList* iter = webkit_context_menu_get_items(contextMenu); + + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_GO_BACK, Visible | Enabled); + iter = checkCurrentItemIsStockActionAndGetNext(iter, WEBKIT_CONTEXT_MENU_ACTION_GO_FORWARD, Visible | Enabled); + iter = checkCurrentItemIsSeparatorAndGetNext(iter); + + GList* subMenuIter = 0; + iter = checkCurrentItemIsSubMenuAndGetNext(iter, "Load options", Visible | Enabled, &subMenuIter); + subMenuIter = checkCurrentItemIsStockActionAndGetNext(subMenuIter, WEBKIT_CONTEXT_MENU_ACTION_STOP, Visible | Enabled); + subMenuIter = checkCurrentItemIsStockActionAndGetNext(subMenuIter, WEBKIT_CONTEXT_MENU_ACTION_RELOAD, Visible | Enabled); + iter = checkCurrentItemIsSeparatorAndGetNext(iter); + + iter = checkCurrentItemIsCustomActionAndGetNext(iter, "Custom _Action", Visible); + iter = checkCurrentItemIsCustomActionAndGetNext(iter, "Custom _Toggle Action", Visible | Enabled | Checked); + g_assert(!iter); + + quitMainLoop(); + + return true; + } +}; + +static void testContextMenuCustomMenu(ContextMenuCustomFullTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + + test->loadHtml("<html><body>WebKitGTK+ Context menu tests</body></html>", "file:///"); + test->waitUntilLoadFinished(); + + test->showContextMenuAndWaitUntilFinished(); +} + +class ContextMenuDisabledTest: public ContextMenuTest { +public: + MAKE_GLIB_TEST_FIXTURE(ContextMenuDisabledTest); + + enum DisableMode { + IgnoreClicks, + IgnoreDefaultMenu + }; + + static gboolean buttonPressEventCallback(GtkWidget*, GdkEvent* event, ContextMenuDisabledTest* test) + { + if (event->button.button != 3) + return FALSE; + return test->rightButtonPressed(); + } + + ContextMenuDisabledTest() + : m_disableMode(IgnoreClicks) + { + g_signal_connect(m_webView, "button-press-event", G_CALLBACK(buttonPressEventCallback), this); + } + + bool contextMenu(WebKitContextMenu* contextMenu, GdkEvent*, WebKitHitTestResult*) + { + if (m_disableMode == IgnoreClicks) + g_assert_not_reached(); + else + quitMainLoop(); + + return true; + } + + bool rightButtonPressed() + { + if (m_disableMode == IgnoreClicks) { + quitMainLoopAfterProcessingPendingEvents(); + return true; + } + return false; + } + + DisableMode m_disableMode; +}; + +static void testContextMenuDisableMenu(ContextMenuDisabledTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + + test->loadHtml("<html><body>WebKitGTK+ Context menu tests</body></html>", "file:///"); + test->waitUntilLoadFinished(); + + test->m_disableMode = ContextMenuDisabledTest::IgnoreDefaultMenu; + test->showContextMenuAndWaitUntilFinished(); + + test->m_disableMode = ContextMenuDisabledTest::IgnoreClicks; + test->showContextMenuAndWaitUntilFinished(); +} + +class ContextMenuSubmenuTest: public ContextMenuTest { +public: + MAKE_GLIB_TEST_FIXTURE(ContextMenuSubmenuTest); + + bool contextMenu(WebKitContextMenu* contextMenu, GdkEvent*, WebKitHitTestResult*) + { + size_t menuSize = webkit_context_menu_get_n_items(contextMenu); + GRefPtr<WebKitContextMenu> subMenu = adoptGRef(webkit_context_menu_new()); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_with_submenu("SubMenuItem", subMenu.get())); + g_assert_cmpuint(webkit_context_menu_get_n_items(contextMenu), ==, menuSize + 1); + + GRefPtr<WebKitContextMenu> subMenu2 = adoptGRef(webkit_context_menu_new()); + GRefPtr<WebKitContextMenuItem> item = webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_OPEN_LINK); + + // Add submenu to newly created item. + g_assert(!webkit_context_menu_item_get_submenu(item.get())); + webkit_context_menu_item_set_submenu(item.get(), subMenu2.get()); + g_assert(webkit_context_menu_item_get_submenu(item.get()) == subMenu2.get()); + + // Replace the submenu. + webkit_context_menu_item_set_submenu(item.get(), 0); + g_assert(!webkit_context_menu_item_get_submenu(item.get())); + + // Try to add a submenu already added to another item. + removeLogFatalFlag(G_LOG_LEVEL_WARNING); + webkit_context_menu_item_set_submenu(item.get(), subMenu.get()); + addLogFatalFlag(G_LOG_LEVEL_WARNING); + g_assert(!webkit_context_menu_item_get_submenu(item.get())); + + // A removed submenu shouldn't have a parent. + webkit_context_menu_item_set_submenu(item.get(), subMenu2.get()); + g_assert(webkit_context_menu_item_get_submenu(item.get()) == subMenu2.get()); + + quitMainLoop(); + + return true; + } +}; + +static void testContextMenuSubMenu(ContextMenuSubmenuTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + + test->loadHtml("<html><body>WebKitGTK+ Context menu tests</body></html>", "file:///"); + test->waitUntilLoadFinished(); + + test->showContextMenuAndWaitUntilFinished(); +} + +class ContextMenuDismissedTest: public ContextMenuTest { +public: + MAKE_GLIB_TEST_FIXTURE(ContextMenuDismissedTest); + + ContextMenuDismissedTest() + : m_dismissed(false) + { + } + + bool contextMenu(WebKitContextMenu* contextMenu, GdkEvent*, WebKitHitTestResult*) + { + quitMainLoop(); + // Show the default context menu. + return false; + } + + void contextMenuDismissed() + { + m_dismissed = true; + ContextMenuTest::contextMenuDismissed(); + } + + void showContextMenuAndWaitUntilDismissed() + { + showContextMenuAndWaitUntilFinished(); + dismissContextMenuAndWaitUntilFinished(); + } + + bool m_dismissed; +}; + +static void testContextMenuDismissed(ContextMenuDismissedTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + + test->loadHtml("<html><body>WebKitGTK+ Context menu tests</body></html>", "file:///"); + test->waitUntilLoadFinished(); + + test->showContextMenuAndWaitUntilDismissed(); + g_assert(test->m_dismissed); +} + +class ContextMenuSmartSeparatorsTest: public ContextMenuTest { +public: + MAKE_GLIB_TEST_FIXTURE(ContextMenuSmartSeparatorsTest); + + bool contextMenu(WebKitContextMenu* contextMenu, GdkEvent*, WebKitHitTestResult*) + { + webkit_context_menu_remove_all(contextMenu); + + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_GO_BACK)); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_GO_FORWARD)); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_COPY)); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT)); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); + webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); + + quitMainLoop(); + + return false; + } + + GtkMenu* showContextMenuAndGetGtkMenu() + { + showContextMenuAndWaitUntilFinished(); + return getPopupMenu(); + } +}; + +static void testContextMenuSmartSeparators(ContextMenuSmartSeparatorsTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + + test->loadHtml("<html><body>WebKitGTK+ Context menu tests</body></html>", "file:///"); + test->waitUntilLoadFinished(); + + GtkMenu* menu = test->showContextMenuAndGetGtkMenu(); + g_assert(menu); + + // Leading and trailing separators are not added to the context menu. + GUniquePtr<GList> menuItems(gtk_container_get_children(GTK_CONTAINER(menu))); + g_assert_cmpuint(g_list_length(menuItems.get()), ==, 6); + GtkWidget* item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 0)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 1)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 2)); + g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 3)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 4)); + g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 5)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + + // Hiding a menu item between two separators hides the following separator. + GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(g_list_nth_data(menuItems.get(), 3))); + gtk_action_set_visible(action, FALSE); + menuItems.reset(gtk_container_get_children(GTK_CONTAINER(menu))); + g_assert_cmpuint(g_list_length(menuItems.get()), ==, 6); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 0)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 1)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 2)); + g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 3)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 4)); + g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 5)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + gtk_action_set_visible(action, TRUE); + + // Showing an action between two separators shows the hidden separator. + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 0)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 1)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 2)); + g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 3)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 4)); + g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 5)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + + // Trailing separators are hidden too. + action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(g_list_nth_data(menuItems.get(), 5))); + gtk_action_set_visible(action, FALSE); + menuItems.reset(gtk_container_get_children(GTK_CONTAINER(menu))); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 0)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 1)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 2)); + g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 3)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 4)); + g_assert(GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_widget_get_visible(item)); + item = GTK_WIDGET(g_list_nth_data(menuItems.get(), 5)); + g_assert(!GTK_IS_SEPARATOR_MENU_ITEM(item) && !gtk_widget_get_visible(item)); +} + +class ContextMenuWebExtensionTest: public ContextMenuTest { +public: + MAKE_GLIB_TEST_FIXTURE(ContextMenuWebExtensionTest); + + void deserializeContextMenuFromUserData(GVariant* userData) + { + m_actions.clear(); + if (!userData) + return; + + GVariantIter iter; + g_variant_iter_init(&iter, userData); + m_actions.reserveInitialCapacity(g_variant_iter_n_children(&iter)); + + uint32_t item; + while (g_variant_iter_next(&iter, "u", &item)) + m_actions.uncheckedAppend(static_cast<WebKitContextMenuAction>(item)); + } + + bool contextMenu(WebKitContextMenu* menu, GdkEvent*, WebKitHitTestResult*) + { + deserializeContextMenuFromUserData(webkit_context_menu_get_user_data(menu)); + GList* items = webkit_context_menu_get_items(menu); + g_assert_cmpuint(g_list_length(items), ==, m_actions.size()); + + unsigned actionIndex = 0; + for (GList* it = items; it; it = g_list_next(it)) { + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(it->data); + g_assert_cmpuint(webkit_context_menu_item_get_stock_action(item), ==, m_actions[actionIndex++]); + } + + quitMainLoop(); + + return true; + } + + Vector<WebKitContextMenuAction> m_actions; +}; + +static void testContextMenuWebExtensionMenu(ContextMenuWebExtensionTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + test->loadHtml("<html><body>WebKitGTK+ Context menu tests<br>" + "<a style='position:absolute; left:1; top:10' href='http://www.webkitgtk.org'>WebKitGTK+ Website</a></body></html>", + "ContextMenuTestDefault"); + test->waitUntilLoadFinished(); + + // Default context menu. + test->showContextMenuAtPositionAndWaitUntilFinished(1, 1); + g_assert_cmpuint(test->m_actions.size(), ==, 4); + g_assert_cmpuint(test->m_actions[0], ==, WEBKIT_CONTEXT_MENU_ACTION_GO_BACK); + g_assert_cmpuint(test->m_actions[1], ==, WEBKIT_CONTEXT_MENU_ACTION_GO_FORWARD); + g_assert_cmpuint(test->m_actions[2], ==, WEBKIT_CONTEXT_MENU_ACTION_STOP); + g_assert_cmpuint(test->m_actions[3], ==, WEBKIT_CONTEXT_MENU_ACTION_RELOAD); + + // Link menu. + test->showContextMenuAtPositionAndWaitUntilFinished(1, 11); + g_assert_cmpuint(test->m_actions.size(), ==, 4); + g_assert_cmpuint(test->m_actions[0], ==, WEBKIT_CONTEXT_MENU_ACTION_OPEN_LINK); + g_assert_cmpuint(test->m_actions[1], ==, WEBKIT_CONTEXT_MENU_ACTION_OPEN_LINK_IN_NEW_WINDOW); + g_assert_cmpuint(test->m_actions[2], ==, WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_LINK_TO_DISK); + g_assert_cmpuint(test->m_actions[3], ==, WEBKIT_CONTEXT_MENU_ACTION_COPY_LINK_TO_CLIPBOARD); + + // Custom menu. + test->loadHtml("<html><body></body></html>", "ContextMenuTestCustom"); + test->showContextMenuAndWaitUntilFinished(); + g_assert_cmpuint(test->m_actions.size(), ==, 4); + g_assert_cmpuint(test->m_actions[0], ==, WEBKIT_CONTEXT_MENU_ACTION_STOP); + g_assert_cmpuint(test->m_actions[1], ==, WEBKIT_CONTEXT_MENU_ACTION_RELOAD); + g_assert_cmpuint(test->m_actions[2], ==, WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION); + g_assert_cmpuint(test->m_actions[3], ==, WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT); + + // Menu cleared by the web process. + test->loadHtml("<html><body></body></html>", "ContextMenuTestClear"); + test->showContextMenuAndWaitUntilFinished(); + g_assert_cmpuint(test->m_actions.size(), ==, 0); +} + +class ContextMenuWebExtensionNodeTest: public ContextMenuTest { +public: + MAKE_GLIB_TEST_FIXTURE(ContextMenuWebExtensionNodeTest); + + struct Node { + enum { + NodeUnknown = 0, + NodeElement = 1, + NodeText = 3 + }; + typedef unsigned Type; + + CString name; + Type type; + CString contents; + CString parentName; + }; + + void deserializeNodeFromUserData(GVariant* userData) + { + GVariantIter iter; + g_variant_iter_init(&iter, userData); + + const char* key; + GVariant* value; + while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) { + if (!strcmp(key, "Name") && g_variant_classify(value) == G_VARIANT_CLASS_STRING) + m_node.name = g_variant_get_string(value, nullptr); + else if (!strcmp(key, "Type") && g_variant_classify(value) == G_VARIANT_CLASS_UINT32) + m_node.type = g_variant_get_uint32(value); + else if (!strcmp(key, "Contents") && g_variant_classify(value) == G_VARIANT_CLASS_STRING) + m_node.contents = g_variant_get_string(value, nullptr); + else if (!strcmp(key, "Parent") && g_variant_classify(value) == G_VARIANT_CLASS_STRING) + m_node.parentName = g_variant_get_string(value, nullptr); + g_variant_unref(value); + } + } + + bool contextMenu(WebKitContextMenu* menu, GdkEvent*, WebKitHitTestResult*) + { + deserializeNodeFromUserData(webkit_context_menu_get_user_data(menu)); + quitMainLoop(); + + return true; + } + + Node m_node; +}; + +static void testContextMenuWebExtensionNode(ContextMenuWebExtensionNodeTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + test->loadHtml("<html><body><p style='position:absolute; left:1; top:1'>WebKitGTK+ Context menu tests</p><br>" + "<a style='position:absolute; left:1; top:100' href='http://www.webkitgtk.org'>WebKitGTK+ Website</a></body></html>", + "ContextMenuTestNode"); + test->waitUntilLoadFinished(); + + test->showContextMenuAtPositionAndWaitUntilFinished(0, 0); + g_assert_cmpstr(test->m_node.name.data(), ==, "HTML"); + g_assert_cmpuint(test->m_node.type, ==, ContextMenuWebExtensionNodeTest::Node::NodeElement); + g_assert_cmpstr(test->m_node.contents.data(), ==, "WebKitGTK+ Context menu testsWebKitGTK+ Website"); + g_assert_cmpstr(test->m_node.parentName.data(), ==, "#document"); + + test->showContextMenuAtPositionAndWaitUntilFinished(1, 20); + g_assert_cmpstr(test->m_node.name.data(), ==, "#text"); + g_assert_cmpuint(test->m_node.type, ==, ContextMenuWebExtensionNodeTest::Node::NodeText); + g_assert_cmpstr(test->m_node.contents.data(), ==, "WebKitGTK+ Context menu tests"); + g_assert_cmpstr(test->m_node.parentName.data(), ==, "P"); + + // Link menu. + test->showContextMenuAtPositionAndWaitUntilFinished(1, 101); + g_assert_cmpstr(test->m_node.name.data(), ==, "#text"); + g_assert_cmpuint(test->m_node.type, ==, ContextMenuWebExtensionNodeTest::Node::NodeText); + g_assert_cmpstr(test->m_node.contents.data(), ==, "WebKitGTK+ Website"); + g_assert_cmpstr(test->m_node.parentName.data(), ==, "A"); +} + +void beforeAll() +{ + ContextMenuDefaultTest::add("WebKitWebView", "default-menu", testContextMenuDefaultMenu); + ContextMenuCustomTest::add("WebKitWebView", "populate-menu", testContextMenuPopulateMenu); + ContextMenuCustomFullTest::add("WebKitWebView", "custom-menu", testContextMenuCustomMenu); + ContextMenuDisabledTest::add("WebKitWebView", "disable-menu", testContextMenuDisableMenu); + ContextMenuSubmenuTest::add("WebKitWebView", "submenu", testContextMenuSubMenu); + ContextMenuDismissedTest::add("WebKitWebView", "menu-dismissed", testContextMenuDismissed); + ContextMenuSmartSeparatorsTest::add("WebKitWebView", "smart-separators", testContextMenuSmartSeparators); + ContextMenuWebExtensionTest::add("WebKitWebPage", "context-menu", testContextMenuWebExtensionMenu); + ContextMenuWebExtensionNodeTest::add("WebKitWebPage", "context-menu-node", testContextMenuWebExtensionNode); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestCookieManager.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestCookieManager.cpp new file mode 100644 index 000000000..1e842cd04 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestCookieManager.cpp @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebKitTestServer.h" +#include "WebViewTest.h" +#include <glib/gstdio.h> + +static WebKitTestServer* kServer; + +static const char* kFirstPartyDomain = "127.0.0.1"; +static const char* kThirdPartyDomain = "localhost"; +static const char* kIndexHtmlFormat = + "<html><body>" + " <p>WebKitGTK+ Cookie Manager test</p>" + " <img src='http://localhost:%u/image.png' width=5 height=5></img>" + "</body></html>"; + +class CookieManagerTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(CookieManagerTest); + + static void cookiesChangedCallback(WebKitCookieManager*, CookieManagerTest* test) + { + test->m_cookiesChanged = true; + if (test->m_finishLoopWhenCookiesChange) + g_main_loop_quit(test->m_mainLoop); + } + + CookieManagerTest() + : WebViewTest() + , m_cookieManager(webkit_web_context_get_cookie_manager(webkit_web_view_get_context(m_webView))) + , m_acceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY) + , m_domains(0) + , m_cookiesChanged(false) + , m_finishLoopWhenCookiesChange(false) + { + g_signal_connect(m_cookieManager, "changed", G_CALLBACK(cookiesChangedCallback), this); + } + + ~CookieManagerTest() + { + g_strfreev(m_domains); + g_signal_handlers_disconnect_matched(m_cookieManager, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + if (m_cookiesTextFile) + g_unlink(m_cookiesTextFile.get()); + if (m_cookiesSQLiteFile) + g_unlink(m_cookiesSQLiteFile.get()); + } + + void setPersistentStorage(WebKitCookiePersistentStorage storage) + { + const char* filename = 0; + switch (storage) { + case WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT: + if (!m_cookiesTextFile) + m_cookiesTextFile.reset(g_build_filename(Test::dataDirectory(), "cookies.txt", nullptr)); + filename = m_cookiesTextFile.get(); + break; + case WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE: + if (!m_cookiesSQLiteFile) + m_cookiesSQLiteFile.reset(g_build_filename(Test::dataDirectory(), "cookies.db", nullptr)); + filename = m_cookiesSQLiteFile.get(); + break; + default: + g_assert_not_reached(); + } + webkit_cookie_manager_set_persistent_storage(m_cookieManager, filename, storage); + } + + static void getAcceptPolicyReadyCallback(GObject* object, GAsyncResult* result, gpointer userData) + { + GUniqueOutPtr<GError> error; + WebKitCookieAcceptPolicy policy = webkit_cookie_manager_get_accept_policy_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr()); + g_assert(!error.get()); + + CookieManagerTest* test = static_cast<CookieManagerTest*>(userData); + test->m_acceptPolicy = policy; + g_main_loop_quit(test->m_mainLoop); + } + + WebKitCookieAcceptPolicy getAcceptPolicy() + { + m_acceptPolicy = WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY; + webkit_cookie_manager_get_accept_policy(m_cookieManager, 0, getAcceptPolicyReadyCallback, this); + g_main_loop_run(m_mainLoop); + + return m_acceptPolicy; + } + + void setAcceptPolicy(WebKitCookieAcceptPolicy policy) + { + webkit_cookie_manager_set_accept_policy(m_cookieManager, policy); + } + + static void getDomainsReadyCallback(GObject* object, GAsyncResult* result, gpointer userData) + { + GUniqueOutPtr<GError> error; + char** domains = webkit_cookie_manager_get_domains_with_cookies_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr()); + g_assert(!error.get()); + + CookieManagerTest* test = static_cast<CookieManagerTest*>(userData); + test->m_domains = domains; + g_main_loop_quit(test->m_mainLoop); + } + + char** getDomains() + { + g_strfreev(m_domains); + m_domains = 0; + webkit_cookie_manager_get_domains_with_cookies(m_cookieManager, 0, getDomainsReadyCallback, this); + g_main_loop_run(m_mainLoop); + + return m_domains; + } + + bool hasDomain(const char* domain) + { + if (!m_domains) + return false; + + for (size_t i = 0; m_domains[i]; ++i) + if (g_str_equal(m_domains[i], domain)) + return true; + return false; + } + + void deleteCookiesForDomain(const char* domain) + { + webkit_cookie_manager_delete_cookies_for_domain(m_cookieManager, domain); + } + + void deleteAllCookies() + { + webkit_cookie_manager_delete_all_cookies(m_cookieManager); + } + + void waitUntilCookiesChanged() + { + m_cookiesChanged = false; + m_finishLoopWhenCookiesChange = true; + g_main_loop_run(m_mainLoop); + m_finishLoopWhenCookiesChange = false; + } + + WebKitCookieManager* m_cookieManager; + WebKitCookieAcceptPolicy m_acceptPolicy; + char** m_domains; + bool m_cookiesChanged; + bool m_finishLoopWhenCookiesChange; + GUniquePtr<char> m_cookiesTextFile; + GUniquePtr<char> m_cookiesSQLiteFile; +}; + +static void testCookieManagerAcceptPolicy(CookieManagerTest* test, gconstpointer) +{ + // Default policy is NO_THIRD_PARTY. + g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY); + test->loadURI(kServer->getURIForPath("/index.html").data()); + test->waitUntilLoadFinished(); + char** domains = test->getDomains(); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 1); + g_assert_cmpstr(domains[0], ==, kFirstPartyDomain); + test->deleteAllCookies(); + + test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); + g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); + test->loadURI(kServer->getURIForPath("/index.html").data()); + test->waitUntilLoadFinished(); + domains = test->getDomains(); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 2); + g_assert(test->hasDomain(kFirstPartyDomain)); + g_assert(test->hasDomain(kThirdPartyDomain)); + test->deleteAllCookies(); + + test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER); + g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NEVER); + test->loadURI(kServer->getURIForPath("/index.html").data()); + test->waitUntilLoadFinished(); + domains = test->getDomains(); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 0); +} + +static void testCookieManagerDeleteCookies(CookieManagerTest* test, gconstpointer) +{ + test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); + test->loadURI(kServer->getURIForPath("/index.html").data()); + test->waitUntilLoadFinished(); + g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2); + + // Delete first party cookies. + test->deleteCookiesForDomain(kFirstPartyDomain); + g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1); + + // Delete third party cookies. + test->deleteCookiesForDomain(kThirdPartyDomain); + g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); + + test->loadURI(kServer->getURIForPath("/index.html").data()); + test->waitUntilLoadFinished(); + g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2); + + // Delete all cookies. + test->deleteAllCookies(); + g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); +} + +static void testCookieManagerCookiesChanged(CookieManagerTest* test, gconstpointer) +{ + g_assert(!test->m_cookiesChanged); + test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); + test->loadURI(kServer->getURIForPath("/index.html").data()); + test->waitUntilLoadFinished(); + g_assert(test->m_cookiesChanged); + + test->deleteCookiesForDomain(kFirstPartyDomain); + test->waitUntilCookiesChanged(); + g_assert(test->m_cookiesChanged); + + test->deleteAllCookies(); + test->waitUntilCookiesChanged(); + g_assert(test->m_cookiesChanged); +} + +static void testCookieManagerPersistentStorage(CookieManagerTest* test, gconstpointer) +{ + test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); + + // Text storage using a new file. + test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); + char** domains = test->getDomains(); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 0); + + test->loadURI(kServer->getURIForPath("/index.html").data()); + test->waitUntilLoadFinished(); + g_assert(test->m_cookiesChanged); + domains = test->getDomains(); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 2); + + + // SQLite storage using a new file. + test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE); + domains = test->getDomains(); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 0); + + test->loadURI(kServer->getURIForPath("/index.html").data()); + test->waitUntilLoadFinished(); + g_assert(test->m_cookiesChanged); + domains = test->getDomains(); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 2); + + // Text storage using an existing file. + test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); + domains = test->getDomains(); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 2); + test->deleteAllCookies(); + g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); + + // SQLite storage with an existing file. + test->setPersistentStorage(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE); + domains = test->getDomains(); + g_assert(domains); + g_assert_cmpint(g_strv_length(domains), ==, 2); + test->deleteAllCookies(); + g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0); +} + +static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + soup_message_set_status(message, SOUP_STATUS_OK); + if (g_str_equal(path, "/index.html")) { + char* indexHtml = g_strdup_printf(kIndexHtmlFormat, soup_server_get_port(server)); + soup_message_headers_replace(message->response_headers, "Set-Cookie", "foo=bar; Max-Age=60"); + soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, indexHtml, strlen(indexHtml)); + } else if (g_str_equal(path, "/image.png")) + soup_message_headers_replace(message->response_headers, "Set-Cookie", "baz=qux; Max-Age=60"); + else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); + soup_message_body_complete(message->response_body); +} + +void beforeAll() +{ + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + + CookieManagerTest::add("WebKitCookieManager", "accept-policy", testCookieManagerAcceptPolicy); + CookieManagerTest::add("WebKitCookieManager", "delete-cookies", testCookieManagerDeleteCookies); + CookieManagerTest::add("WebKitCookieManager", "cookies-changed", testCookieManagerCookiesChanged); + CookieManagerTest::add("WebKitCookieManager", "persistent-storage", testCookieManagerPersistentStorage); +} + +void afterAll() +{ + delete kServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMDOMWindow.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMDOMWindow.cpp new file mode 100644 index 000000000..98c6e1064 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMDOMWindow.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebProcessTestRunner.h" +#include "WebViewTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + +#define HTML_DOCUMENT "<html><head><title></title></head><style type='text/css'>#test { font-size: 16px; }</style><body><p id='test'>test</p></body></html>" + +typedef struct { + gboolean loaded; + gboolean clicked; + WebProcessTestRunner* testRunner; + WebViewTest* test; +} DomDomWindowTestStatus; + +static DomDomWindowTestStatus status; + +static void signalsNotifyCallback(const gchar *key, const gchar *value, gconstpointer) +{ + if (g_str_equal(key, "ready")) { + // The document was already loaded in the webprocess, and its "load" + // signal couldn't be captured on time (was issued before the test + // started). We load it again to force a new "load" signal in the + // webprocess, which will be captured this time + status.test->loadHtml(HTML_DOCUMENT, 0); + } + + if (g_str_equal(key, "loaded")) { + status.loaded = TRUE; + status.test->showInWindowAndWaitUntilMapped(); + + // Click in a known location where the text is + status.test->clickMouseButton(20, 18, 1, 0); + } + + if (g_str_equal(key, "clicked")) + status.clicked = TRUE; + + if (g_str_equal(key, "finish")) { + status.test = 0; + status.testRunner->finishTest(status.loaded && status.clicked); + } +} + +static void dispatchEventNotifyCallback(const gchar *key, const gchar *value, gconstpointer) +{ + if (g_str_equal(key, "ready")) { + // The document was already loaded in the webprocess, and its "load" + // signal couldn't be captured on time (was issued before the test + // started). We load it again to force a new "load" signal in the + // webprocess, which will be captured this time + status.test->loadHtml(HTML_DOCUMENT, 0); + } + + if (g_str_equal(key, "loaded")) + status.loaded = TRUE; + + if (g_str_equal(key, "clicked")) + status.clicked = TRUE; + + if (g_str_equal(key, "finish")) { + status.test = 0; + status.testRunner->finishTest(status.loaded && status.clicked); + } +} + +static void testWebKitDOMDOMWindowSignals(WebViewTest* test, gconstpointer) +{ + status.loaded = FALSE; + status.clicked = FALSE; + status.test = test; + + status.testRunner->setNotifyCallback(G_CALLBACK(signalsNotifyCallback), 0); + + // The HTML document will we loaded later, when the test is "ready" because + // we want to test the "load" signal + + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add(&builder, "{sv}", "pageID", g_variant_new_uint64(webkit_web_view_get_page_id(status.test->m_webView))); + status.testRunner->runTestAndWait("WebKitDOMDOMWindow", "signals", g_variant_builder_end(&builder)); + g_assert(status.testRunner->getTestResult()); +} + +static void testWebKitDOMDOMWindowDispatchEvent(WebViewTest* test, gconstpointer) +{ + status.loaded = FALSE; + status.clicked = FALSE; + status.test = test; + + status.testRunner->setNotifyCallback(G_CALLBACK(dispatchEventNotifyCallback), 0); + + // The HTML document will we loaded later, when the test is "ready" because + // we want to test the "load" signal + + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add(&builder, "{sv}", "pageID", g_variant_new_uint64(webkit_web_view_get_page_id(status.test->m_webView))); + status.testRunner->runTestAndWait("WebKitDOMDOMWindow", "dispatch-event", g_variant_builder_end(&builder)); + g_assert(status.testRunner->getTestResult()); +} + +static void testWebKitDOMDOMWindowGetComputedStyle(WebViewTest* test, gconstpointer) +{ + status.loaded = FALSE; + status.clicked = FALSE; + status.test = test; + + static const char* testHTML = HTML_DOCUMENT; + status.test->loadHtml(testHTML, 0); + status.test->waitUntilLoadFinished(); + + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add(&builder, "{sv}", "pageID", g_variant_new_uint64(webkit_web_view_get_page_id(status.test->m_webView))); + g_assert(status.testRunner->runTest("WebKitDOMDOMWindow", "get-computed-style", g_variant_builder_end(&builder))); +} + +void beforeAll() +{ + status.testRunner = new WebProcessTestRunner(); + webkit_web_context_set_web_extensions_directory(webkit_web_context_get_default(), WEBKIT_TEST_WEB_EXTENSIONS_DIR); + + WebViewTest::add("WebKitDOMDOMWindow", "signals", testWebKitDOMDOMWindowSignals); + WebViewTest::add("WebKitDOMDOMWindow", "dispatch-event", testWebKitDOMDOMWindowDispatchEvent); + WebViewTest::add("WebKitDOMDOMWindow", "get-computed-style", testWebKitDOMDOMWindowGetComputedStyle); +} + +void afterAll() +{ + delete status.testRunner; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNode.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNode.cpp new file mode 100644 index 000000000..886356b7e --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNode.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebViewTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + +static void testWebKitDOMNodeHierarchyNavigation(WebViewTest* test, gconstpointer) +{ + static const char* testHTML = "<html><head><title>This is the title</title></head><body><p>1</p><p>2</p><p>3</p></body></html>"; + test->loadHtml(testHTML, 0); + test->waitUntilLoadFinished(); + + g_assert(test->runWebProcessTest("WebKitDOMNode", "hierarchy-navigation")); +} + +static void testWebKitDOMNodeInsertion(WebViewTest* test, gconstpointer) +{ + static const char* testHTML = "<html><body></body></html>"; + test->loadHtml(testHTML, 0); + test->waitUntilLoadFinished(); + + g_assert(test->runWebProcessTest("WebKitDOMNode", "insertion")); +} + +static void prepareDOMForTagNamesTests(WebViewTest* test) +{ + static const char* testHTML = "<html><head></head><body>" + "<video id='video' preload='none'>" + " <source src='movie.ogg' type='video/ogg'>" + " Your browser does not support the video tag." + "</video>" + "<video id='video2' preload='none'>" + " <source src='movie.ogg' type='video/ogg'>" + " Your browser does not support the video tag." + "</video>" + "<input type='hidden' id='test' name='finish' value='false'></body></html>"; + test->loadHtml(testHTML, nullptr); + test->waitUntilLoadFinished(); +} + +static void testWebKitDOMNodeTagNamesNodeList(WebViewTest* test, gconstpointer) +{ + prepareDOMForTagNamesTests(test); + g_assert(test->runWebProcessTest("WebKitDOMNode", "tag-names-node-list")); +} + +static void testWebKitDOMNodeTagNamesHTMLCollection(WebViewTest* test, gconstpointer) +{ + prepareDOMForTagNamesTests(test); + g_assert(test->runWebProcessTest("WebKitDOMNode", "tag-names-html-collection")); +} + +static void testWebKitDOMObjectCache(WebViewTest* test, gconstpointer) +{ + static const char* testHTML = "<html><body><div id='container'><p>DOM Cache test</p><a id='link href='#'>link</a></div></body></html>"; + + // Run the test 3 times to make sure the DOM objects are correctly released when the + // document is detached from the frame for every new document created. + for (unsigned i = 0; i < 3; ++i) { + test->loadHtml(testHTML, nullptr); + test->waitUntilLoadFinished(); + + g_assert(test->runWebProcessTest("WebKitDOMNode", "dom-cache")); + } +} + + +void beforeAll() +{ + WebViewTest::add("WebKitDOMNode", "hierarchy-navigation", testWebKitDOMNodeHierarchyNavigation); + WebViewTest::add("WebKitDOMNode", "insertion", testWebKitDOMNodeInsertion); + WebViewTest::add("WebKitDOMNode", "tag-names-node-list", testWebKitDOMNodeTagNamesNodeList); + WebViewTest::add("WebKitDOMNode", "tag-names-html-collection", testWebKitDOMNodeTagNamesHTMLCollection); + WebViewTest::add("WebKitDOMNode", "dom-cache", testWebKitDOMObjectCache); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNodeFilter.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNodeFilter.cpp new file mode 100644 index 000000000..812946153 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMNodeFilter.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebViewTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + +static const char* testHTML = "<html id='root'><head><title>DOMNodeTreeWalker</title></head>" + "<body><input type='button' name='push' value='push'><input type='button' name='clear' value='clear'><br></body></html>"; + +static void runTest(WebViewTest* test, const char* name) +{ + test->loadHtml(testHTML, nullptr); + test->waitUntilLoadFinished(); + + g_assert(test->runWebProcessTest("WebKitDOMNodeFilter", name)); +} + +static void testWebKitDOMNodeFilterTreeWalker(WebViewTest* test, gconstpointer) +{ + runTest(test, "tree-walker"); +} + +static void testWebKitDOMNodeFilterNodeIterator(WebViewTest* test, gconstpointer) +{ + runTest(test, "node-iterator"); +} + +void beforeAll() +{ + WebViewTest::add("WebKitDOMNodeFilter", "tree-walker", testWebKitDOMNodeFilterTreeWalker); + WebViewTest::add("WebKitDOMNodeFilter", "node-iterator", testWebKitDOMNodeFilterNodeIterator); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMXPathNSResolver.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMXPathNSResolver.cpp new file mode 100644 index 000000000..ff9a77192 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDOMXPathNSResolver.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebViewTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + +static void testWebKitDOMXPathNSResolverNative(WebViewTest* test, gconstpointer) +{ + static const char* nativeXML = "<root xmlns:foo='http://www.example.org'><foo:child>SUCCESS</foo:child></root>"; + GRefPtr<GBytes> bytes = adoptGRef(g_bytes_new_static(nativeXML, strlen(nativeXML))); + test->loadBytes(bytes.get(), "text/xml", nullptr, nullptr); + test->waitUntilLoadFinished(); + g_assert(test->runWebProcessTest("WebKitDOMXPathNSResolver", "native")); +} + +static void testWebKitDOMXPathNSResolverCustom(WebViewTest* test, gconstpointer) +{ + static const char* customXML = "<root xmlns='http://www.example.com'><child>SUCCESS</child></root>"; + GRefPtr<GBytes> bytes = adoptGRef(g_bytes_new_static(customXML, strlen(customXML))); + test->loadBytes(bytes.get(), "text/xml", nullptr, nullptr); + test->waitUntilLoadFinished(); + g_assert(test->runWebProcessTest("WebKitDOMXPathNSResolver", "custom")); +} + +void beforeAll() +{ + WebViewTest::add("WebKitDOMXPathNSResolver", "native", testWebKitDOMXPathNSResolverNative); + WebViewTest::add("WebKitDOMXPathNSResolver", "custom", testWebKitDOMXPathNSResolverCustom); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDownloads.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDownloads.cpp new file mode 100644 index 000000000..b4f21a130 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestDownloads.cpp @@ -0,0 +1,633 @@ +/* + * Copyright (C) 2012, 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebKitTestServer.h" +#include "WebViewTest.h" +#include <glib/gstdio.h> +#include <gtk/gtk.h> +#include <libsoup/soup.h> +#include <string.h> +#include <webkit2/webkit2.h> +#include <wtf/Vector.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> +#include <wtf/text/CString.h> + +class DownloadTest: public Test { +public: + MAKE_GLIB_TEST_FIXTURE(DownloadTest); + + enum DownloadEvent { + Started, + ReceivedResponse, + CreatedDestination, + ReceivedData, + Failed, + Finished + }; + + static void receivedResponseCallback(WebKitDownload* download, GParamSpec*, DownloadTest* test) + { + g_assert(webkit_download_get_response(download)); + test->receivedResponse(download); + } + + static void createdDestinationCallback(WebKitDownload* download, const gchar* destination, DownloadTest* test) + { + g_assert(webkit_download_get_destination(download)); + g_assert_cmpstr(webkit_download_get_destination(download), ==, destination); + GRefPtr<GFile> file = adoptGRef(g_file_new_for_uri(destination)); + g_assert(g_file_query_exists(file.get(), nullptr)); + test->createdDestination(download, destination); + } + + static void receivedDataCallback(WebKitDownload* download, guint64 dataLength, DownloadTest* test) + { + test->receivedData(download, dataLength); + } + + static void finishedCallback(WebKitDownload* download, DownloadTest* test) + { + test->finished(download); + } + + static void failedCallback(WebKitDownload* download, GError* error, DownloadTest* test) + { + g_assert(error); + + const char* destinationURI = webkit_download_get_destination(download); + if (destinationURI) { + GUniquePtr<char> tempFileURI(g_strconcat(destinationURI, ".wkdownload", nullptr)); + GRefPtr<GFile> tempFile = adoptGRef(g_file_new_for_uri(tempFileURI.get())); + g_assert(!g_file_query_exists(tempFile.get(), nullptr)); + } + + test->failed(download, error); + } + + static gboolean decideDestinationCallback(WebKitDownload* download, const gchar* suggestedFilename, DownloadTest* test) + { + g_assert(suggestedFilename); + test->decideDestination(download, suggestedFilename); + return TRUE; + } + + static void downloadStartedCallback(WebKitWebContext* context, WebKitDownload* download, DownloadTest* test) + { + g_assert(webkit_download_get_request(download)); + test->started(download); + g_signal_connect(download, "notify::response", G_CALLBACK(receivedResponseCallback), test); + g_signal_connect(download, "created-destination", G_CALLBACK(createdDestinationCallback), test); + g_signal_connect(download, "received-data", G_CALLBACK(receivedDataCallback), test); + g_signal_connect(download, "finished", G_CALLBACK(finishedCallback), test); + g_signal_connect(download, "failed", G_CALLBACK(failedCallback), test); + g_signal_connect(download, "decide-destination", G_CALLBACK(decideDestinationCallback), test); + } + + DownloadTest() + : m_mainLoop(g_main_loop_new(nullptr, TRUE)) + , m_downloadSize(0) + , m_allowOverwrite(false) + { + g_signal_connect(m_webContext.get(), "download-started", G_CALLBACK(downloadStartedCallback), this); + } + + ~DownloadTest() + { + g_signal_handlers_disconnect_matched(m_webContext.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + g_main_loop_unref(m_mainLoop); + } + + virtual void started(WebKitDownload* download) + { + m_downloadSize = 0; + m_downloadEvents.clear(); + m_downloadEvents.append(Started); + } + + virtual void receivedResponse(WebKitDownload* download) + { + m_downloadEvents.append(ReceivedResponse); + } + + virtual void createdDestination(WebKitDownload* download, const char* destination) + { + m_downloadEvents.append(CreatedDestination); + } + + virtual void receivedData(WebKitDownload* download, guint64 dataLength) + { + m_downloadSize += dataLength; + if (!m_downloadEvents.contains(ReceivedData)) + m_downloadEvents.append(ReceivedData); + } + + virtual void finished(WebKitDownload* download) + { + g_assert_cmpuint(m_downloadSize, ==, webkit_download_get_received_data_length(download)); + m_downloadEvents.append(Finished); + g_main_loop_quit(m_mainLoop); + } + + virtual void failed(WebKitDownload* download, GError* error) + { + m_downloadEvents.append(Failed); + } + + virtual void decideDestination(WebKitDownload* download, const gchar* suggestedFilename) + { + GUniquePtr<char> destination(g_build_filename(Test::dataDirectory(), suggestedFilename, nullptr)); + GUniquePtr<char> destinationURI(g_filename_to_uri(destination.get(), 0, 0)); + webkit_download_set_destination(download, destinationURI.get()); + } + + WebKitDownload* downloadURIAndWaitUntilFinishes(const CString& requestURI) + { + WebKitDownload* download = webkit_web_context_download_uri(m_webContext.get(), requestURI.data()); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download)); + + g_assert(!webkit_download_get_allow_overwrite(download)); + webkit_download_set_allow_overwrite(download, m_allowOverwrite); + g_assert(webkit_download_get_allow_overwrite(download) == m_allowOverwrite); + + WebKitURIRequest* request = webkit_download_get_request(download); + g_assert(request); + ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, requestURI); + + g_main_loop_run(m_mainLoop); + + return download; + } + + void checkDestinationAndDeleteFile(WebKitDownload* download, const char* expectedName) + { + if (!webkit_download_get_destination(download)) + return; + GRefPtr<GFile> destFile = adoptGRef(g_file_new_for_uri(webkit_download_get_destination(download))); + GUniquePtr<char> destBasename(g_file_get_basename(destFile.get())); + g_assert_cmpstr(destBasename.get(), ==, expectedName); + + g_file_delete(destFile.get(), 0, 0); + } + + GMainLoop* m_mainLoop; + Vector<DownloadEvent> m_downloadEvents; + guint64 m_downloadSize; + bool m_allowOverwrite; +}; + +static GRefPtr<WebKitDownload> downloadLocalFileSuccessfully(DownloadTest* test, const char* filename) +{ + GUniquePtr<char> sourcePath(g_build_filename(Test::getResourcesDir().data(), filename, nullptr)); + GRefPtr<GFile> source = adoptGRef(g_file_new_for_path(sourcePath.get())); + GRefPtr<GFileInfo> sourceInfo = adoptGRef(g_file_query_info(source.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), 0, 0)); + GUniquePtr<char> sourceURI(g_file_get_uri(source.get())); + GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes(sourceURI.get())); + g_assert(!webkit_download_get_web_view(download.get())); + + Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents; + g_assert_cmpint(events.size(), ==, 5); + g_assert_cmpint(events[0], ==, DownloadTest::Started); + g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse); + g_assert_cmpint(events[2], ==, DownloadTest::CreatedDestination); + g_assert_cmpint(events[3], ==, DownloadTest::ReceivedData); + g_assert_cmpint(events[4], ==, DownloadTest::Finished); + + WebKitURIRequest* request = webkit_download_get_request(download.get()); + g_assert(request); + g_assert_cmpstr(webkit_uri_request_get_uri(request), ==, sourceURI.get()); + + g_assert_cmpint(test->m_downloadSize, ==, g_file_info_get_size(sourceInfo.get())); + g_assert(webkit_download_get_destination(download.get())); + g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 1); + + return download; +} + +static void testDownloadLocalFile(DownloadTest* test, gconstpointer) +{ + static const char* filename = "test.pdf"; + GRefPtr<WebKitDownload> download = downloadLocalFileSuccessfully(test, filename); + test->checkDestinationAndDeleteFile(download.get(), filename); +} + +static void createFileAtDestination(const char* filename) +{ + GUniquePtr<char> path(g_build_filename(Test::dataDirectory(), filename, nullptr)); + GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path.get())); + GUniqueOutPtr<GError> error; + g_file_create(file.get(), G_FILE_CREATE_NONE, nullptr, &error.outPtr()); + g_assert(!error); + g_assert(g_file_query_exists(file.get(), nullptr)); +} + +static void testDownloadOverwriteDestinationAllowed(DownloadTest* test, gconstpointer) +{ + static const char* filename = "test.pdf"; + createFileAtDestination(filename); + + test->m_allowOverwrite = true; + GRefPtr<WebKitDownload> download = downloadLocalFileSuccessfully(test, filename); + test->checkDestinationAndDeleteFile(download.get(), filename); +} + +class DownloadErrorTest: public DownloadTest { +public: + MAKE_GLIB_TEST_FIXTURE(DownloadErrorTest); + + enum ExpectedError { + NetworkError, + DownloadCancelled, + InvalidDestination, + DestinationExists + }; + + DownloadErrorTest() + : m_expectedError(NetworkError) + { + } + + void receivedResponse(WebKitDownload* download) + { + DownloadTest::receivedResponse(download); + } + + void createdDestination(WebKitDownload* download, const char* destination) + { + if (m_expectedError == DownloadCancelled) + webkit_download_cancel(download); + else + g_assert_not_reached(); + } + + void failed(WebKitDownload* download, GError* error) + { + g_assert(g_error_matches(error, WEBKIT_DOWNLOAD_ERROR, expectedErrorToWebKitDownloadError(m_expectedError))); + DownloadTest::failed(download, error); + } + + void decideDestination(WebKitDownload* download, const gchar* suggestedFilename) + { + if (m_expectedError != InvalidDestination) { + DownloadTest::decideDestination(download, suggestedFilename); + return; + } + webkit_download_set_destination(download, "file:///foo/bar"); + } + + static WebKitDownloadError expectedErrorToWebKitDownloadError(ExpectedError expected) + { + switch (expected) { + case NetworkError: + return WEBKIT_DOWNLOAD_ERROR_NETWORK; + case DownloadCancelled: + return WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER; + case InvalidDestination: + return WEBKIT_DOWNLOAD_ERROR_DESTINATION; + case DestinationExists: + return WEBKIT_DOWNLOAD_ERROR_DESTINATION; + default: + g_assert_not_reached(); + } + } + + ExpectedError m_expectedError; +}; + +static void testDownloadOverwriteDestinationDisallowed(DownloadErrorTest* test, gconstpointer) +{ + static const char* filename = "test.pdf"; + createFileAtDestination(filename); + + test->m_expectedError = DownloadErrorTest::DestinationExists; + GUniquePtr<char> sourcePath(g_build_filename(Test::getResourcesDir().data(), filename, nullptr)); + GRefPtr<GFile> source = adoptGRef(g_file_new_for_path(sourcePath.get())); + GUniquePtr<char> sourceURI(g_file_get_uri(source.get())); + GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes(sourceURI.get())); + g_assert(!webkit_download_get_web_view(download.get())); + + Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents; + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, DownloadTest::Started); + g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse); + g_assert_cmpint(events[2], ==, DownloadTest::Failed); + g_assert_cmpint(events[3], ==, DownloadTest::Finished); + g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 0); + + test->checkDestinationAndDeleteFile(download.get(), filename); +} + +static void testDownloadLocalFileError(DownloadErrorTest* test, gconstpointer) +{ + test->m_expectedError = DownloadErrorTest::NetworkError; + GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes("file:///foo/bar")); + g_assert(!webkit_download_get_web_view(download.get())); + + Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents; + g_assert_cmpint(events.size(), ==, 3); + g_assert_cmpint(events[0], ==, DownloadTest::Started); + g_assert_cmpint(events[1], ==, DownloadTest::Failed); + g_assert_cmpint(events[2], ==, DownloadTest::Finished); + events.clear(); + g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1); + + test->m_expectedError = DownloadErrorTest::InvalidDestination; + GUniquePtr<char> path(g_build_filename(Test::getResourcesDir().data(), "test.pdf", nullptr)); + GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path.get())); + GUniquePtr<char> uri(g_file_get_uri(file.get())); + download = adoptGRef(test->downloadURIAndWaitUntilFinishes(uri.get())); + g_assert(!webkit_download_get_web_view(download.get())); + + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, DownloadTest::Started); + g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse); + g_assert_cmpint(events[2], ==, DownloadTest::Failed); + g_assert_cmpint(events[3], ==, DownloadTest::Finished); + events.clear(); + g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1); + test->checkDestinationAndDeleteFile(download.get(), "bar"); + + test->m_expectedError = DownloadErrorTest::DownloadCancelled; + download = adoptGRef(test->downloadURIAndWaitUntilFinishes(uri.get())); + g_assert(!webkit_download_get_web_view(download.get())); + + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, DownloadTest::Started); + g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse); + g_assert_cmpint(events[2], ==, DownloadTest::Failed); + g_assert_cmpint(events[3], ==, DownloadTest::Finished); + events.clear(); + g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1); + test->checkDestinationAndDeleteFile(download.get(), "test.pdf"); +} + +static WebKitTestServer* kServer; +static const char* kServerSuggestedFilename = "webkit-downloaded-file"; + +static void addContentDispositionHTTPHeaderToResponse(SoupMessage* message) +{ + GUniquePtr<char> contentDisposition(g_strdup_printf("filename=%s", kServerSuggestedFilename)); + soup_message_headers_append(message->response_headers, "Content-Disposition", contentDisposition.get()); +} + +static gboolean writeNextChunkIdle(SoupMessage* message) +{ + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, "chunk", 5); + return FALSE; +} + +static void writeNextChunk(SoupMessage* message) +{ + g_timeout_add(100, reinterpret_cast<GSourceFunc>(writeNextChunkIdle), message); +} + +static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + soup_message_set_status(message, SOUP_STATUS_OK); + + if (g_str_equal(path, "/cancel-after-destination")) { + // Use an infinite message to make sure it's cancelled before it finishes. + soup_message_headers_set_encoding(message->response_headers, SOUP_ENCODING_CHUNKED); + addContentDispositionHTTPHeaderToResponse(message); + g_signal_connect(message, "wrote_headers", G_CALLBACK(writeNextChunk), nullptr); + g_signal_connect(message, "wrote_chunk", G_CALLBACK(writeNextChunk), nullptr); + return; + } + + GUniquePtr<char> filePath(g_build_filename(Test::getResourcesDir().data(), path, nullptr)); + char* contents; + gsize contentsLength; + if (!g_file_get_contents(filePath.get(), &contents, &contentsLength, 0)) { + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); + soup_message_body_complete(message->response_body); + return; + } + + addContentDispositionHTTPHeaderToResponse(message); + soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, contentsLength); + + soup_message_body_complete(message->response_body); +} + +static void testDownloadRemoteFile(DownloadTest* test, gconstpointer) +{ + GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/test.pdf"))); + g_assert(!webkit_download_get_web_view(download.get())); + + Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents; + g_assert_cmpint(events.size(), ==, 5); + g_assert_cmpint(events[0], ==, DownloadTest::Started); + g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse); + g_assert_cmpint(events[2], ==, DownloadTest::CreatedDestination); + g_assert_cmpint(events[3], ==, DownloadTest::ReceivedData); + g_assert_cmpint(events[4], ==, DownloadTest::Finished); + events.clear(); + + WebKitURIRequest* request = webkit_download_get_request(download.get()); + g_assert(request); + ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, kServer->getURIForPath("/test.pdf")); + + g_assert(webkit_download_get_destination(download.get())); + g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 1); + test->checkDestinationAndDeleteFile(download.get(), kServerSuggestedFilename); +} + +static void testDownloadRemoteFileError(DownloadErrorTest* test, gconstpointer) +{ + test->m_expectedError = DownloadErrorTest::NetworkError; + GRefPtr<WebKitDownload> download = adoptGRef(test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/foo"))); + g_assert(!webkit_download_get_web_view(download.get())); + + Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents; + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, DownloadTest::Started); + g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse); + g_assert_cmpint(events[2], ==, DownloadTest::Failed); + g_assert_cmpint(events[3], ==, DownloadTest::Finished); + events.clear(); + WebKitURIResponse* response = webkit_download_get_response(download.get()); + g_assert_cmpuint(webkit_uri_response_get_status_code(response), ==, 404); + g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1); + + test->m_expectedError = DownloadErrorTest::InvalidDestination; + download = adoptGRef(test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/test.pdf"))); + g_assert(!webkit_download_get_web_view(download.get())); + + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, DownloadTest::Started); + g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse); + g_assert_cmpint(events[2], ==, DownloadTest::Failed); + g_assert_cmpint(events[3], ==, DownloadTest::Finished); + events.clear(); + g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1); + test->checkDestinationAndDeleteFile(download.get(), "bar"); + + test->m_expectedError = DownloadErrorTest::DownloadCancelled; + download = adoptGRef(test->downloadURIAndWaitUntilFinishes(kServer->getURIForPath("/cancel-after-destination"))); + g_assert(!webkit_download_get_web_view(download.get())); + + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, DownloadTest::Started); + g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse); + g_assert_cmpint(events[2], ==, DownloadTest::Failed); + g_assert_cmpint(events[3], ==, DownloadTest::Finished); + events.clear(); + g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1); + // Check the intermediate file is deleted when the download is cancelled. + GUniquePtr<char> intermediateURI(g_strdup_printf("%s.wkdownload", webkit_download_get_destination(download.get()))); + GRefPtr<GFile> intermediateFile = adoptGRef(g_file_new_for_uri(intermediateURI.get())); + g_assert(!g_file_query_exists(intermediateFile.get(), nullptr)); +} + +class WebViewDownloadTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(WebViewDownloadTest); + + static void downloadStartedCallback(WebKitWebContext* context, WebKitDownload* download, WebViewDownloadTest* test) + { + test->m_download = download; + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download)); + test->quitMainLoop(); + } + + WebViewDownloadTest() + { + g_signal_connect(webkit_web_view_get_context(m_webView), "download-started", G_CALLBACK(downloadStartedCallback), this); + } + + ~WebViewDownloadTest() + { + g_signal_handlers_disconnect_matched(webkit_web_view_get_context(m_webView), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + void waitUntilDownloadStarted() + { + m_download = 0; + g_main_loop_run(m_mainLoop); + g_assert(m_download.get()); + } + + static gboolean downloadDecideDestinationCallback(WebKitDownload* download, const gchar* suggestedFilename, WebViewDownloadTest* test) + { + GUniquePtr<char> destination(g_build_filename(Test::dataDirectory(), suggestedFilename, nullptr)); + GUniquePtr<char> destinationURI(g_filename_to_uri(destination.get(), 0, 0)); + webkit_download_set_destination(download, destinationURI.get()); + return TRUE; + } + + static void downloadFinishedCallback(WebKitDownload* download, WebViewDownloadTest* test) + { + test->quitMainLoop(); + } + + void waitUntilDownloadFinished() + { + g_signal_connect(m_download.get(), "decide-destination", G_CALLBACK(downloadDecideDestinationCallback), this); + g_signal_connect(m_download.get(), "finished", G_CALLBACK(downloadFinishedCallback), this); + g_main_loop_run(m_mainLoop); + } + + GRefPtr<WebKitDownload> m_download; +}; + +static void testWebViewDownloadURI(WebViewDownloadTest* test, gconstpointer) +{ + GRefPtr<WebKitDownload> download = adoptGRef(webkit_web_view_download_uri(test->m_webView, kServer->getURIForPath("/test.pdf").data())); + test->waitUntilDownloadStarted(); + g_assert(test->m_webView == webkit_download_get_web_view(download.get())); + test->waitUntilDownloadFinished(); + + GRefPtr<GFile> downloadFile = adoptGRef(g_file_new_for_uri(webkit_download_get_destination(download.get()))); + GRefPtr<GFileInfo> downloadFileInfo = adoptGRef(g_file_query_info(downloadFile.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), 0, 0)); + g_assert_cmpint(g_file_info_get_size(downloadFileInfo.get()), >, 0); + g_file_delete(downloadFile.get(), 0, 0); +} + +class PolicyResponseDownloadTest: public WebViewDownloadTest { +public: + MAKE_GLIB_TEST_FIXTURE(PolicyResponseDownloadTest); + + static gboolean decidePolicyCallback(WebKitWebView* webView, WebKitPolicyDecision* decision, WebKitPolicyDecisionType type, PolicyResponseDownloadTest* test) + { + if (type != WEBKIT_POLICY_DECISION_TYPE_RESPONSE) + return FALSE; + + webkit_policy_decision_download(decision); + return TRUE; + } + + PolicyResponseDownloadTest() + { + g_signal_connect(m_webView, "decide-policy", G_CALLBACK(decidePolicyCallback), this); + } + + ~PolicyResponseDownloadTest() + { + g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + void cancelDownloadAndWaitUntilFinished() + { + webkit_download_cancel(m_download.get()); + waitUntilDownloadFinished(); + m_download = 0; + } +}; + +static void testPolicyResponseDownload(PolicyResponseDownloadTest* test, gconstpointer) +{ + // Test that a download started by the the policy checker contains the web view. + CString requestURI = kServer->getURIForPath("/test.pdf").data(); + test->loadURI(requestURI.data()); + test->waitUntilDownloadStarted(); + + WebKitURIRequest* request = webkit_download_get_request(test->m_download.get()); + g_assert(request); + ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, requestURI); + + g_assert(test->m_webView == webkit_download_get_web_view(test->m_download.get())); + test->cancelDownloadAndWaitUntilFinished(); +} + +void beforeAll() +{ + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + + DownloadTest::add("Downloads", "local-file", testDownloadLocalFile); + DownloadTest::add("Downloads", "overwrite-destination-allowed", testDownloadOverwriteDestinationAllowed); + DownloadErrorTest::add("Downloads", "overwrite-destination-disallowed", testDownloadOverwriteDestinationDisallowed); + DownloadErrorTest::add("Downloads", "local-file-error", testDownloadLocalFileError); + DownloadTest::add("Downloads", "remote-file", testDownloadRemoteFile); + DownloadErrorTest::add("Downloads", "remote-file-error", testDownloadRemoteFileError); + WebViewDownloadTest::add("WebKitWebView", "download-uri", testWebViewDownloadURI); + PolicyResponseDownloadTest::add("Downloads", "policy-decision-download", testPolicyResponseDownload); +} + +void afterAll() +{ + delete kServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestEditor.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestEditor.cpp new file mode 100644 index 000000000..fc429d4c3 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestEditor.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebViewTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + +static void testWebKitWebEditorSelectionChanged(WebViewTest* test, gconstpointer) +{ + static const gchar* testHTML = "<html><body>All work and no play make Jack a dull boy.</body></html>"; + test->loadHtml(testHTML, nullptr); + test->waitUntilLoadFinished(); + + g_assert(test->runWebProcessTest("WebKitWebEditor", "selection-changed")); +} + +void beforeAll() +{ + WebViewTest::add("WebKitWebEditor", "selection-changed", testWebKitWebEditorSelectionChanged); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestFrame.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestFrame.cpp new file mode 100644 index 000000000..9145ab813 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestFrame.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebViewTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + +static void webkitFrameTestRun(WebViewTest* test, const char* testName) +{ + static const char* testHTML = "<html><body></body></html>"; + test->loadHtml(testHTML, 0); + test->waitUntilLoadFinished(); + + g_assert(test->runWebProcessTest("WebKitFrame", testName)); +} + +static void testWebKitFrameMainFrame(WebViewTest* test, gconstpointer) +{ + webkitFrameTestRun(test, "main-frame"); +} + +static void testWebKitFrameURI(WebViewTest* test, gconstpointer) +{ + webkitFrameTestRun(test, "uri"); +} + +static void testWebKitFrameJavaScriptContext(WebViewTest* test, gconstpointer) +{ + webkitFrameTestRun(test, "javascript-context"); +} + +void beforeAll() +{ + WebViewTest::add("WebKitFrame", "main-frame", testWebKitFrameMainFrame); + WebViewTest::add("WebKitFrame", "uri", testWebKitFrameURI); + WebViewTest::add("WebKitFrame", "javascript-context", testWebKitFrameJavaScriptContext); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestInspector.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestInspector.cpp new file mode 100644 index 000000000..3d993e24f --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestInspector.cpp @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebViewTest.h" +#include <wtf/Vector.h> +#include <wtf/glib/GRefPtr.h> + +class InspectorTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(InspectorTest); + + enum InspectorEvents { + OpenWindow, + BringToFront, + Closed, + Attach, + Detach + }; + + static gboolean openWindowCallback(WebKitWebInspector*, InspectorTest* test) + { + return test->openWindow(); + } + + static gboolean bringToFrontCallback(WebKitWebInspector*, InspectorTest* test) + { + return test->bringToFront(); + } + + static void closedCallback(WebKitWebInspector*, InspectorTest* test) + { + return test->closed(); + } + + static gboolean attachCallback(WebKitWebInspector*, InspectorTest* test) + { + return test->attach(); + } + + static gboolean detachCallback(WebKitWebInspector*, InspectorTest* test) + { + return test->detach(); + } + + static const unsigned gMinimumAttachedInspectorWidth = 750; + static const unsigned gMinimumAttachedInspectorHeight = 250; + + InspectorTest() + : WebViewTest() + , m_inspector(webkit_web_view_get_inspector(m_webView)) + { + webkit_settings_set_enable_developer_extras(webkit_web_view_get_settings(m_webView), TRUE); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_inspector)); + g_signal_connect(m_inspector, "open-window", G_CALLBACK(openWindowCallback), this); + g_signal_connect(m_inspector, "bring-to-front", G_CALLBACK(bringToFrontCallback), this); + g_signal_connect(m_inspector, "closed", G_CALLBACK(closedCallback), this); + g_signal_connect(m_inspector, "attach", G_CALLBACK(attachCallback), this); + g_signal_connect(m_inspector, "detach", G_CALLBACK(detachCallback), this); + } + + ~InspectorTest() + { + g_signal_handlers_disconnect_matched(m_inspector, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + virtual bool openWindow() + { + m_events.append(OpenWindow); + g_main_loop_quit(m_mainLoop); + return TRUE; + } + + virtual bool bringToFront() + { + m_events.append(BringToFront); + g_main_loop_quit(m_mainLoop); + return FALSE; + } + + virtual void closed() + { + m_events.append(Closed); + } + + virtual bool attach() + { + m_events.append(Attach); + return TRUE; + } + + virtual bool detach() + { + m_events.append(Detach); + return TRUE; + } + + + static gboolean showIdle(InspectorTest* test) + { + webkit_web_inspector_show(test->m_inspector); + return FALSE; + } + + void show() + { + g_idle_add(reinterpret_cast<GSourceFunc>(showIdle), this); + g_main_loop_run(m_mainLoop); + } + + static void canAttachChanged(InspectorTest* test) + { + g_main_loop_quit(test->m_mainLoop); + } + + void resizeViewAndAttach() + { + // Resize the view to make room for the inspector. + if (!webkit_web_inspector_get_can_attach(m_inspector)) { + unsigned long handler = g_signal_connect_swapped(m_inspector, "notify::can-attach", G_CALLBACK(canAttachChanged), this); + resizeView(gMinimumAttachedInspectorWidth, (gMinimumAttachedInspectorHeight + 1) * 4 / 3); + g_main_loop_run(m_mainLoop); + g_signal_handler_disconnect(m_inspector, handler); + } + + g_assert(webkit_web_inspector_get_can_attach(m_inspector)); + webkit_web_inspector_attach(m_inspector); + } + + static gboolean detachIdle(InspectorTest* test) + { + webkit_web_inspector_detach(test->m_inspector); + return FALSE; + } + + void detachAndWaitUntilWindowOpened() + { + g_idle_add(reinterpret_cast<GSourceFunc>(detachIdle), this); + g_main_loop_run(m_mainLoop); + } + + void close() + { + webkit_web_inspector_close(m_inspector); + } + + WebKitWebInspector* m_inspector; + Vector<InspectorEvents> m_events; +}; + +static void testInspectorDefault(InspectorTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + test->resizeView(200, 200); + test->loadHtml("<html><body><p>WebKitGTK+ Inspector test</p></body></html>", 0); + test->waitUntilLoadFinished(); + + test->show(); + // We don't add the view to a container, so consume the weak ref with GRefPtr. + GRefPtr<WebKitWebViewBase> inspectorView = webkit_web_inspector_get_web_view(test->m_inspector); + g_assert(inspectorView.get()); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(inspectorView.get())); + g_assert(!webkit_web_inspector_is_attached(test->m_inspector)); + g_assert_cmpuint(webkit_web_inspector_get_attached_height(test->m_inspector), ==, 0); + g_assert(!webkit_web_inspector_get_can_attach(test->m_inspector)); + Vector<InspectorTest::InspectorEvents>& events = test->m_events; + g_assert_cmpint(events.size(), ==, 1); + g_assert_cmpint(events[0], ==, InspectorTest::OpenWindow); + test->m_events.clear(); + + test->show(); + events = test->m_events; + g_assert_cmpint(events.size(), ==, 1); + g_assert_cmpint(events[0], ==, InspectorTest::BringToFront); + test->m_events.clear(); + + test->resizeViewAndAttach(); + g_assert(webkit_web_inspector_is_attached(test->m_inspector)); + g_assert_cmpuint(webkit_web_inspector_get_attached_height(test->m_inspector), >=, InspectorTest::gMinimumAttachedInspectorHeight); + events = test->m_events; + g_assert_cmpint(events.size(), ==, 1); + g_assert_cmpint(events[0], ==, InspectorTest::Attach); + test->m_events.clear(); + + test->detachAndWaitUntilWindowOpened(); + g_assert(!webkit_web_inspector_is_attached(test->m_inspector)); + events = test->m_events; + g_assert_cmpint(events.size(), ==, 2); + g_assert_cmpint(events[0], ==, InspectorTest::Detach); + g_assert_cmpint(events[1], ==, InspectorTest::OpenWindow); + test->m_events.clear(); + + test->close(); + events = test->m_events; + g_assert_cmpint(events.size(), ==, 1); + g_assert_cmpint(events[0], ==, InspectorTest::Closed); + test->m_events.clear(); +} + +class CustomInspectorTest: public InspectorTest { +public: + MAKE_GLIB_TEST_FIXTURE(CustomInspectorTest); + + CustomInspectorTest() + : InspectorTest() + , m_inspectorWindow(0) + { + } + + ~CustomInspectorTest() + { + if (m_inspectorWindow) + gtk_widget_destroy(m_inspectorWindow); + } + + bool openWindow() + { + g_assert(!m_inspectorWindow); + m_inspectorWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); + WebKitWebViewBase* inspectorView = webkit_web_inspector_get_web_view(m_inspector); + g_assert(inspectorView); + gtk_container_add(GTK_CONTAINER(m_inspectorWindow), GTK_WIDGET(inspectorView)); + gtk_widget_show_all(m_inspectorWindow); + + return InspectorTest::openWindow(); + } + + void closed() + { + if (m_inspectorWindow) { + gtk_widget_destroy(m_inspectorWindow); + m_inspectorWindow = 0; + } + + return InspectorTest::closed(); + } + + bool attach() + { + GRefPtr<WebKitWebViewBase> inspectorView = webkit_web_inspector_get_web_view(m_inspector); + if (m_inspectorWindow) { + gtk_container_remove(GTK_CONTAINER(m_inspectorWindow), GTK_WIDGET(inspectorView.get())); + gtk_widget_destroy(m_inspectorWindow); + m_inspectorWindow = 0; + } + + GtkWidget* pane; + if (gtk_bin_get_child(GTK_BIN(m_parentWindow)) == GTK_WIDGET(m_webView)) { + GRefPtr<WebKitWebView> inspectedView = m_webView; + gtk_container_remove(GTK_CONTAINER(m_parentWindow), GTK_WIDGET(m_webView)); + pane = gtk_paned_new(GTK_ORIENTATION_VERTICAL); + gtk_paned_add1(GTK_PANED(pane), GTK_WIDGET(m_webView)); + gtk_container_add(GTK_CONTAINER(m_parentWindow), pane); + gtk_widget_show_all(pane); + } else + pane = gtk_bin_get_child(GTK_BIN(m_parentWindow)); + gtk_paned_set_position(GTK_PANED(pane), webkit_web_inspector_get_attached_height(m_inspector)); + gtk_paned_add2(GTK_PANED(pane), GTK_WIDGET(inspectorView.get())); + + return InspectorTest::attach(); + } + + bool detach() + { + GRefPtr<WebKitWebViewBase> inspectorView = webkit_web_inspector_get_web_view(m_inspector); + GtkWidget* pane = gtk_bin_get_child(GTK_BIN(m_parentWindow)); + g_assert(GTK_IS_PANED(pane)); + gtk_container_remove(GTK_CONTAINER(pane), GTK_WIDGET(inspectorView.get())); + return InspectorTest::detach(); + } + + void destroyWindow() + { + g_assert(m_inspectorWindow); + gtk_widget_destroy(m_inspectorWindow); + m_inspectorWindow = 0; + } + + GtkWidget* m_inspectorWindow; +}; + +static void testInspectorManualAttachDetach(CustomInspectorTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + test->resizeView(200, 200); + test->loadHtml("<html><body><p>WebKitGTK+ Inspector test</p></body></html>", 0); + test->waitUntilLoadFinished(); + + test->show(); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webkit_web_inspector_get_web_view(test->m_inspector))); + g_assert(!webkit_web_inspector_is_attached(test->m_inspector)); + Vector<InspectorTest::InspectorEvents>& events = test->m_events; + g_assert_cmpint(events.size(), ==, 1); + g_assert_cmpint(events[0], ==, InspectorTest::OpenWindow); + test->m_events.clear(); + + test->resizeViewAndAttach(); + g_assert(webkit_web_inspector_is_attached(test->m_inspector)); + g_assert_cmpuint(webkit_web_inspector_get_attached_height(test->m_inspector), >=, InspectorTest::gMinimumAttachedInspectorHeight); + events = test->m_events; + g_assert_cmpint(events.size(), ==, 1); + g_assert_cmpint(events[0], ==, InspectorTest::Attach); + test->m_events.clear(); + + test->detachAndWaitUntilWindowOpened(); + g_assert(!webkit_web_inspector_is_attached(test->m_inspector)); + events = test->m_events; + g_assert_cmpint(events.size(), ==, 2); + g_assert_cmpint(events[0], ==, InspectorTest::Detach); + g_assert_cmpint(events[1], ==, InspectorTest::OpenWindow); + test->m_events.clear(); + + test->resizeViewAndAttach(); + g_assert(webkit_web_inspector_is_attached(test->m_inspector)); + test->m_events.clear(); + test->close(); + events = test->m_events; + g_assert_cmpint(events.size(), ==, 2); + g_assert_cmpint(events[0], ==, InspectorTest::Detach); + g_assert_cmpint(events[1], ==, InspectorTest::Closed); + test->m_events.clear(); +} + +static void testInspectorCustomContainerDestroyed(CustomInspectorTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + test->resizeView(200, 200); + test->loadHtml("<html><body><p>WebKitGTK+ Inspector test</p></body></html>", 0); + test->waitUntilLoadFinished(); + + test->show(); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webkit_web_inspector_get_web_view(test->m_inspector))); + g_assert(!webkit_web_inspector_is_attached(test->m_inspector)); + + test->m_events.clear(); + test->destroyWindow(); + Vector<InspectorTest::InspectorEvents>& events = test->m_events; + g_assert_cmpint(events.size(), ==, 1); + g_assert_cmpint(events[0], ==, InspectorTest::Closed); + test->m_events.clear(); +} + +void beforeAll() +{ + InspectorTest::add("WebKitWebInspector", "default", testInspectorDefault); + CustomInspectorTest::add("WebKitWebInspector", "manual-attach-detach", testInspectorManualAttachDetach); + CustomInspectorTest::add("WebKitWebInspector", "custom-container-destroyed", testInspectorCustomContainerDestroyed); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestInspectorServer.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestInspectorServer.cpp new file mode 100644 index 000000000..bbdd104c5 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestInspectorServer.cpp @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2012 Samsung Electronics Ltd. 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 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 "WebViewTest.h" +#include <wtf/glib/GRefPtr.h> +#include <wtf/text/WTFString.h> + +// Name of the test server application creating the webView object. +static const char* gTestServerAppName = "InspectorTestServer"; + +// Max seconds to wait for the test server before inspecting it. +static const int gMaxWaitForChild = 5; + +// The PID for the test server running, so we can kill it if needed. +static GPid gChildProcessPid = 0; + +// Whether the child has replied and it's ready. +static bool gChildIsReady = false; + +static void stopTestServer() +{ + // Do nothing if there's no server running. + if (!gChildProcessPid) + return; + + g_spawn_close_pid(gChildProcessPid); + kill(gChildProcessPid, SIGTERM); + gChildProcessPid = 0; +} + +static void sigAbortHandler(int sigNum) +{ + // Just stop the test server if SIGABRT was received. + stopTestServer(); +} + +static gpointer testServerMonitorThreadFunc(gpointer) +{ + // Wait for the specified timeout to happen. + g_usleep(gMaxWaitForChild * G_USEC_PER_SEC); + + // Kill the child process if not ready yet. + if (!gChildIsReady) + stopTestServer(); + + g_thread_exit(0); + return 0; +} + +static void startTestServerMonitor() +{ + gChildIsReady = false; + g_thread_new("TestServerMonitor", testServerMonitorThreadFunc, 0); +} + +static void startTestServer() +{ + // Prepare argv[] for spawning the server process. + GUniquePtr<char> testServerPath(g_build_filename(WEBKIT_EXEC_PATH, "TestWebKitAPI", "WebKit2Gtk", gTestServerAppName, NULL)); + + // We install a handler to ensure that we kill the child process + // if the parent dies because of whatever the reason is. + signal(SIGABRT, sigAbortHandler); + + char* testServerArgv[2]; + testServerArgv[0] = testServerPath.get(); + testServerArgv[1] = 0; + + // Spawn the server, getting its stdout file descriptor to set a + // communication channel, so we know when it's ready. + int childStdout = 0; + g_assert(g_spawn_async_with_pipes(0, testServerArgv, 0, static_cast<GSpawnFlags>(0), 0, 0, + &gChildProcessPid, 0, &childStdout, 0, 0)); + + // Start monitoring the test server (in a separate thread) to + // ensure we don't block on the child process more than a timeout. + startTestServerMonitor(); + + char msg[2]; + GIOChannel* ioChannel = g_io_channel_unix_new(childStdout); + if (g_io_channel_read_chars(ioChannel, msg, 2, 0, 0) == G_IO_STATUS_NORMAL) { + // Check whether the server sent a message saying it's ready + // and store the result globally, so the monitor can see it. + gChildIsReady = msg[0] == 'O' && msg[1] == 'K'; + } + g_io_channel_unref(ioChannel); + close(childStdout); + + // The timeout was reached and the server is not ready yet, so + // stop it inmediately, and let the unit tests fail. + if (!gChildIsReady) + stopTestServer(); +} + +class InspectorServerTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(InspectorServerTest); + + InspectorServerTest() + : WebViewTest() + { + } + + bool getPageList() + { + loadHtml("<script type=\"text/javascript\">\n" + "var pages;\n" + "var xhr = new XMLHttpRequest;\n" + "xhr.open(\"GET\", \"/pagelist.json\");\n" + "xhr.onload = function(e) {\n" + "if (xhr.status == 200) {\n" + "pages = JSON.parse(xhr.responseText);\n" + "document.title = \"OK\";\n" + "} else \n" + "document.title = \"FAIL\";\n" + "}\n" + "xhr.send();\n" + "</script>\n", + "http://127.0.0.1:2999/"); + + waitUntilTitleChanged(); + + if (!strcmp(webkit_web_view_get_title(m_webView), "OK")) + return true; + + return false; + } + + ~InspectorServerTest() + { + } +}; + +// Test to get inspector server page list from the test server. +// Should contain only one entry pointing to http://127.0.0.1:2999/webinspector/Main.html?page=1 +static void testInspectorServerPageList(InspectorServerTest* test, gconstpointer) +{ + GUniqueOutPtr<GError> error; + + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + g_assert(test->getPageList()); + + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages.length;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert_cmpint(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 1); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages[0].id;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + int pageId = WebViewTest::javascriptResultToNumber(javascriptResult); + + GUniquePtr<char> valueString; + javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages[0].url;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "http://127.0.0.1:2999/"); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages[0].inspectorUrl;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + String validInspectorURL = String("/Main.html?page=") + String::number(pageId); + ASSERT_CMP_CSTRING(valueString.get(), ==, validInspectorURL.utf8()); +} + +// Test sending a raw remote debugging message through our web socket server. +// For this specific message see: http://code.google.com/chrome/devtools/docs/protocol/tot/runtime.html#command-evaluate +static void testRemoteDebuggingMessage(InspectorServerTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + + test->loadHtml("<script type=\"text/javascript\">\n" + "var socket = new WebSocket('ws://127.0.0.1:2999/devtools/page/1');\n" + "socket.onmessage = function(message) {\n" + "var response = JSON.parse(message.data);\n" + "if (response.id === 1)\n" + "document.title = response.result.result.value;\n" + "else\n" + "document.title = \"FAIL\";\n" + "}\n" + "socket.onopen = function() {\n" + "socket.send('{\"id\": 1, \"method\": \"Runtime.evaluate\", \"params\": {\"expression\": \"2 + 2\" } }');\n" + "}\n" + "</script>", + "http://127.0.0.1:2999/"); + test->waitUntilTitleChanged(); + + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, "4"); +} + +static void openRemoteDebuggingSession(InspectorServerTest* test, gconstpointer) +{ + // To test the whole pipeline this exploits a behavior of the inspector front-end which won't provide the page address as title unless the + // debugging session was established correctly through web socket. + // In our case page URL should be http://127.0.0.1:2999/ + // So this test case will fail if: + // - The page list didn't return a valid inspector URL + // - Or the front-end couldn't be loaded through the inspector HTTP server + // - Or the web socket connection couldn't be established between the front-end and the page through the inspector server + // Let's see if this test isn't raising too many false positives, in which case we should use a better predicate if available. + + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + + g_assert(test->getPageList()); + + GUniqueOutPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("pages[0].inspectorUrl;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + + String resolvedURL = String("http://127.0.0.1:2999") + String::fromUTF8(WebViewTest::javascriptResultToCString(javascriptResult)); + test->loadURI(resolvedURL.utf8().data()); + test->waitUntilLoadFinished(); + + const char* title = webkit_web_view_get_title(test->m_webView); + if (!title || !*title) + test->waitUntilTitleChanged(); + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, "127.0.0.1"); +} + +static void sendIncompleteRequest(InspectorServerTest* test, gconstpointer) +{ + GUniqueOutPtr<GError> error; + + // Connect to the inspector server. + GRefPtr<GSocketClient> client = adoptGRef(g_socket_client_new()); + GRefPtr<GSocketConnection> connection = adoptGRef(g_socket_client_connect_to_host(client.get(), "127.0.0.1", 2999, 0, &error.outPtr())); + g_assert_no_error(error.get()); + + // Send incomplete request (missing blank line after headers) and check if inspector server + // replies. The server should not reply to an incomplete request and the test should timeout + // on read. + GOutputStream* ostream = g_io_stream_get_output_stream(G_IO_STREAM(connection.get())); + // Request missing blank line after headers. + const gchar* incompleteRequest = "GET /devtools/page/1 HTTP/1.1\r\nHost: Localhost\r\n"; + g_output_stream_write(ostream, incompleteRequest, strlen(incompleteRequest), 0, &error.outPtr()); + g_assert_no_error(error.get()); + + GInputStream* istream = g_io_stream_get_input_stream(G_IO_STREAM(connection.get())); + char response[16]; + memset(response, 0, sizeof(response)); + GRefPtr<GCancellable> cancel = adoptGRef(g_cancellable_new()); + g_input_stream_read_async(istream, response, sizeof(response) - 1, G_PRIORITY_DEFAULT, cancel.get(), 0, 0); + // Give a chance for the server to reply. + test->wait(1); + g_cancellable_cancel(cancel.get()); + // If we got any answer it means the server replied to an incomplete request, lets fail. + g_assert(response[0] == '\0'); +} + +void beforeAll() +{ + // Overwrite WEBKIT_INSPECTOR_SERVER variable with default IP address but different port to avoid conflict with the test inspector server page. + g_setenv("WEBKIT_INSPECTOR_SERVER", "127.0.0.1:2998", TRUE); + + startTestServer(); + InspectorServerTest::add("WebKitWebInspectorServer", "test-page-list", testInspectorServerPageList); + InspectorServerTest::add("WebKitWebInspectorServer", "test-remote-debugging-message", testRemoteDebuggingMessage); + InspectorServerTest::add("WebKitWebInspectorServer", "test-open-debugging-session", openRemoteDebuggingSession); + InspectorServerTest::add("WebKitWebInspectorServer", "test-incomplete-request", sendIncompleteRequest); + +} + +void afterAll() +{ + stopTestServer(); +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestLoaderClient.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestLoaderClient.cpp new file mode 100644 index 000000000..227b389ff --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestLoaderClient.cpp @@ -0,0 +1,551 @@ +/* + * Copyright (C) 2009, 2010 Gustavo Noronha Silva + * Copyright (C) 2009, 2011 Igalia S.L. + * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "LoadTrackingTest.h" +#include "WebKitTestBus.h" +#include "WebKitTestServer.h" +#include "WebViewTest.h" +#include <gtk/gtk.h> +#include <libsoup/soup.h> +#include <wtf/text/CString.h> + +static WebKitTestBus* bus; +static WebKitTestServer* kServer; + +const char* kDNTHeaderNotPresent = "DNT header not present"; + +static void testLoadingStatus(LoadTrackingTest* test, gconstpointer data) +{ + test->setRedirectURI(kServer->getURIForPath("/normal").data()); + test->loadURI(kServer->getURIForPath("/redirect").data()); + test->waitUntilLoadFinished(); + + Vector<LoadTrackingTest::LoadEvents>& events = test->m_loadEvents; + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(events[1], ==, LoadTrackingTest::ProvisionalLoadReceivedServerRedirect); + g_assert_cmpint(events[2], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(events[3], ==, LoadTrackingTest::LoadFinished); +} + +static void testLoadingError(LoadTrackingTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/error").data()); + test->waitUntilLoadFinished(); + + Vector<LoadTrackingTest::LoadEvents>& events = test->m_loadEvents; + g_assert_cmpint(events.size(), ==, 3); + g_assert_cmpint(events[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(events[1], ==, LoadTrackingTest::ProvisionalLoadFailed); + g_assert_cmpint(events[2], ==, LoadTrackingTest::LoadFinished); +} + +static void assertNormalLoadHappened(Vector<LoadTrackingTest::LoadEvents>& events) +{ + g_assert_cmpint(events.size(), ==, 3); + g_assert_cmpint(events[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(events[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(events[2], ==, LoadTrackingTest::LoadFinished); +} + +static void testLoadHtml(LoadTrackingTest* test, gconstpointer) +{ + test->loadHtml("<html><body>Hello WebKit-GTK+</body></html>", 0); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); +} + +static void testLoadAlternateHTML(LoadTrackingTest* test, gconstpointer) +{ + test->loadAlternateHTML("<html><body>Alternate page</body></html>", "http://error-page.foo/", 0); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); +} + +static void testLoadAlternateHTMLForLocalPage(LoadTrackingTest* test, gconstpointer) +{ + test->loadAlternateHTML("<html><body>Alternate page</body></html>", "file:///not/actually/loaded.html", 0); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); +} + +static void testLoadPlainText(LoadTrackingTest* test, gconstpointer) +{ + test->loadPlainText("Hello WebKit-GTK+"); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); +} + +static void testLoadBytes(LoadTrackingTest* test, gconstpointer) +{ + GUniquePtr<char> filePath(g_build_filename(Test::getResourcesDir().data(), "blank.ico", nullptr)); + char* contents; + gsize contentsLength; + g_file_get_contents(filePath.get(), &contents, &contentsLength, nullptr); + GRefPtr<GBytes> bytes = adoptGRef(g_bytes_new_take(contents, contentsLength)); + test->loadBytes(bytes.get(), "image/vnd.microsoft.icon", nullptr, nullptr); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); +} + +static void testLoadRequest(LoadTrackingTest* test, gconstpointer) +{ + GRefPtr<WebKitURIRequest> request(webkit_uri_request_new(kServer->getURIForPath("/normal").data())); + test->loadRequest(request.get()); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); +} + +static void testLoadFromGResource(LoadTrackingTest* test, gconstpointer) +{ + GRefPtr<WebKitURIRequest> request(webkit_uri_request_new("resource:///org/webkit/webkit2gtk/tests/boring.html")); + test->loadRequest(request.get()); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); +} + +class LoadStopTrackingTest : public LoadTrackingTest { +public: + MAKE_GLIB_TEST_FIXTURE(LoadStopTrackingTest); + + virtual void loadCommitted() + { + LoadTrackingTest::loadCommitted(); + webkit_web_view_stop_loading(m_webView); + } + virtual void loadFailed(const gchar* failingURI, GError* error) + { + g_assert(g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)); + LoadTrackingTest::loadFailed(failingURI, error); + } +}; + +static void testLoadCancelled(LoadStopTrackingTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/cancelled").data()); + test->waitUntilLoadFinished(); + + Vector<LoadTrackingTest::LoadEvents>& events = test->m_loadEvents; + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(events[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(events[2], ==, LoadTrackingTest::LoadFailed); + g_assert_cmpint(events[3], ==, LoadTrackingTest::LoadFinished); +} + +static void testWebViewTitle(LoadTrackingTest* test, gconstpointer) +{ + g_assert(!webkit_web_view_get_title(test->m_webView)); + test->loadHtml("<html><head><title>Welcome to WebKit-GTK+!</title></head></html>", 0); + test->waitUntilLoadFinished(); + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, "Welcome to WebKit-GTK+!"); +} + +static void testWebViewReload(LoadTrackingTest* test, gconstpointer) +{ + // Check that nothing happens when there's nothing to reload. + test->reload(); + test->wait(0.25); // Wait for a quarter of a second. + + test->loadURI(kServer->getURIForPath("/normal").data()); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); + + test->reload(); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); +} + +static void testLoadProgress(LoadTrackingTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/normal").data()); + test->waitUntilLoadFinished(); + g_assert_cmpfloat(test->m_estimatedProgress, ==, 1); +} + +static void testWebViewHistoryLoad(LoadTrackingTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/normal").data()); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); + + test->loadURI(kServer->getURIForPath("/normal2").data()); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); + + // Check that load process is the same for pages loaded from history cache. + test->goBack(); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); + + test->goForward(); + test->waitUntilLoadFinished(); + assertNormalLoadHappened(test->m_loadEvents); +} + +class ViewURITrackingTest: public LoadTrackingTest { +public: + MAKE_GLIB_TEST_FIXTURE(ViewURITrackingTest); + + static void uriChanged(GObject*, GParamSpec*, ViewURITrackingTest* test) + { + g_assert_cmpstr(test->m_activeURI.data(), !=, webkit_web_view_get_uri(test->m_webView)); + test->m_activeURI = webkit_web_view_get_uri(test->m_webView); + } + + ViewURITrackingTest() + : m_activeURI(webkit_web_view_get_uri(m_webView)) + { + g_assert(m_activeURI.isNull()); + g_signal_connect(m_webView, "notify::uri", G_CALLBACK(uriChanged), this); + } + + void provisionalLoadStarted() + { + checkActiveURI("/redirect"); + } + + void provisionalLoadReceivedServerRedirect() + { + checkActiveURI("/normal"); + } + + void loadCommitted() + { + checkActiveURI("/normal"); + } + + void loadFinished() + { + checkActiveURI("/normal"); + LoadTrackingTest::loadFinished(); + } + + CString m_activeURI; + +private: + void checkActiveURI(const char* uri) + { + ASSERT_CMP_CSTRING(m_activeURI, ==, kServer->getURIForPath(uri)); + } +}; + +static void testWebViewActiveURI(ViewURITrackingTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/redirect").data()); + test->waitUntilLoadFinished(); +} + +class ViewIsLoadingTest: public LoadTrackingTest { +public: + MAKE_GLIB_TEST_FIXTURE(ViewIsLoadingTest); + + static void isLoadingChanged(GObject*, GParamSpec*, ViewIsLoadingTest* test) + { + if (webkit_web_view_is_loading(test->m_webView)) + test->beginLoad(); + else + test->endLoad(); + } + + ViewIsLoadingTest() + { + g_signal_connect(m_webView, "notify::is-loading", G_CALLBACK(isLoadingChanged), this); + } + + void beginLoad() + { + // New load, load-started hasn't been emitted yet. + g_assert(m_loadEvents.isEmpty()); + g_assert_cmpstr(webkit_web_view_get_uri(m_webView), ==, m_activeURI.data()); + } + + void endLoad() + { + // Load finish, load-finished and load-failed haven't been emitted yet. + g_assert(!m_loadEvents.isEmpty()); + g_assert(!m_loadEvents.contains(LoadTrackingTest::LoadFinished)); + g_assert(!m_loadEvents.contains(LoadTrackingTest::LoadFailed)); + } +}; + +static void testWebViewIsLoading(ViewIsLoadingTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/normal").data()); + test->waitUntilLoadFinished(); + + test->reload(); + test->waitUntilLoadFinished(); + + test->loadURI(kServer->getURIForPath("/error").data()); + test->waitUntilLoadFinished(); + + test->loadURI(kServer->getURIForPath("/normal").data()); + test->waitUntilLoadFinished(); + test->loadURI(kServer->getURIForPath("/normal2").data()); + test->waitUntilLoadFinished(); + + test->goBack(); + test->waitUntilLoadFinished(); + + test->goForward(); + test->waitUntilLoadFinished(); +} + +class WebPageURITest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(WebPageURITest); + + static void webPageURIChangedCallback(GDBusConnection*, const char*, const char*, const char*, const char*, GVariant* result, WebPageURITest* test) + { + const char* uri; + g_variant_get(result, "(&s)", &uri); + test->m_webPageURIs.append(uri); + } + + static void webViewURIChanged(GObject*, GParamSpec*, WebPageURITest* test) + { + test->m_webViewURIs.append(webkit_web_view_get_uri(test->m_webView)); + } + + WebPageURITest() + { + GUniquePtr<char> extensionBusName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", Test::s_webExtensionID)); + GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy(extensionBusName.get(), + "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", m_mainLoop)); + m_uriChangedSignalID = g_dbus_connection_signal_subscribe( + g_dbus_proxy_get_connection(proxy.get()), + 0, + "org.webkit.gtk.WebExtensionTest", + "URIChanged", + "/org/webkit/gtk/WebExtensionTest", + 0, + G_DBUS_SIGNAL_FLAGS_NONE, + reinterpret_cast<GDBusSignalCallback>(webPageURIChangedCallback), + this, + 0); + g_assert(m_uriChangedSignalID); + + g_signal_connect(m_webView, "notify::uri", G_CALLBACK(webViewURIChanged), this); + } + + ~WebPageURITest() + { + g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + g_dbus_connection_signal_unsubscribe(bus->connection(), m_uriChangedSignalID); + } + + unsigned m_uriChangedSignalID; + Vector<CString> m_webPageURIs; + Vector<CString> m_webViewURIs; +}; + +static void testWebPageURI(WebPageURITest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/redirect").data()); + test->waitUntilLoadFinished(); + + g_assert_cmpint(test->m_webPageURIs.size(), ==, test->m_webViewURIs.size()); + for (size_t i = 0; i < test->m_webPageURIs.size(); ++i) + ASSERT_CMP_CSTRING(test->m_webPageURIs[i], ==, test->m_webViewURIs[i]); + + g_assert_cmpint(test->m_webPageURIs.size(), ==, 2); + ASSERT_CMP_CSTRING(test->m_webPageURIs[0], ==, kServer->getURIForPath("/redirect")); + ASSERT_CMP_CSTRING(test->m_webPageURIs[1], ==, kServer->getURIForPath("/normal")); + +} + +static void testURIRequestHTTPHeaders(WebViewTest* test, gconstpointer) +{ + GRefPtr<WebKitURIRequest> uriRequest = adoptGRef(webkit_uri_request_new("file:///foo/bar")); + g_assert(uriRequest.get()); + g_assert_cmpstr(webkit_uri_request_get_uri(uriRequest.get()), ==, "file:///foo/bar"); + g_assert(!webkit_uri_request_get_http_headers(uriRequest.get())); + + // Load a request with no Do Not Track header. + webkit_uri_request_set_uri(uriRequest.get(), kServer->getURIForPath("/do-not-track-header").data()); + test->loadRequest(uriRequest.get()); + test->waitUntilLoadFinished(); + + size_t mainResourceDataSize = 0; + const char* mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpint(mainResourceDataSize, ==, strlen(kDNTHeaderNotPresent)); + g_assert(!strncmp(mainResourceData, kDNTHeaderNotPresent, mainResourceDataSize)); + + // Add the Do Not Track header and load the request again. + SoupMessageHeaders* headers = webkit_uri_request_get_http_headers(uriRequest.get()); + g_assert(headers); + soup_message_headers_append(headers, "DNT", "1"); + test->loadRequest(uriRequest.get()); + test->waitUntilLoadFinished(); + + mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpint(mainResourceDataSize, ==, 1); + g_assert(!strncmp(mainResourceData, "1", mainResourceDataSize)); + + // Load a URI for which the web extension will add the Do Not Track header. + test->loadURI(kServer->getURIForPath("/add-do-not-track-header").data()); + test->waitUntilLoadFinished(); + + mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpint(mainResourceDataSize, ==, 1); + g_assert(!strncmp(mainResourceData, "1", mainResourceDataSize)); +} + +static void testURIRequestHTTPMethod(WebViewTest* test, gconstpointer) +{ + GRefPtr<WebKitURIRequest> uriRequest = adoptGRef(webkit_uri_request_new("file:///foo/bar")); + g_assert(uriRequest.get()); + g_assert_cmpstr(webkit_uri_request_get_uri(uriRequest.get()), ==, "file:///foo/bar"); + g_assert(!webkit_uri_request_get_http_method(uriRequest.get())); + + webkit_uri_request_set_uri(uriRequest.get(), kServer->getURIForPath("/http-get-method").data()); + test->loadRequest(uriRequest.get()); + test->waitUntilLoadFinished(); + + test->runJavaScriptAndWaitUntilFinished("xhr = new XMLHttpRequest; xhr.open('POST', '/http-post-method', false); xhr.send();", nullptr); +} + +static void testURIResponseHTTPHeaders(WebViewTest* test, gconstpointer) +{ + test->loadHtml("<html><body>No HTTP headers</body></html>", "file:///"); + test->waitUntilLoadFinished(); + WebKitWebResource* resource = webkit_web_view_get_main_resource(test->m_webView); + g_assert(WEBKIT_IS_WEB_RESOURCE(resource)); + WebKitURIResponse* response = webkit_web_resource_get_response(resource); + g_assert(WEBKIT_IS_URI_RESPONSE(response)); + g_assert(!webkit_uri_response_get_http_headers(response)); + + test->loadURI(kServer->getURIForPath("/headers").data()); + test->waitUntilLoadFinished(); + resource = webkit_web_view_get_main_resource(test->m_webView); + g_assert(WEBKIT_IS_WEB_RESOURCE(resource)); + response = webkit_web_resource_get_response(resource); + g_assert(WEBKIT_IS_URI_RESPONSE(response)); + SoupMessageHeaders* headers = webkit_uri_response_get_http_headers(response); + g_assert(headers); + g_assert_cmpstr(soup_message_headers_get_one(headers, "Foo"), ==, "bar"); +} + +static void testRedirectToDataURI(WebViewTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/redirect-to-data").data()); + test->waitUntilLoadFinished(); + + static const char* expectedData = "data-uri"; + size_t mainResourceDataSize = 0; + const char* mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpint(mainResourceDataSize, ==, strlen(expectedData)); + g_assert(!strncmp(mainResourceData, expectedData, mainResourceDataSize)); +} + +static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + static const char* responseString = "<html><body>Testing!Testing!Testing!Testing!Testing!Testing!Testing!" + "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!" + "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!" + "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!" + "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!" + "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!" + "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!" + "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!</body></html>"; + + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + soup_message_set_status(message, SOUP_STATUS_OK); + + if (g_str_has_prefix(path, "/normal") || g_str_has_prefix(path, "/http-get-method")) + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, responseString, strlen(responseString)); + else if (g_str_equal(path, "/error")) + soup_message_set_status(message, SOUP_STATUS_CANT_CONNECT); + else if (g_str_equal(path, "/redirect")) { + soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY); + soup_message_headers_append(message->response_headers, "Location", "/normal"); + } else if (g_str_equal(path, "/cancelled")) { + soup_message_headers_set_encoding(message->response_headers, SOUP_ENCODING_CHUNKED); + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, responseString, strlen(responseString)); + soup_server_unpause_message(server, message); + return; + } else if (g_str_equal(path, "/do-not-track-header") || g_str_equal(path, "/add-do-not-track-header")) { + const char* doNotTrack = soup_message_headers_get_one(message->request_headers, "DNT"); + if (doNotTrack) + soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, doNotTrack, strlen(doNotTrack)); + else + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kDNTHeaderNotPresent, strlen(kDNTHeaderNotPresent)); + soup_message_set_status(message, SOUP_STATUS_OK); + } else if (g_str_equal(path, "/headers")) { + soup_message_headers_append(message->response_headers, "Foo", "bar"); + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, responseString, strlen(responseString)); + } else if (g_str_equal(path, "/redirect-to-data")) { + soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY); + soup_message_headers_append(message->response_headers, "Location", "data:text/plain;charset=utf-8,data-uri"); + } else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); + + soup_message_body_complete(message->response_body); +} + +void beforeAll() +{ + bus = new WebKitTestBus(); + if (!bus->run()) + return; + + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + + LoadTrackingTest::add("WebKitWebView", "loading-status", testLoadingStatus); + LoadTrackingTest::add("WebKitWebView", "loading-error", testLoadingError); + LoadTrackingTest::add("WebKitWebView", "load-html", testLoadHtml); + LoadTrackingTest::add("WebKitWebView", "load-alternate-html", testLoadAlternateHTML); + LoadTrackingTest::add("WebKitWebView", "load-alternate-html-for-local-page", testLoadAlternateHTMLForLocalPage); + LoadTrackingTest::add("WebKitWebView", "load-plain-text", testLoadPlainText); + LoadTrackingTest::add("WebKitWebView", "load-bytes", testLoadBytes); + LoadTrackingTest::add("WebKitWebView", "load-request", testLoadRequest); + LoadTrackingTest::add("WebKitWebView", "load-gresource", testLoadFromGResource); + LoadStopTrackingTest::add("WebKitWebView", "stop-loading", testLoadCancelled); + LoadTrackingTest::add("WebKitWebView", "title", testWebViewTitle); + LoadTrackingTest::add("WebKitWebView", "progress", testLoadProgress); + LoadTrackingTest::add("WebKitWebView", "reload", testWebViewReload); + LoadTrackingTest::add("WebKitWebView", "history-load", testWebViewHistoryLoad); + + // This test checks that web view notify::uri signal is correctly emitted + // and the uri is already updated when loader client signals are emitted. + ViewURITrackingTest::add("WebKitWebView", "active-uri", testWebViewActiveURI); + + ViewIsLoadingTest::add("WebKitWebView", "is-loading", testWebViewIsLoading); + WebPageURITest::add("WebKitWebPage", "get-uri", testWebPageURI); + WebViewTest::add("WebKitURIRequest", "http-headers", testURIRequestHTTPHeaders); + WebViewTest::add("WebKitURIRequest", "http-method", testURIRequestHTTPMethod); + WebViewTest::add("WebKitURIResponse", "http-headers", testURIResponseHTTPHeaders); + WebViewTest::add("WebKitWebPage", "redirect-to-data-uri", testRedirectToDataURI); +} + +void afterAll() +{ + delete bus; + delete kServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestMultiprocess.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestMultiprocess.cpp new file mode 100644 index 000000000..020ad3529 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestMultiprocess.cpp @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "TestMain.h" +#include "WebKitTestBus.h" +#include "WebViewTest.h" +#include <webkit2/webkit2.h> +#include <wtf/Vector.h> + +static const unsigned numViews = 2; +static WebKitTestBus* bus; + +class MultiprocessTest: public Test { +public: + MAKE_GLIB_TEST_FIXTURE(MultiprocessTest); + + MultiprocessTest() + : m_mainLoop(g_main_loop_new(nullptr, TRUE)) + , m_initializeWebExtensionsSignalCount(0) + , m_webViewBusNames(numViews) + , m_webViews(numViews) + { + webkit_web_context_set_process_model(m_webContext.get(), WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES); + } + + void initializeWebExtensions() override + { + Test::initializeWebExtensions(); + m_initializeWebExtensionsSignalCount++; + } + + static void loadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent, MultiprocessTest* test) + { + if (loadEvent != WEBKIT_LOAD_FINISHED) + return; + g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(loadChanged), test); + g_main_loop_quit(test->m_mainLoop); + } + + void loadWebViewAndWaitUntilLoaded(unsigned index) + { + g_assert_cmpuint(index, <, numViews); + + m_webViews[index] = WEBKIT_WEB_VIEW(webkit_web_view_new_with_context(m_webContext.get())); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_webViews[index].get())); + + m_webViewBusNames[index] = GUniquePtr<char>(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", Test::s_webExtensionID)); + + webkit_web_view_load_html(m_webViews[index].get(), "<html></html>", nullptr); + g_signal_connect(m_webViews[index].get(), "load-changed", G_CALLBACK(loadChanged), this); + g_main_loop_run(m_mainLoop); + } + + unsigned webProcessPid(unsigned index) + { + g_assert_cmpuint(index, <, numViews); + + GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy(m_webViewBusNames[index].get(), + "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", m_mainLoop)); + + GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync( + proxy.get(), + "GetProcessIdentifier", + nullptr, + G_DBUS_CALL_FLAGS_NONE, + -1, nullptr, nullptr)); + g_assert(result); + + guint32 identifier = 0; + g_variant_get(result.get(), "(u)", &identifier); + return identifier; + } + + static void nameVanishedCallback(GDBusConnection* connection, const gchar* name, gpointer userData) + { + g_main_loop_quit(static_cast<GMainLoop*>(userData)); + } + + void destroyWebViewAndWaitUntilWebProcessFinishes(unsigned index) + { + g_assert_cmpuint(index, <, numViews); + + unsigned watcherID = g_bus_watch_name_on_connection(bus->connection(), m_webViewBusNames[index].get(), G_BUS_NAME_WATCHER_FLAGS_NONE, + nullptr, nameVanishedCallback, m_mainLoop, nullptr); + gtk_widget_destroy(GTK_WIDGET(m_webViews[index].get())); + g_main_loop_run(m_mainLoop); + g_bus_unwatch_name(watcherID); + } + + GMainLoop* m_mainLoop; + unsigned m_initializeWebExtensionsSignalCount; + Vector<GUniquePtr<char>, numViews> m_webViewBusNames; + Vector<GRefPtr<WebKitWebView>, numViews> m_webViews; +}; + +static void testProcessPerWebView(MultiprocessTest* test, gconstpointer) +{ + // Create two web views. As we are in multiprocess mode, there must be + // two web processes, running an instance of the web extension each. + // The initialize-web-extensions must have been called twice, and the + // identifiers generated for them must be different (and their reported + // process identifiers). + + for (unsigned i = 0; i < numViews; i++) { + test->loadWebViewAndWaitUntilLoaded(i); + g_assert(WEBKIT_IS_WEB_VIEW(test->m_webViews[i].get())); + g_assert(test->m_webViewBusNames[i]); + } + + g_assert_cmpuint(test->m_initializeWebExtensionsSignalCount, ==, numViews); + g_assert_cmpstr(test->m_webViewBusNames[0].get(), !=, test->m_webViewBusNames[1].get()); + g_assert_cmpuint(test->webProcessPid(0), !=, test->webProcessPid(1)); + + // Check that web processes finish when the web view is destroyed even when it's not finalized. + // See https://bugs.webkit.org/show_bug.cgi?id=129783. + for (unsigned i = 0; i < numViews; i++) { + GRefPtr<WebKitWebView> webView = test->m_webViews[i]; + test->destroyWebViewAndWaitUntilWebProcessFinishes(i); + } +} + +class UIClientMultiprocessTest: public Test { +public: + MAKE_GLIB_TEST_FIXTURE(UIClientMultiprocessTest); + + enum WebViewEvents { + Create, + ReadyToShow, + Close + }; + + static GtkWidget* viewCreateCallback(WebKitWebView* webView, WebKitNavigationAction*, UIClientMultiprocessTest* test) + { + return test->viewCreate(webView); + } + + static void viewReadyToShowCallback(WebKitWebView* webView, UIClientMultiprocessTest* test) + { + test->viewReadyToShow(webView); + } + + static void viewCloseCallback(WebKitWebView* webView, UIClientMultiprocessTest* test) + { + test->viewClose(webView); + } + + UIClientMultiprocessTest() + : m_mainLoop(g_main_loop_new(nullptr, TRUE)) + , m_initializeWebExtensionsSignalCount(0) + { + webkit_web_context_set_process_model(m_webContext.get(), WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES); + m_webView = WEBKIT_WEB_VIEW(g_object_ref_sink(webkit_web_view_new_with_context(m_webContext.get()))); + webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(m_webView), TRUE); + + g_signal_connect(m_webView, "create", G_CALLBACK(viewCreateCallback), this); + } + + ~UIClientMultiprocessTest() + { + g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + gtk_widget_destroy(GTK_WIDGET(m_webView)); + } + + void initializeWebExtensions() override + { + Test::initializeWebExtensions(); + m_initializeWebExtensionsSignalCount++; + } + + GtkWidget* viewCreate(WebKitWebView* webView) + { + g_assert(webView == m_webView); + + GtkWidget* newWebView = webkit_web_view_new_with_related_view(webView); + g_object_ref_sink(newWebView); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(newWebView)); + m_webViewEvents.append(Create); + + g_signal_connect(newWebView, "ready-to-show", G_CALLBACK(viewReadyToShowCallback), this); + g_signal_connect(newWebView, "close", G_CALLBACK(viewCloseCallback), this); + + return newWebView; + } + + void viewReadyToShow(WebKitWebView* webView) + { + g_assert(m_webView != webView); + m_webViewEvents.append(ReadyToShow); + } + + void viewClose(WebKitWebView* webView) + { + g_assert(m_webView != webView); + + m_webViewEvents.append(Close); + g_object_unref(webView); + g_main_loop_quit(m_mainLoop); + } + + void waitUntilNewWebViewClose() + { + g_main_loop_run(m_mainLoop); + } + + WebKitWebView* m_webView; + GMainLoop* m_mainLoop; + unsigned m_initializeWebExtensionsSignalCount; + Vector<WebViewEvents> m_webViewEvents; +}; + +static void testMultiprocessWebViewCreateReadyClose(UIClientMultiprocessTest* test, gconstpointer) +{ + webkit_web_view_load_html(test->m_webView, "<html><body onLoad=\"window.open().close();\"></html>", nullptr); + test->waitUntilNewWebViewClose(); + + Vector<UIClientMultiprocessTest::WebViewEvents>& events = test->m_webViewEvents; + g_assert_cmpint(events.size(), ==, 3); + g_assert_cmpint(events[0], ==, UIClientMultiprocessTest::Create); + g_assert_cmpint(events[1], ==, UIClientMultiprocessTest::ReadyToShow); + g_assert_cmpint(events[2], ==, UIClientMultiprocessTest::Close); + + g_assert_cmpuint(test->m_initializeWebExtensionsSignalCount, ==, 1); +} + +static void testWebProcessLimit(MultiprocessTest* test, gconstpointer) +{ + g_assert_cmpuint(webkit_web_context_get_web_process_count_limit(test->m_webContext.get()), ==, 0); + + webkit_web_context_set_web_process_count_limit(test->m_webContext.get(), 1); + g_assert_cmpuint(webkit_web_context_get_web_process_count_limit(test->m_webContext.get()), ==, 1); + + // Create two web views but there should be only one web process. + for (unsigned i = 0; i < numViews; i++) { + test->loadWebViewAndWaitUntilLoaded(i); + g_assert(WEBKIT_IS_WEB_VIEW(test->m_webViews[i].get())); + } + + g_assert_cmpuint(test->m_initializeWebExtensionsSignalCount, ==, 1); +} + +void beforeAll() +{ + // Check that default setting is the one stated in the documentation + g_assert_cmpuint(webkit_web_context_get_process_model(webkit_web_context_get_default()), + ==, WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS); + + webkit_web_context_set_process_model(webkit_web_context_get_default(), + WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES); + + // Check that the getter returns the newly-set value + g_assert_cmpuint(webkit_web_context_get_process_model(webkit_web_context_get_default()), + ==, WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES); + + bus = new WebKitTestBus(); + if (!bus->run()) + return; + + MultiprocessTest::add("WebKitWebContext", "process-per-web-view", testProcessPerWebView); + UIClientMultiprocessTest::add("WebKitWebView", "multiprocess-create-ready-close", testMultiprocessWebViewCreateReadyClose); + MultiprocessTest::add("WebKitWebContext", "web-process-limit", testWebProcessLimit); +} + +void afterAll() +{ + delete bus; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestPrinting.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestPrinting.cpp new file mode 100644 index 000000000..c13185427 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestPrinting.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebViewTest.h" +#include <glib/gstdio.h> +#include <wtf/glib/GRefPtr.h> + +#ifdef HAVE_GTK_UNIX_PRINTING +#include <gtk/gtkunixprint.h> +#endif + +static void testPrintOperationPrintSettings(WebViewTest* test, gconstpointer) +{ + GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(webkit_print_operation_new(test->m_webView)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printOperation.get())); + + g_assert(!webkit_print_operation_get_print_settings(printOperation.get())); + g_assert(!webkit_print_operation_get_page_setup(printOperation.get())); + + GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new()); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printSettings.get())); + + GRefPtr<GtkPageSetup> pageSetup = adoptGRef(gtk_page_setup_new()); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(pageSetup.get())); + + webkit_print_operation_set_print_settings(printOperation.get(), printSettings.get()); + webkit_print_operation_set_page_setup(printOperation.get(), pageSetup.get()); + + g_assert(webkit_print_operation_get_print_settings(printOperation.get()) == printSettings.get()); + g_assert(webkit_print_operation_get_page_setup(printOperation.get()) == pageSetup.get()); +} + +static gboolean webViewPrintCallback(WebKitWebView* webView, WebKitPrintOperation* printOperation, WebViewTest* test) +{ + g_assert(webView == test->m_webView); + + g_assert(WEBKIT_IS_PRINT_OPERATION(printOperation)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printOperation)); + + g_assert(!webkit_print_operation_get_print_settings(printOperation)); + g_assert(!webkit_print_operation_get_page_setup(printOperation)); + + g_main_loop_quit(test->m_mainLoop); + + return TRUE; +} + +static void testWebViewPrint(WebViewTest* test, gconstpointer) +{ + g_signal_connect(test->m_webView, "print", G_CALLBACK(webViewPrintCallback), test); + test->loadHtml("<html><body onLoad=\"print();\">WebKitGTK+ printing test</body></html>", 0); + g_main_loop_run(test->m_mainLoop); +} + +#ifdef HAVE_GTK_UNIX_PRINTING +static gboolean testPrintOperationPrintPrinter(GtkPrinter* printer, gpointer userData) +{ + if (strcmp(gtk_printer_get_name(printer), "Print to File")) + return FALSE; + + GtkPrinter** foundPrinter = static_cast<GtkPrinter**>(userData); + *foundPrinter = static_cast<GtkPrinter*>(g_object_ref(printer)); + return TRUE; +} + +static GtkPrinter* findPrintToFilePrinter() +{ + GtkPrinter* printer = 0; + gtk_enumerate_printers(testPrintOperationPrintPrinter, &printer, 0, TRUE); + return printer; +} + +class PrintTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(PrintTest); + + static void printFinishedCallback(WebKitPrintOperation*, PrintTest* test) + { + g_main_loop_quit(test->m_mainLoop); + } + + static void printFailedCallback(WebKitPrintOperation*, GError* error, PrintTest* test) + { + g_assert(test->m_expectedError); + g_assert(error); + g_assert(g_error_matches(error, WEBKIT_PRINT_ERROR, test->m_expectedError)); + } + + PrintTest() + : m_expectedError(0) + { + m_printOperation = adoptGRef(webkit_print_operation_new(m_webView)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_printOperation.get())); + g_signal_connect(m_printOperation.get(), "finished", G_CALLBACK(printFinishedCallback), this); + g_signal_connect(m_printOperation.get(), "failed", G_CALLBACK(printFailedCallback), this); + } + + void waitUntilPrintFinished() + { + g_main_loop_run(m_mainLoop); + } + + GRefPtr<WebKitPrintOperation> m_printOperation; + unsigned m_expectedError; +}; + +static void testPrintOperationPrint(PrintTest* test, gconstpointer) +{ + test->loadHtml("<html><body>WebKitGTK+ printing test</body></html>", 0); + test->waitUntilLoadFinished(); + + GRefPtr<GtkPrinter> printer = adoptGRef(findPrintToFilePrinter()); + if (!printer) { + g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found"); + return; + } + + GUniquePtr<char> outputFilename(g_build_filename(Test::dataDirectory(), "webkit-print.pdf", nullptr)); + GRefPtr<GFile> outputFile = adoptGRef(g_file_new_for_path(outputFilename.get())); + GUniquePtr<char> outputURI(g_file_get_uri(outputFile.get())); + + GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new()); + gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get())); + gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, outputURI.get()); + + webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get()); + webkit_print_operation_print(test->m_printOperation.get()); + test->waitUntilPrintFinished(); + + GRefPtr<GFileInfo> fileInfo = adoptGRef(g_file_query_info(outputFile.get(), + G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + static_cast<GFileQueryInfoFlags>(0), 0, 0)); + g_assert(fileInfo.get()); + g_assert_cmpint(g_file_info_get_size(fileInfo.get()), >, 0); + g_assert_cmpstr(g_file_info_get_content_type(fileInfo.get()), ==, "application/pdf"); + + g_file_delete(outputFile.get(), 0, 0); +} + +static void testPrintOperationErrors(PrintTest* test, gconstpointer) +{ + test->loadHtml("<html><body>WebKitGTK+ printing errors test</body></html>", 0); + test->waitUntilLoadFinished(); + + GRefPtr<GtkPrinter> printer = adoptGRef(findPrintToFilePrinter()); + if (!printer) { + g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found"); + return; + } + + // General Error: invalid filename. + test->m_expectedError = WEBKIT_PRINT_ERROR_GENERAL; + GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new()); + gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get())); + gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, "file:///foo/bar"); + webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get()); + webkit_print_operation_print(test->m_printOperation.get()); + test->waitUntilPrintFinished(); + + // Printer not found error. + test->m_expectedError = WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND; + gtk_print_settings_set_printer(printSettings.get(), "The fake WebKit printer"); + webkit_print_operation_print(test->m_printOperation.get()); + test->waitUntilPrintFinished(); + + // No pages to print: print even pages for a single page document. + test->m_expectedError = WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE; + gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get())); + gtk_print_settings_set_page_set(printSettings.get(), GTK_PAGE_SET_EVEN); + webkit_print_operation_print(test->m_printOperation.get()); + test->waitUntilPrintFinished(); +} + +class CloseAfterPrintTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(CloseAfterPrintTest); + + static GtkWidget* webViewCreate(WebKitWebView* webView, WebKitNavigationAction*, CloseAfterPrintTest* test) + { + return test->createWebView(); + } + + static gboolean webViewPrint(WebKitWebView* webView, WebKitPrintOperation* printOperation, CloseAfterPrintTest* test) + { + test->print(printOperation); + return TRUE; + } + + static void printOperationFinished(WebKitPrintOperation* printOperation, CloseAfterPrintTest* test) + { + test->printFinished(); + } + + static void webViewClosed(WebKitWebView* webView, CloseAfterPrintTest* test) + { + gtk_widget_destroy(GTK_WIDGET(webView)); + test->m_webViewClosed = true; + if (test->m_printFinished) + g_main_loop_quit(test->m_mainLoop); + } + + CloseAfterPrintTest() + : m_webViewClosed(false) + , m_printFinished(false) + { + webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(m_webView), TRUE); + g_signal_connect(m_webView, "create", G_CALLBACK(webViewCreate), this); + } + + GtkWidget* createWebView() + { + GtkWidget* newWebView = webkit_web_view_new_with_context(m_webContext.get()); + g_object_ref_sink(newWebView); + + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(newWebView)); + g_signal_connect(newWebView, "print", G_CALLBACK(webViewPrint), this); + g_signal_connect(newWebView, "close", G_CALLBACK(webViewClosed), this); + return newWebView; + } + + void print(WebKitPrintOperation* printOperation) + { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printOperation)); + + GRefPtr<GtkPrinter> printer = adoptGRef(findPrintToFilePrinter()); + if (!printer) { + g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found"); + return; + } + + GUniquePtr<char> outputFilename(g_build_filename(Test::dataDirectory(), "webkit-close-after-print.pdf", nullptr)); + m_outputFile = adoptGRef(g_file_new_for_path(outputFilename.get())); + GUniquePtr<char> outputURI(g_file_get_uri(m_outputFile.get())); + + GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new()); + gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get())); + gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, outputURI.get()); + webkit_print_operation_set_print_settings(printOperation, printSettings.get()); + + m_printOperation = printOperation; + g_signal_connect(m_printOperation.get(), "finished", G_CALLBACK(printOperationFinished), this); + webkit_print_operation_print(m_printOperation.get()); + } + + void printFinished() + { + m_printFinished = true; + m_printOperation = nullptr; + g_assert(m_outputFile); + g_file_delete(m_outputFile.get(), 0, 0); + m_outputFile = nullptr; + if (m_webViewClosed) + g_main_loop_quit(m_mainLoop); + } + + void waitUntilPrintFinishedAndViewClosed() + { + g_main_loop_run(m_mainLoop); + } + + GRefPtr<WebKitPrintOperation> m_printOperation; + GRefPtr<GFile> m_outputFile; + bool m_webViewClosed; + bool m_printFinished; +}; + +static void testPrintOperationCloseAfterPrint(CloseAfterPrintTest* test, gconstpointer) +{ + test->loadHtml("<html><body onLoad=\"w = window.open();w.print();w.close();\"></body></html>", 0); + test->waitUntilPrintFinishedAndViewClosed(); +} +#endif // HAVE_GTK_UNIX_PRINTING + +void beforeAll() +{ + WebViewTest::add("WebKitPrintOperation", "printing-settings", testPrintOperationPrintSettings); + WebViewTest::add("WebKitWebView", "print", testWebViewPrint); +#ifdef HAVE_GTK_UNIX_PRINTING + PrintTest::add("WebKitPrintOperation", "print", testPrintOperationPrint); + PrintTest::add("WebKitPrintOperation", "print-errors", testPrintOperationErrors); + CloseAfterPrintTest::add("WebKitPrintOperation", "close-after-print", testPrintOperationCloseAfterPrint); +#endif +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestResources.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestResources.cpp new file mode 100644 index 000000000..1510e5d49 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestResources.cpp @@ -0,0 +1,877 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebKitTestServer.h" +#include "WebViewTest.h" +#include <wtf/Vector.h> +#include <wtf/glib/GMutexLocker.h> +#include <wtf/glib/GRefPtr.h> + +static WebKitTestServer* kServer; + +static const char* kIndexHtml = + "<html><head>" + " <link rel='stylesheet' href='/style.css' type='text/css'>" + " <script language='javascript' src='/javascript.js'></script>" + "</head><body>WebKitGTK+ resources test</body></html>"; + +static const char* kStyleCSS = + "body {" + " margin: 0px;" + " padding: 0px;" + " font-family: sans-serif;" + " background: url(/blank.ico) 0 0 no-repeat;" + " color: black;" + "}"; + +static const char* kJavascript = "function foo () { var a = 1; }"; + +class ResourcesTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(ResourcesTest); + + static void resourceSentRequestCallback(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse, ResourcesTest* test) + { + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + if (redirectResponse) + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(redirectResponse)); + test->resourceSentRequest(resource, request, redirectResponse); + } + + static void resourceReceivedResponseCallback(WebKitWebResource* resource, GParamSpec*, ResourcesTest* test) + { + g_assert(webkit_web_resource_get_response(resource)); + test->resourceReceivedResponse(resource); + } + + static void resourceReceivedDataCallback(WebKitWebResource* resource, guint64 bytesReceived, ResourcesTest* test) + { + test->resourceReceivedData(resource, bytesReceived); + } + + static void resourceFinishedCallback(WebKitWebResource* resource, ResourcesTest* test) + { + test->resourceFinished(resource); + } + + static void resourceFailedCallback(WebKitWebResource* resource, GError* error, ResourcesTest* test) + { + g_assert(error); + test->resourceFailed(resource, error); + } + + static void resourceLoadStartedCallback(WebKitWebView* webView, WebKitWebResource* resource, WebKitURIRequest* request, ResourcesTest* test) + { + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(resource)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + + // Ignore favicons. + if (g_str_has_suffix(webkit_uri_request_get_uri(request), "favicon.ico")) + return; + + test->resourceLoadStarted(resource, request); + g_signal_connect(resource, "sent-request", G_CALLBACK(resourceSentRequestCallback), test); + g_signal_connect(resource, "notify::response", G_CALLBACK(resourceReceivedResponseCallback), test); + g_signal_connect(resource, "received-data", G_CALLBACK(resourceReceivedDataCallback), test); + g_signal_connect(resource, "finished", G_CALLBACK(resourceFinishedCallback), test); + g_signal_connect(resource, "failed", G_CALLBACK(resourceFailedCallback), test); + } + + void clearSubresources() + { + g_list_free_full(m_subresources, reinterpret_cast<GDestroyNotify>(g_object_unref)); + m_subresources = 0; + } + + ResourcesTest() + : WebViewTest() + , m_resourcesLoaded(0) + , m_resourcesToLoad(0) + , m_resourceDataSize(0) + , m_subresources(0) + { + g_signal_connect(m_webView, "resource-load-started", G_CALLBACK(resourceLoadStartedCallback), this); + } + + ~ResourcesTest() + { + clearSubresources(); + } + + virtual void resourceLoadStarted(WebKitWebResource* resource, WebKitURIRequest* request) + { + } + + virtual void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse) + { + } + + virtual void resourceReceivedResponse(WebKitWebResource* resource) + { + } + + virtual void resourceReceivedData(WebKitWebResource* resource, guint64 bytesReceived) + { + } + + virtual void resourceFinished(WebKitWebResource* resource) + { + g_signal_handlers_disconnect_matched(resource, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + if (webkit_web_view_get_main_resource(m_webView) != resource) + m_subresources = g_list_prepend(m_subresources, g_object_ref(resource)); + if (++m_resourcesLoaded == m_resourcesToLoad) + g_main_loop_quit(m_mainLoop); + } + + virtual void resourceFailed(WebKitWebResource* resource, GError* error) + { + g_assert_not_reached(); + } + + void waitUntilResourcesLoaded(size_t resourcesCount) + { + m_resourcesLoaded = 0; + m_resourcesToLoad = resourcesCount; + clearSubresources(); + g_main_loop_run(m_mainLoop); + } + + GList* subresources() + { + return m_subresources; + } + + static void resourceGetDataCallback(GObject* object, GAsyncResult* result, gpointer userData) + { + size_t dataSize; + GUniqueOutPtr<GError> error; + unsigned char* data = webkit_web_resource_get_data_finish(WEBKIT_WEB_RESOURCE(object), result, &dataSize, &error.outPtr()); + g_assert(!error.get()); + g_assert(data); + g_assert_cmpint(dataSize, >, 0); + + ResourcesTest* test = static_cast<ResourcesTest*>(userData); + test->m_resourceData.reset(reinterpret_cast<char*>(data)); + test->m_resourceDataSize = dataSize; + g_main_loop_quit(test->m_mainLoop); + } + + void checkResourceData(WebKitWebResource* resource) + { + m_resourceDataSize = 0; + webkit_web_resource_get_data(resource, 0, resourceGetDataCallback, this); + g_main_loop_run(m_mainLoop); + + const char* uri = webkit_web_resource_get_uri(resource); + if (uri == kServer->getURIForPath("/")) { + g_assert_cmpint(m_resourceDataSize, ==, strlen(kIndexHtml)); + g_assert(!strncmp(m_resourceData.get(), kIndexHtml, m_resourceDataSize)); + } else if (uri == kServer->getURIForPath("/style.css")) { + g_assert_cmpint(m_resourceDataSize, ==, strlen(kStyleCSS)); + g_assert(!strncmp(m_resourceData.get(), kStyleCSS, m_resourceDataSize)); + } else if (uri == kServer->getURIForPath("/javascript.js")) { + g_assert_cmpint(m_resourceDataSize, ==, strlen(kJavascript)); + g_assert(!strncmp(m_resourceData.get(), kJavascript, m_resourceDataSize)); + } else if (uri == kServer->getURIForPath("/blank.ico")) { + GUniquePtr<char> filePath(g_build_filename(Test::getResourcesDir().data(), "blank.ico", nullptr)); + GUniqueOutPtr<char> contents; + gsize contentsLength; + g_file_get_contents(filePath.get(), &contents.outPtr(), &contentsLength, nullptr); + g_assert_cmpint(m_resourceDataSize, ==, contentsLength); + g_assert(!memcmp(m_resourceData.get(), contents.get(), contentsLength)); + } else + g_assert_not_reached(); + m_resourceData.reset(); + } + + size_t m_resourcesLoaded; + size_t m_resourcesToLoad; + GUniquePtr<char> m_resourceData; + size_t m_resourceDataSize; + GList* m_subresources; +}; + +static void testWebViewResources(ResourcesTest* test, gconstpointer) +{ + // Nothing loaded yet, there shoulnd't be resources. + g_assert(!webkit_web_view_get_main_resource(test->m_webView)); + g_assert(!test->subresources()); + + // Load simple page without subresources. + test->loadHtml("<html><body>Testing WebKitGTK+</body></html>", 0); + test->waitUntilLoadFinished(); + WebKitWebResource* resource = webkit_web_view_get_main_resource(test->m_webView); + g_assert(resource); + g_assert_cmpstr(webkit_web_view_get_uri(test->m_webView), ==, webkit_web_resource_get_uri(resource)); + g_assert(!test->subresources()); + + // Load simple page with subresources. + test->loadURI(kServer->getURIForPath("/").data()); + test->waitUntilResourcesLoaded(4); + + resource = webkit_web_view_get_main_resource(test->m_webView); + g_assert(resource); + g_assert_cmpstr(webkit_web_view_get_uri(test->m_webView), ==, webkit_web_resource_get_uri(resource)); + GList* subresources = test->subresources(); + g_assert(subresources); + g_assert_cmpint(g_list_length(subresources), ==, 3); + +#if 0 + // Load the same URI again. + // FIXME: we need a workaround for bug https://bugs.webkit.org/show_bug.cgi?id=78510. + test->loadURI(kServer->getURIForPath("/").data()); + test->waitUntilResourcesLoaded(4); +#endif + + // Reload. + webkit_web_view_reload_bypass_cache(test->m_webView); + test->waitUntilResourcesLoaded(4); +} + +class SingleResourceLoadTest: public ResourcesTest { +public: + MAKE_GLIB_TEST_FIXTURE(SingleResourceLoadTest); + + enum LoadEvents { + Started, + SentRequest, + Redirected, + ReceivedResponse, + ReceivedData, + Finished, + Failed + }; + + SingleResourceLoadTest() + : ResourcesTest() + , m_resourceDataReceived(0) + { + m_resourcesToLoad = 2; + } + + void resourceLoadStarted(WebKitWebResource* resource, WebKitURIRequest* request) + { + if (resource == webkit_web_view_get_main_resource(m_webView)) + return; + + m_resourceDataReceived = 0; + m_resource = resource; + m_loadEvents.append(Started); + } + + void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse) + { + if (resource != m_resource) + return; + + if (redirectResponse) + m_loadEvents.append(Redirected); + else + m_loadEvents.append(SentRequest); + } + + void resourceReceivedResponse(WebKitWebResource* resource) + { + if (resource != m_resource) + return; + + m_loadEvents.append(ReceivedResponse); + } + + void resourceReceivedData(WebKitWebResource* resource, guint64 bytesReceived) + { + if (resource != m_resource) + return; + + m_resourceDataReceived += bytesReceived; + if (!m_loadEvents.contains(ReceivedData)) + m_loadEvents.append(ReceivedData); + } + + void resourceFinished(WebKitWebResource* resource) + { + if (resource != m_resource) { + ResourcesTest::resourceFinished(resource); + return; + } + + if (!m_loadEvents.contains(Failed)) { + WebKitURIResponse* response = webkit_web_resource_get_response(m_resource.get()); + g_assert(response); + g_assert_cmpint(webkit_uri_response_get_content_length(response), ==, m_resourceDataReceived); + } + m_loadEvents.append(Finished); + ResourcesTest::resourceFinished(resource); + } + + void resourceFailed(WebKitWebResource* resource, GError* error) + { + if (resource == m_resource) + m_loadEvents.append(Failed); + } + + void waitUntilResourceLoadFinished() + { + m_resource = 0; + m_resourcesLoaded = 0; + g_main_loop_run(m_mainLoop); + } + + WebKitURIResponse* waitUntilResourceLoadFinishedAndReturnURIResponse() + { + waitUntilResourceLoadFinished(); + g_assert(m_resource); + return webkit_web_resource_get_response(m_resource.get()); + } + + GRefPtr<WebKitWebResource> m_resource; + Vector<LoadEvents> m_loadEvents; + guint64 m_resourceDataReceived; +}; + +static void testWebResourceLoading(SingleResourceLoadTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/javascript.html").data()); + test->waitUntilResourceLoadFinished(); + g_assert(test->m_resource); + Vector<SingleResourceLoadTest::LoadEvents>& events = test->m_loadEvents; + g_assert_cmpint(events.size(), ==, 5); + g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started); + g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest); + g_assert_cmpint(events[2], ==, SingleResourceLoadTest::ReceivedResponse); + g_assert_cmpint(events[3], ==, SingleResourceLoadTest::ReceivedData); + g_assert_cmpint(events[4], ==, SingleResourceLoadTest::Finished); + events.clear(); + + test->loadURI(kServer->getURIForPath("/redirected-css.html").data()); + test->waitUntilResourceLoadFinished(); + g_assert(test->m_resource); + g_assert_cmpint(events.size(), ==, 6); + g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started); + g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest); + g_assert_cmpint(events[2], ==, SingleResourceLoadTest::Redirected); + g_assert_cmpint(events[3], ==, SingleResourceLoadTest::ReceivedResponse); + g_assert_cmpint(events[4], ==, SingleResourceLoadTest::ReceivedData); + g_assert_cmpint(events[5], ==, SingleResourceLoadTest::Finished); + events.clear(); + + test->loadURI(kServer->getURIForPath("/invalid-css.html").data()); + test->waitUntilResourceLoadFinished(); + g_assert(test->m_resource); + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started); + g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest); + g_assert_cmpint(events[2], ==, SingleResourceLoadTest::Failed); + g_assert_cmpint(events[3], ==, SingleResourceLoadTest::Finished); + events.clear(); +} + +static void testWebResourceResponse(SingleResourceLoadTest* test, gconstpointer) +{ + // No cached resource: First load. + test->loadURI(kServer->getURIForPath("/javascript.html").data()); + WebKitURIResponse* response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); + + // No cached resource: Second load. + test->loadURI(kServer->getURIForPath("/javascript.html").data()); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); + + // No cached resource: Reload. + webkit_web_view_reload(test->m_webView); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); + + // Cached resource: First load. + test->loadURI(kServer->getURIForPath("/image.html").data()); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); + + // Cached resource: Second load. + test->loadURI(kServer->getURIForPath("/image.html").data()); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_OK); + + // Cached resource: Reload. + webkit_web_view_reload(test->m_webView); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpint(webkit_uri_response_get_status_code(response), ==, SOUP_STATUS_NOT_MODIFIED); +} + +static void testWebResourceMimeType(SingleResourceLoadTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/javascript.html").data()); + WebKitURIResponse* response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "text/javascript"); + + test->loadURI(kServer->getURIForPath("/image.html").data()); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "image/x-icon"); + + test->loadURI(kServer->getURIForPath("/redirected-css.html").data()); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "text/css"); +} + +static void testWebResourceSuggestedFilename(SingleResourceLoadTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/javascript.html").data()); + WebKitURIResponse* response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert_cmpstr(webkit_uri_response_get_suggested_filename(response), ==, "JavaScript.js"); + + test->loadURI(kServer->getURIForPath("/image.html").data()); + response = test->waitUntilResourceLoadFinishedAndReturnURIResponse(); + g_assert(!webkit_uri_response_get_suggested_filename(response)); +} + +class ResourceURITrackingTest: public SingleResourceLoadTest { +public: + MAKE_GLIB_TEST_FIXTURE(ResourceURITrackingTest); + + ResourceURITrackingTest() + : SingleResourceLoadTest() + { + } + + static void uriChanged(WebKitWebResource* resource, GParamSpec*, ResourceURITrackingTest* test) + { + g_assert(resource == test->m_resource.get()); + g_assert_cmpstr(test->m_activeURI.data(), !=, webkit_web_resource_get_uri(test->m_resource.get())); + test->m_activeURI = webkit_web_resource_get_uri(test->m_resource.get()); + } + + void resourceLoadStarted(WebKitWebResource* resource, WebKitURIRequest* request) + { + if (resource == webkit_web_view_get_main_resource(m_webView)) + return; + + m_resource = resource; + m_activeURI = webkit_web_resource_get_uri(resource); + checkActiveURI("/redirected.css"); + g_assert_cmpstr(m_activeURI.data(), ==, webkit_uri_request_get_uri(request)); + g_signal_connect(resource, "notify::uri", G_CALLBACK(uriChanged), this); + } + + void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse) + { + if (resource != m_resource) + return; + + if (redirectResponse) + checkActiveURI("/simple-style.css"); + else + checkActiveURI("/redirected.css"); + g_assert_cmpstr(m_activeURI.data(), ==, webkit_uri_request_get_uri(request)); + } + + void resourceReceivedResponse(WebKitWebResource* resource) + { + if (resource != m_resource) + return; + + checkActiveURI("/simple-style.css"); + } + + void resourceReceivedData(WebKitWebResource* resource, guint64 bytesReceived) + { + } + + void resourceFinished(WebKitWebResource* resource) + { + if (resource == m_resource) + checkActiveURI("/simple-style.css"); + ResourcesTest::resourceFinished(resource); + } + + void resourceFailed(WebKitWebResource*, GError*) + { + g_assert_not_reached(); + } + + CString m_activeURI; + +private: + void checkActiveURI(const char* uri) + { + ASSERT_CMP_CSTRING(m_activeURI, ==, kServer->getURIForPath(uri)); + } +}; + +static void testWebResourceActiveURI(ResourceURITrackingTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/redirected-css.html").data()); + test->waitUntilResourceLoadFinished(); +} + +static void testWebResourceGetData(ResourcesTest* test, gconstpointer) +{ + test->loadURI(kServer->getURIForPath("/").data()); + test->waitUntilResourcesLoaded(4); + + WebKitWebResource* resource = webkit_web_view_get_main_resource(test->m_webView); + g_assert(resource); + test->checkResourceData(resource); + + GList* subresources = test->subresources(); + for (GList* item = subresources; item; item = g_list_next(item)) + test->checkResourceData(WEBKIT_WEB_RESOURCE(item->data)); +} + +static void testWebViewResourcesHistoryCache(SingleResourceLoadTest* test, gconstpointer) +{ + CString javascriptURI = kServer->getURIForPath("/javascript.html"); + test->loadURI(javascriptURI.data()); + test->waitUntilResourceLoadFinished(); + WebKitWebResource* resource = webkit_web_view_get_main_resource(test->m_webView); + g_assert(resource); + g_assert_cmpstr(webkit_web_resource_get_uri(resource), ==, javascriptURI.data()); + + CString simpleStyleCSSURI = kServer->getURIForPath("/simple-style-css.html"); + test->loadURI(simpleStyleCSSURI.data()); + test->waitUntilResourceLoadFinished(); + resource = webkit_web_view_get_main_resource(test->m_webView); + g_assert(resource); + g_assert_cmpstr(webkit_web_resource_get_uri(resource), ==, simpleStyleCSSURI.data()); + + test->goBack(); + test->waitUntilResourceLoadFinished(); + resource = webkit_web_view_get_main_resource(test->m_webView); + g_assert(resource); + g_assert_cmpstr(webkit_web_resource_get_uri(resource), ==, javascriptURI.data()); + + test->goForward(); + test->waitUntilResourceLoadFinished(); + resource = webkit_web_view_get_main_resource(test->m_webView); + g_assert(resource); + g_assert_cmpstr(webkit_web_resource_get_uri(resource), ==, simpleStyleCSSURI.data()); +} + +class SendRequestTest: public SingleResourceLoadTest { +public: + MAKE_GLIB_TEST_FIXTURE(SendRequestTest); + + void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse) + { + if (resource != m_resource) + return; + + if (redirectResponse) + g_assert_cmpstr(webkit_uri_request_get_uri(request), ==, m_expectedNewResourceURIAfterRedirection.data()); + else + g_assert_cmpstr(webkit_uri_request_get_uri(request), ==, m_expectedNewResourceURI.data()); + g_assert_cmpstr(webkit_uri_request_get_uri(request), ==, webkit_web_resource_get_uri(resource)); + + SingleResourceLoadTest::resourceSentRequest(resource, request, redirectResponse); + } + + void resourceFailed(WebKitWebResource* resource, GError* error) + { + if (resource != m_resource) + return; + + g_assert_cmpstr(webkit_web_resource_get_uri(resource), ==, m_expectedCancelledResourceURI.data()); + g_assert_error(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED); + + SingleResourceLoadTest::resourceFailed(resource, error); + } + + void setExpectedNewResourceURI(const CString& uri) + { + m_expectedNewResourceURI = uri; + } + + void setExpectedCancelledResourceURI(const CString& uri) + { + m_expectedCancelledResourceURI = uri; + } + + void setExpectedNewResourceURIAfterRedirection(const CString& uri) + { + m_expectedNewResourceURIAfterRedirection = uri; + } + + CString m_expectedNewResourceURI; + CString m_expectedCancelledResourceURI; + CString m_expectedNewResourceURIAfterRedirection; +}; + +static void testWebResourceSendRequest(SendRequestTest* test, gconstpointer) +{ + test->setExpectedNewResourceURI(kServer->getURIForPath("/javascript.js")); + test->loadURI(kServer->getURIForPath("relative-javascript.html").data()); + test->waitUntilResourceLoadFinished(); + g_assert(test->m_resource); + + Vector<SingleResourceLoadTest::LoadEvents>& events = test->m_loadEvents; + g_assert_cmpint(events.size(), ==, 5); + g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started); + g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest); + g_assert_cmpint(events[2], ==, SingleResourceLoadTest::ReceivedResponse); + g_assert_cmpint(events[3], ==, SingleResourceLoadTest::ReceivedData); + g_assert_cmpint(events[4], ==, SingleResourceLoadTest::Finished); + events.clear(); + + // Cancel request. + test->setExpectedCancelledResourceURI(kServer->getURIForPath("/cancel-this.js")); + test->loadURI(kServer->getURIForPath("/resource-to-cancel.html").data()); + test->waitUntilResourceLoadFinished(); + g_assert(test->m_resource); + + g_assert_cmpint(events.size(), ==, 3); + g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started); + g_assert_cmpint(events[1], ==, SingleResourceLoadTest::Failed); + g_assert_cmpint(events[2], ==, SingleResourceLoadTest::Finished); + events.clear(); + + // URI changed after a redirect. + test->setExpectedNewResourceURI(kServer->getURIForPath("/redirected.js")); + test->setExpectedNewResourceURIAfterRedirection(kServer->getURIForPath("/javascript-after-redirection.js")); + test->loadURI(kServer->getURIForPath("redirected-javascript.html").data()); + test->waitUntilResourceLoadFinished(); + g_assert(test->m_resource); + + g_assert_cmpint(events.size(), ==, 6); + g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started); + g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest); + g_assert_cmpint(events[2], ==, SingleResourceLoadTest::Redirected); + g_assert_cmpint(events[3], ==, SingleResourceLoadTest::ReceivedResponse); + g_assert_cmpint(events[4], ==, SingleResourceLoadTest::ReceivedData); + g_assert_cmpint(events[5], ==, SingleResourceLoadTest::Finished); + events.clear(); + + // Cancel after a redirect. + test->setExpectedNewResourceURI(kServer->getURIForPath("/redirected-to-cancel.js")); + test->setExpectedCancelledResourceURI(kServer->getURIForPath("/redirected-to-cancel.js")); + test->loadURI(kServer->getURIForPath("/redirected-to-cancel.html").data()); + test->waitUntilResourceLoadFinished(); + g_assert(test->m_resource); + + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started); + g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest); + g_assert_cmpint(events[2], ==, SingleResourceLoadTest::Failed); + g_assert_cmpint(events[3], ==, SingleResourceLoadTest::Finished); + events.clear(); +} + +static GMutex s_serverMutex; +static const unsigned s_maxConnectionsPerHost = 6; + +class SyncRequestOnMaxConnsTest: public ResourcesTest { +public: + MAKE_GLIB_TEST_FIXTURE(SyncRequestOnMaxConnsTest); + + void resourceLoadStarted(WebKitWebResource*, WebKitURIRequest*) override + { + if (!m_resourcesToStartPending) + return; + + if (!--m_resourcesToStartPending) + g_main_loop_quit(m_mainLoop); + } + + void waitUntilResourcesStarted(unsigned requestCount) + { + m_resourcesToStartPending = requestCount; + g_main_loop_run(m_mainLoop); + } + + unsigned m_resourcesToStartPending; +}; + +static void testWebViewSyncRequestOnMaxConns(SyncRequestOnMaxConnsTest* test, gconstpointer) +{ + WTF::GMutexLocker<GMutex> lock(s_serverMutex); + test->loadURI(kServer->getURIForPath("/sync-request-on-max-conns-0").data()); + test->waitUntilResourcesStarted(s_maxConnectionsPerHost + 1); // s_maxConnectionsPerHost resource + main resource. + + for (unsigned i = 0; i < 2; ++i) { + GUniquePtr<char> xhr(g_strdup_printf("xhr = new XMLHttpRequest; xhr.open('GET', '/sync-request-on-max-conns-xhr%u', false); xhr.send();", i)); + webkit_web_view_run_javascript(test->m_webView, xhr.get(), nullptr, nullptr, nullptr); + } + + // By default sync XHRs have a 10 seconds timeout, we don't want to wait all that so use our own timeout. + guint timeoutSourceID = g_timeout_add(1000, [] (gpointer) -> gboolean { + g_assert_not_reached(); + return G_SOURCE_REMOVE; + }, nullptr); + + struct UnlockServerSourceContext { + WTF::GMutexLocker<GMutex>& lock; + guint unlockServerSourceID; + } context = { + lock, + g_idle_add_full(G_PRIORITY_DEFAULT, [](gpointer userData) -> gboolean { + auto& context = *static_cast<UnlockServerSourceContext*>(userData); + context.unlockServerSourceID = 0; + context.lock.unlock(); + return G_SOURCE_REMOVE; + }, &context, nullptr) + }; + test->waitUntilResourcesLoaded(s_maxConnectionsPerHost + 3); // s_maxConnectionsPerHost resource + main resource + 2 XHR. + g_source_remove(timeoutSourceID); + if (context.unlockServerSourceID) + g_source_remove(context.unlockServerSourceID); +} + +static void addCacheHTTPHeadersToResponse(SoupMessage* message) +{ + // The actual date doesn't really matter. + SoupDate* soupDate = soup_date_new_from_now(0); + GUniquePtr<char> date(soup_date_to_string(soupDate, SOUP_DATE_HTTP)); + soup_message_headers_append(message->response_headers, "Last-Modified", date.get()); + soup_date_free(soupDate); + soup_message_headers_append(message->response_headers, "Cache-control", "public, max-age=31536000"); + soupDate = soup_date_new_from_now(3600); + date.reset(soup_date_to_string(soupDate, SOUP_DATE_HTTP)); + soup_message_headers_append(message->response_headers, "Expires", date.get()); + soup_date_free(soupDate); +} + +static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + soup_message_set_status(message, SOUP_STATUS_OK); + + if (soup_message_headers_get_one(message->request_headers, "If-Modified-Since")) { + soup_message_set_status(message, SOUP_STATUS_NOT_MODIFIED); + soup_message_body_complete(message->response_body); + return; + } + + if (g_str_equal(path, "/")) { + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kIndexHtml, strlen(kIndexHtml)); + } else if (g_str_equal(path, "/javascript.html")) { + static const char* javascriptHtml = "<html><head><script language='javascript' src='/javascript.js'></script></head><body></body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, javascriptHtml, strlen(javascriptHtml)); + } else if (g_str_equal(path, "/image.html")) { + static const char* imageHTML = "<html><body><img src='/blank.ico'></img></body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, imageHTML, strlen(imageHTML)); + } else if (g_str_equal(path, "/redirected-css.html")) { + static const char* redirectedCSSHtml = "<html><head><link rel='stylesheet' href='/redirected.css' type='text/css'></head><body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, redirectedCSSHtml, strlen(redirectedCSSHtml)); + } else if (g_str_equal(path, "/invalid-css.html")) { + static const char* invalidCSSHtml = "<html><head><link rel='stylesheet' href='/invalid.css' type='text/css'></head><body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, invalidCSSHtml, strlen(invalidCSSHtml)); + } else if (g_str_equal(path, "/simple-style-css.html")) { + static const char* simpleStyleCSSHtml = "<html><head><link rel='stylesheet' href='/simple-style.css' type='text/css'></head><body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, simpleStyleCSSHtml, strlen(simpleStyleCSSHtml)); + } else if (g_str_equal(path, "/style.css")) { + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kStyleCSS, strlen(kStyleCSS)); + addCacheHTTPHeadersToResponse(message); + soup_message_headers_append(message->response_headers, "Content-Type", "text/css"); + } else if (g_str_equal(path, "/javascript.js") || g_str_equal(path, "/javascript-after-redirection.js")) { + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kJavascript, strlen(kJavascript)); + soup_message_headers_append(message->response_headers, "Content-Type", "text/javascript"); + soup_message_headers_append(message->response_headers, "Content-Disposition", "filename=JavaScript.js"); + } else if (g_str_equal(path, "/relative-javascript.html")) { + static const char* javascriptRelativeHTML = "<html><head><script language='javascript' src='remove-this/javascript.js'></script></head><body></body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, javascriptRelativeHTML, strlen(javascriptRelativeHTML)); + } else if (g_str_equal(path, "/resource-to-cancel.html")) { + static const char* resourceToCancelHTML = "<html><head><script language='javascript' src='cancel-this.js'></script></head><body></body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, resourceToCancelHTML, strlen(resourceToCancelHTML)); + } else if (g_str_equal(path, "/redirected-javascript.html")) { + static const char* javascriptRelativeHTML = "<html><head><script language='javascript' src='/redirected.js'></script></head><body></body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, javascriptRelativeHTML, strlen(javascriptRelativeHTML)); + } else if (g_str_equal(path, "/redirected-to-cancel.html")) { + static const char* javascriptRelativeHTML = "<html><head><script language='javascript' src='/redirected-to-cancel.js'></script></head><body></body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, javascriptRelativeHTML, strlen(javascriptRelativeHTML)); + } else if (g_str_equal(path, "/blank.ico")) { + GUniquePtr<char> filePath(g_build_filename(Test::getResourcesDir().data(), path, nullptr)); + char* contents; + gsize contentsLength; + g_file_get_contents(filePath.get(), &contents, &contentsLength, 0); + soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, contentsLength); + addCacheHTTPHeadersToResponse(message); + soup_message_headers_append(message->response_headers, "Content-Type", "image/vnd.microsoft.icon"); + } else if (g_str_equal(path, "/simple-style.css")) { + static const char* simpleCSS = + "body {" + " margin: 0px;" + " padding: 0px;" + "}"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, simpleCSS, strlen(simpleCSS)); + soup_message_headers_append(message->response_headers, "Content-Type", "text/css"); + } else if (g_str_equal(path, "/redirected.css")) { + soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY); + soup_message_headers_append(message->response_headers, "Location", "/simple-style.css"); + } else if (g_str_equal(path, "/redirected.js")) { + soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY); + soup_message_headers_append(message->response_headers, "Location", "/remove-this/javascript-after-redirection.js"); + } else if (g_str_equal(path, "/redirected-to-cancel.js")) { + soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY); + soup_message_headers_append(message->response_headers, "Location", "/cancel-this.js"); + } else if (g_str_equal(path, "/invalid.css")) + soup_message_set_status(message, SOUP_STATUS_CANT_CONNECT); + else if (g_str_has_prefix(path, "/sync-request-on-max-conns-")) { + char* contents; + gsize contentsLength; + if (g_str_equal(path, "/sync-request-on-max-conns-0")) { + GString* imagesHTML = g_string_new("<html><body>"); + for (unsigned i = 1; i <= s_maxConnectionsPerHost; ++i) + g_string_append_printf(imagesHTML, "<img src='/sync-request-on-max-conns-%u'>", i); + g_string_append(imagesHTML, "</body></html>"); + + contentsLength = imagesHTML->len; + contents = g_string_free(imagesHTML, FALSE); + } else { + { + // We don't actually need to keep the mutex, so we release it as soon as we get it. + WTF::GMutexLocker<GMutex> lock(s_serverMutex); + } + + GUniquePtr<char> filePath(g_build_filename(Test::getResourcesDir().data(), "blank.ico", nullptr)); + g_file_get_contents(filePath.get(), &contents, &contentsLength, 0); + } + soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, contentsLength); + } else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); + soup_message_body_complete(message->response_body); +} + +void beforeAll() +{ + kServer = new WebKitTestServer(WebKitTestServer::ServerOptions::ServerRunInThread); + kServer->run(serverCallback); + + ResourcesTest::add("WebKitWebView", "resources", testWebViewResources); + SingleResourceLoadTest::add("WebKitWebResource", "loading", testWebResourceLoading); + SingleResourceLoadTest::add("WebKitWebResource", "response", testWebResourceResponse); + SingleResourceLoadTest::add("WebKitWebResource", "mime-type", testWebResourceMimeType); + SingleResourceLoadTest::add("WebKitWebResource", "suggested-filename", testWebResourceSuggestedFilename); + ResourceURITrackingTest::add("WebKitWebResource", "active-uri", testWebResourceActiveURI); + ResourcesTest::add("WebKitWebResource", "get-data", testWebResourceGetData); + SingleResourceLoadTest::add("WebKitWebView", "history-cache", testWebViewResourcesHistoryCache); + SendRequestTest::add("WebKitWebPage", "send-request", testWebResourceSendRequest); +#if SOUP_CHECK_VERSION(2, 49, 91) + SyncRequestOnMaxConnsTest::add("WebKitWebView", "sync-request-on-max-conns", testWebViewSyncRequestOnMaxConns); +#endif +} + +void afterAll() +{ + delete kServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSSL.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSSL.cpp new file mode 100644 index 000000000..10c5e73b6 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSSL.cpp @@ -0,0 +1,434 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "LoadTrackingTest.h" +#include "WebKitTestServer.h" +#include <gtk/gtk.h> + +static WebKitTestServer* kHttpsServer; +static WebKitTestServer* kHttpServer; + +static const char* indexHTML = "<html><body>Testing WebKit2GTK+ SSL</body></htmll>"; +static const char* insecureContentHTML = "<html><script src=\"%s\"></script><body><p>Text + image <img src=\"%s\" align=\"right\"/></p></body></html>"; +static const char TLSExpectedSuccessTitle[] = "WebKit2Gtk+ TLS permission test"; +static const char TLSSuccessHTMLString[] = "<html><head><title>WebKit2Gtk+ TLS permission test</title></head><body></body></html>"; + +class SSLTest: public LoadTrackingTest { +public: + MAKE_GLIB_TEST_FIXTURE(SSLTest); + + SSLTest() + : m_tlsErrors(static_cast<GTlsCertificateFlags>(0)) + { + } + + virtual void provisionalLoadFailed(const gchar* failingURI, GError* error) + { + g_assert_error(error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED); + LoadTrackingTest::provisionalLoadFailed(failingURI, error); + } + + virtual void loadCommitted() + { + GTlsCertificate* certificate = 0; + webkit_web_view_get_tls_info(m_webView, &certificate, &m_tlsErrors); + m_certificate = certificate; + LoadTrackingTest::loadCommitted(); + } + + void waitUntilLoadFinished() + { + m_certificate = 0; + m_tlsErrors = static_cast<GTlsCertificateFlags>(0); + LoadTrackingTest::waitUntilLoadFinished(); + } + + GRefPtr<GTlsCertificate> m_certificate; + GTlsCertificateFlags m_tlsErrors; +}; + +static void testSSL(SSLTest* test, gconstpointer) +{ + WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); + WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context); + webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE); + + test->loadURI(kHttpsServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + g_assert(test->m_certificate); + // We always expect errors because we are using a self-signed certificate, + // but only G_TLS_CERTIFICATE_UNKNOWN_CA flags should be present. + g_assert(test->m_tlsErrors); + g_assert_cmpuint(test->m_tlsErrors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA); + + // Non HTTPS loads shouldn't have a certificate nor errors. + test->loadHtml(indexHTML, 0); + test->waitUntilLoadFinished(); + g_assert(!test->m_certificate); + g_assert(!test->m_tlsErrors); + + webkit_web_context_set_tls_errors_policy(context, originalPolicy); +} + +class InsecureContentTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(InsecureContentTest); + + InsecureContentTest() + : m_insecureContentRun(false) + , m_insecureContentDisplayed(false) + { + g_signal_connect(m_webView, "insecure-content-detected", G_CALLBACK(insecureContentDetectedCallback), this); + } + + static void insecureContentDetectedCallback(WebKitWebView* webView, WebKitInsecureContentEvent event, InsecureContentTest* test) + { + g_assert(webView == test->m_webView); + + if (event == WEBKIT_INSECURE_CONTENT_RUN) + test->m_insecureContentRun = true; + + if (event == WEBKIT_INSECURE_CONTENT_DISPLAYED) + test->m_insecureContentDisplayed = true; + } + + bool m_insecureContentRun; + bool m_insecureContentDisplayed; +}; + +static void testInsecureContent(InsecureContentTest* test, gconstpointer) +{ + WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); + WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context); + webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE); + + test->loadURI(kHttpsServer->getURIForPath("/insecure-content/").data()); + test->waitUntilLoadFinished(); + + g_assert(!test->m_insecureContentRun); + // Images are currently always displayed, even bypassing mixed content settings. Check + // https://bugs.webkit.org/show_bug.cgi?id=142469 + g_assert(test->m_insecureContentDisplayed); + + webkit_web_context_set_tls_errors_policy(context, originalPolicy); +} + +static bool assertIfSSLRequestProcessed = false; + +static void testTLSErrorsPolicy(SSLTest* test, gconstpointer) +{ + WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); + // TLS errors are treated as transport failures by default. + g_assert(webkit_web_context_get_tls_errors_policy(context) == WEBKIT_TLS_ERRORS_POLICY_FAIL); + + assertIfSSLRequestProcessed = true; + test->loadURI(kHttpsServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + g_assert(test->m_loadFailed); + g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted)); + assertIfSSLRequestProcessed = false; + + webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE); + g_assert(webkit_web_context_get_tls_errors_policy(context) == WEBKIT_TLS_ERRORS_POLICY_IGNORE); + + test->m_loadFailed = false; + test->loadURI(kHttpsServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + g_assert(!test->m_loadFailed); + + webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL); + g_assert(webkit_web_context_get_tls_errors_policy(context) == WEBKIT_TLS_ERRORS_POLICY_FAIL); +} + +static void testTLSErrorsRedirect(SSLTest* test, gconstpointer) +{ + WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); + WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context); + webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL); + + assertIfSSLRequestProcessed = true; + test->loadURI(kHttpsServer->getURIForPath("/redirect").data()); + test->waitUntilLoadFinished(); + g_assert(test->m_loadFailed); + g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted)); + assertIfSSLRequestProcessed = false; + + webkit_web_context_set_tls_errors_policy(context, originalPolicy); +} + +static gboolean webViewAuthenticationCallback(WebKitWebView*, WebKitAuthenticationRequest* request) +{ + g_assert_not_reached(); + return TRUE; +} + + +static void testTLSErrorsHTTPAuth(SSLTest* test, gconstpointer) +{ + WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); + WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context); + webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL); + + assertIfSSLRequestProcessed = true; + g_signal_connect(test->m_webView, "authenticate", G_CALLBACK(webViewAuthenticationCallback), NULL); + test->loadURI(kHttpsServer->getURIForPath("/auth").data()); + test->waitUntilLoadFinished(); + g_assert(test->m_loadFailed); + g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted)); + assertIfSSLRequestProcessed = false; + + webkit_web_context_set_tls_errors_policy(context, originalPolicy); +} + +class TLSErrorsTest: public SSLTest { +public: + MAKE_GLIB_TEST_FIXTURE(TLSErrorsTest); + + TLSErrorsTest() + : m_tlsErrors(static_cast<GTlsCertificateFlags>(0)) + , m_failingURI(nullptr) + { + } + + ~TLSErrorsTest() + { + if (m_failingURI) + soup_uri_free(m_failingURI); + } + + bool loadFailedWithTLSErrors(const char* failingURI, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors) override + { + LoadTrackingTest::loadFailedWithTLSErrors(failingURI, certificate, tlsErrors); + + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(certificate)); + m_certificate = certificate; + m_tlsErrors = tlsErrors; + if (m_failingURI) + soup_uri_free(m_failingURI); + m_failingURI = soup_uri_new(failingURI); + return true; + } + + GTlsCertificate* certificate() const { return m_certificate.get(); } + GTlsCertificateFlags tlsErrors() const { return m_tlsErrors; } + const char* host() const { return m_failingURI->host; } + +private: + GRefPtr<GTlsCertificate> m_certificate; + GTlsCertificateFlags m_tlsErrors; + SoupURI* m_failingURI; +}; + +static void testLoadFailedWithTLSErrors(TLSErrorsTest* test, gconstpointer) +{ + WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); + WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context); + webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL); + + assertIfSSLRequestProcessed = true; + // The load-failed-with-tls-errors signal should be emitted when there is a TLS failure. + test->loadURI(kHttpsServer->getURIForPath("/test-tls/").data()); + test->waitUntilLoadFinished(); + g_assert(G_IS_TLS_CERTIFICATE(test->certificate())); + g_assert_cmpuint(test->tlsErrors(), ==, G_TLS_CERTIFICATE_UNKNOWN_CA); + g_assert_cmpstr(test->host(), ==, soup_uri_get_host(kHttpsServer->baseURI())); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadFailedWithTLSErrors); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + assertIfSSLRequestProcessed = false; + + // Test allowing an exception for this certificate on this host. + webkit_web_context_allow_tls_certificate_for_host(context, test->certificate(), test->host()); + // The page should now load without errors. + test->loadURI(kHttpsServer->getURIForPath("/test-tls/").data()); + test->waitUntilLoadFinished(); + + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, TLSExpectedSuccessTitle); + + webkit_web_context_set_tls_errors_policy(context, originalPolicy); +} + +class TLSSubresourceTest : public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(TLSSubresourceTest); + + static void resourceLoadStartedCallback(WebKitWebView* webView, WebKitWebResource* resource, WebKitURIRequest* request, TLSSubresourceTest* test) + { + if (webkit_web_view_get_main_resource(test->m_webView) == resource) + return; + + // Ignore favicons. + if (g_str_has_suffix(webkit_uri_request_get_uri(request), "favicon.ico")) + return; + + test->subresourceLoadStarted(resource); + } + + TLSSubresourceTest() + : m_tlsErrors(static_cast<GTlsCertificateFlags>(0)) + { + g_signal_connect(m_webView, "resource-load-started", G_CALLBACK(resourceLoadStartedCallback), this); + } + + static void subresourceFailedCallback(WebKitWebResource*, GError*) + { + g_assert_not_reached(); + } + + static void subresourceFailedWithTLSErrorsCallback(WebKitWebResource* resource, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors, TLSSubresourceTest* test) + { + test->subresourceFailedWithTLSErrors(resource, certificate, tlsErrors); + } + + void subresourceLoadStarted(WebKitWebResource* resource) + { + g_signal_connect(resource, "failed", G_CALLBACK(subresourceFailedCallback), nullptr); + g_signal_connect(resource, "failed-with-tls-errors", G_CALLBACK(subresourceFailedWithTLSErrorsCallback), this); + } + + void subresourceFailedWithTLSErrors(WebKitWebResource* resource, GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors) + { + m_certificate = certificate; + m_tlsErrors = tlsErrors; + g_main_loop_quit(m_mainLoop); + } + + void waitUntilSubresourceLoadFail() + { + g_main_loop_run(m_mainLoop); + } + + GRefPtr<GTlsCertificate> m_certificate; + GTlsCertificateFlags m_tlsErrors; +}; + +static void testSubresourceLoadFailedWithTLSErrors(TLSSubresourceTest* test, gconstpointer) +{ + WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); + webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL); + + assertIfSSLRequestProcessed = true; + test->loadURI(kHttpServer->getURIForPath("/").data()); + test->waitUntilSubresourceLoadFail(); + g_assert(G_IS_TLS_CERTIFICATE(test->m_certificate.get())); + g_assert_cmpuint(test->m_tlsErrors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA); + assertIfSSLRequestProcessed = false; +} + +static void httpsServerCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + g_assert(!assertIfSSLRequestProcessed); + + if (g_str_equal(path, "/")) { + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, indexHTML, strlen(indexHTML)); + soup_message_body_complete(message->response_body); + } else if (g_str_equal(path, "/insecure-content/")) { + GUniquePtr<char> responseHTML(g_strdup_printf(insecureContentHTML, kHttpServer->getURIForPath("/test-script").data(), kHttpServer->getURIForPath("/test-image").data())); + soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, responseHTML.get(), strlen(responseHTML.get())); + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_complete(message->response_body); + } else if (g_str_equal(path, "/test-tls/")) { + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, TLSSuccessHTMLString, strlen(TLSSuccessHTMLString)); + soup_message_body_complete(message->response_body); + } else if (g_str_equal(path, "/redirect")) { + soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY); + soup_message_headers_append(message->response_headers, "Location", kHttpServer->getURIForPath("/test-image").data()); + } else if (g_str_equal(path, "/auth")) { + soup_message_set_status(message, SOUP_STATUS_UNAUTHORIZED); + soup_message_headers_append(message->response_headers, "WWW-Authenticate", "Basic realm=\"HTTPS auth\""); + } else if (g_str_equal(path, "/style.css")) { + soup_message_set_status(message, SOUP_STATUS_OK); + static const char* styleCSS = "body { color: black; }"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, styleCSS, strlen(styleCSS)); + } else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); +} + +static void httpServerCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + if (g_str_equal(path, "/test-script")) { + GUniquePtr<char> pathToFile(g_build_filename(Test::getResourcesDir().data(), "link-title.js", nullptr)); + char* contents; + gsize length; + g_file_get_contents(pathToFile.get(), &contents, &length, 0); + + soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, length); + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_complete(message->response_body); + } else if (g_str_equal(path, "/test-image")) { + GUniquePtr<char> pathToFile(g_build_filename(Test::getResourcesDir().data(), "blank.ico", nullptr)); + char* contents; + gsize length; + g_file_get_contents(pathToFile.get(), &contents, &length, 0); + + soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, length); + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_complete(message->response_body); + } else if (g_str_equal(path, "/")) { + soup_message_set_status(message, SOUP_STATUS_OK); + char* responseHTML = g_strdup_printf("<html><head><link rel='stylesheet' href='%s' type='text/css'></head><body>SSL subresource test</body></html>", + kHttpsServer->getURIForPath("/style.css").data()); + soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, responseHTML, strlen(responseHTML)); + soup_message_body_complete(message->response_body); + } else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); +} + +void beforeAll() +{ + kHttpsServer = new WebKitTestServer(WebKitTestServer::ServerHTTPS); + kHttpsServer->run(httpsServerCallback); + + kHttpServer = new WebKitTestServer(WebKitTestServer::ServerHTTP); + kHttpServer->run(httpServerCallback); + + SSLTest::add("WebKitWebView", "ssl", testSSL); + InsecureContentTest::add("WebKitWebView", "insecure-content", testInsecureContent); + SSLTest::add("WebKitWebView", "tls-errors-policy", testTLSErrorsPolicy); + SSLTest::add("WebKitWebView", "tls-errors-redirect-to-http", testTLSErrorsRedirect); + SSLTest::add("WebKitWebView", "tls-http-auth", testTLSErrorsHTTPAuth); + TLSSubresourceTest::add("WebKitWebView", "tls-subresource", testSubresourceLoadFailedWithTLSErrors); + TLSErrorsTest::add("WebKitWebView", "load-failed-with-tls-errors", testLoadFailedWithTLSErrors); +} + +void afterAll() +{ + delete kHttpsServer; + delete kHttpServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp new file mode 100644 index 000000000..fc48fa468 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp @@ -0,0 +1,1062 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebViewTest.h" +#include <wtf/HashSet.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/text/StringHash.h> + +static const char* kAlertDialogMessage = "WebKitGTK+ alert dialog message"; +static const char* kConfirmDialogMessage = "WebKitGTK+ confirm dialog message"; +static const char* kPromptDialogMessage = "WebKitGTK+ prompt dialog message"; +static const char* kPromptDialogReturnedText = "WebKitGTK+ prompt dialog returned text"; +static const char* kBeforeUnloadConfirmDialogMessage = "WebKitGTK+ beforeunload dialog message"; + +class UIClientTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(UIClientTest); + + enum WebViewEvents { + Create, + ReadyToShow, + RunAsModal, + Close + }; + + class WindowProperties { + public: + WindowProperties() + : m_isNull(true) + , m_toolbarVisible(true) + , m_statusbarVisible(true) + , m_scrollbarsVisible(true) + , m_menubarVisible(true) + , m_locationbarVisible(true) + , m_resizable(true) + , m_fullscreen(false) + { + memset(&m_geometry, 0, sizeof(GdkRectangle)); + } + + WindowProperties(WebKitWindowProperties* windowProperties) + : m_isNull(false) + , m_toolbarVisible(webkit_window_properties_get_toolbar_visible(windowProperties)) + , m_statusbarVisible(webkit_window_properties_get_statusbar_visible(windowProperties)) + , m_scrollbarsVisible(webkit_window_properties_get_scrollbars_visible(windowProperties)) + , m_menubarVisible(webkit_window_properties_get_menubar_visible(windowProperties)) + , m_locationbarVisible(webkit_window_properties_get_locationbar_visible(windowProperties)) + , m_resizable(webkit_window_properties_get_resizable(windowProperties)) + , m_fullscreen(webkit_window_properties_get_fullscreen(windowProperties)) + { + webkit_window_properties_get_geometry(windowProperties, &m_geometry); + } + + WindowProperties(GdkRectangle* geometry, bool toolbarVisible, bool statusbarVisible, bool scrollbarsVisible, bool menubarVisible, bool locationbarVisible, bool resizable, bool fullscreen) + : m_isNull(false) + , m_geometry(*geometry) + , m_toolbarVisible(toolbarVisible) + , m_statusbarVisible(statusbarVisible) + , m_scrollbarsVisible(scrollbarsVisible) + , m_menubarVisible(menubarVisible) + , m_locationbarVisible(locationbarVisible) + , m_resizable(resizable) + , m_fullscreen(fullscreen) + { + } + + bool isNull() const { return m_isNull; } + + void assertEqual(const WindowProperties& other) const + { + g_assert_cmpint(m_geometry.x, ==, other.m_geometry.x); + g_assert_cmpint(m_geometry.y, ==, other.m_geometry.y); + g_assert_cmpint(m_geometry.width, ==, other.m_geometry.width); + g_assert_cmpint(m_geometry.height, ==, other.m_geometry.height); + g_assert_cmpint(static_cast<int>(m_toolbarVisible), ==, static_cast<int>(other.m_toolbarVisible)); + g_assert_cmpint(static_cast<int>(m_statusbarVisible), ==, static_cast<int>(other.m_statusbarVisible)); + g_assert_cmpint(static_cast<int>(m_scrollbarsVisible), ==, static_cast<int>(other.m_scrollbarsVisible)); + g_assert_cmpint(static_cast<int>(m_menubarVisible), ==, static_cast<int>(other.m_menubarVisible)); + g_assert_cmpint(static_cast<int>(m_locationbarVisible), ==, static_cast<int>(other.m_locationbarVisible)); + g_assert_cmpint(static_cast<int>(m_resizable), ==, static_cast<int>(other.m_resizable)); + g_assert_cmpint(static_cast<int>(m_fullscreen), ==, static_cast<int>(other.m_fullscreen)); + } + + private: + bool m_isNull; + + GdkRectangle m_geometry; + + bool m_toolbarVisible; + bool m_statusbarVisible; + bool m_scrollbarsVisible; + bool m_menubarVisible; + bool m_locationbarVisible; + + bool m_resizable; + bool m_fullscreen; + }; + + static void windowPropertiesNotifyCallback(GObject*, GParamSpec* paramSpec, UIClientTest* test) + { + test->m_windowPropertiesChanged.add(g_param_spec_get_name(paramSpec)); + } + + static GtkWidget* viewCreateCallback(WebKitWebView* webView, WebKitNavigationAction* navigation, UIClientTest* test) + { + return test->viewCreate(webView, navigation); + } + + static void viewReadyToShowCallback(WebKitWebView* webView, UIClientTest* test) + { + test->viewReadyToShow(webView); + } + + static void viewCloseCallback(WebKitWebView* webView, UIClientTest* test) + { + test->viewClose(webView); + } + + void scriptAlert(WebKitScriptDialog* dialog) + { + switch (m_scriptDialogType) { + case WEBKIT_SCRIPT_DIALOG_ALERT: + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kAlertDialogMessage); + break; + case WEBKIT_SCRIPT_DIALOG_CONFIRM: + g_assert(m_scriptDialogConfirmed); + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, "confirmed"); + + break; + case WEBKIT_SCRIPT_DIALOG_PROMPT: + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kPromptDialogReturnedText); + break; + case WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: + g_assert_not_reached(); + break; + } + + g_main_loop_quit(m_mainLoop); + } + + void scriptConfirm(WebKitScriptDialog* dialog) + { + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kConfirmDialogMessage); + m_scriptDialogConfirmed = !m_scriptDialogConfirmed; + webkit_script_dialog_confirm_set_confirmed(dialog, m_scriptDialogConfirmed); + } + + void scriptPrompt(WebKitScriptDialog* dialog) + { + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kPromptDialogMessage); + g_assert_cmpstr(webkit_script_dialog_prompt_get_default_text(dialog), ==, "default"); + webkit_script_dialog_prompt_set_text(dialog, kPromptDialogReturnedText); + } + + void scriptBeforeUnloadConfirm(WebKitScriptDialog* dialog) + { + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kBeforeUnloadConfirmDialogMessage); + m_scriptDialogConfirmed = true; + webkit_script_dialog_confirm_set_confirmed(dialog, m_scriptDialogConfirmed); + } + + static gboolean scriptDialog(WebKitWebView*, WebKitScriptDialog* dialog, UIClientTest* test) + { + switch (webkit_script_dialog_get_dialog_type(dialog)) { + case WEBKIT_SCRIPT_DIALOG_ALERT: + test->scriptAlert(dialog); + break; + case WEBKIT_SCRIPT_DIALOG_CONFIRM: + test->scriptConfirm(dialog); + break; + case WEBKIT_SCRIPT_DIALOG_PROMPT: + test->scriptPrompt(dialog); + break; + case WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: + test->scriptBeforeUnloadConfirm(dialog); + break; + } + + return TRUE; + } + + static void mouseTargetChanged(WebKitWebView*, WebKitHitTestResult* hitTestResult, guint modifiers, UIClientTest* test) + { + g_assert(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(hitTestResult)); + + test->m_mouseTargetHitTestResult = hitTestResult; + test->m_mouseTargetModifiers = modifiers; + g_main_loop_quit(test->m_mainLoop); + } + + static gboolean permissionRequested(WebKitWebView*, WebKitPermissionRequest* request, UIClientTest* test) + { + g_assert(WEBKIT_IS_PERMISSION_REQUEST(request)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + + if (test->m_verifyMediaTypes && WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)) { + WebKitUserMediaPermissionRequest* userMediaRequest = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request); + g_assert(webkit_user_media_permission_is_for_audio_device(userMediaRequest) == test->m_expectedAudioMedia); + g_assert(webkit_user_media_permission_is_for_video_device(userMediaRequest) == test->m_expectedVideoMedia); + } + + if (test->m_allowPermissionRequests) + webkit_permission_request_allow(request); + else + webkit_permission_request_deny(request); + + return TRUE; + } + + UIClientTest() + : m_scriptDialogType(WEBKIT_SCRIPT_DIALOG_ALERT) + , m_scriptDialogConfirmed(true) + , m_allowPermissionRequests(false) + , m_verifyMediaTypes(false) + , m_expectedAudioMedia(false) + , m_expectedVideoMedia(false) + , m_mouseTargetModifiers(0) + { + webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(m_webView), TRUE); + g_signal_connect(m_webView, "create", G_CALLBACK(viewCreateCallback), this); + g_signal_connect(m_webView, "script-dialog", G_CALLBACK(scriptDialog), this); + g_signal_connect(m_webView, "mouse-target-changed", G_CALLBACK(mouseTargetChanged), this); + g_signal_connect(m_webView, "permission-request", G_CALLBACK(permissionRequested), this); + } + + ~UIClientTest() + { + g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + static void tryWebViewCloseCallback(UIClientTest* test) + { + g_main_loop_quit(test->m_mainLoop); + } + + void tryCloseAndWaitUntilClosed() + { + gulong handler = g_signal_connect_swapped(m_webView, "close", G_CALLBACK(tryWebViewCloseCallback), this); + // Use an idle because webkit_web_view_try_close can emit the close signal in the + // current run loop iteration. + g_idle_add([](gpointer data) -> gboolean { + webkit_web_view_try_close(WEBKIT_WEB_VIEW(data)); + return G_SOURCE_REMOVE; + }, m_webView); + g_main_loop_run(m_mainLoop); + g_signal_handler_disconnect(m_webView, handler); + } + + void waitUntilMainLoopFinishes() + { + g_main_loop_run(m_mainLoop); + } + + void setExpectedWindowProperties(const WindowProperties& windowProperties) + { + m_windowProperties = windowProperties; + } + + WebKitHitTestResult* moveMouseAndWaitUntilMouseTargetChanged(int x, int y, unsigned mouseModifiers = 0) + { + mouseMoveTo(x, y, mouseModifiers); + g_main_loop_run(m_mainLoop); + return m_mouseTargetHitTestResult.get(); + } + + virtual GtkWidget* viewCreate(WebKitWebView* webView, WebKitNavigationAction* navigation) + { + g_assert(webView == m_webView); + g_assert(navigation); + + GtkWidget* newWebView = webkit_web_view_new_with_context(webkit_web_view_get_context(webView)); + g_object_ref_sink(newWebView); + + m_webViewEvents.append(Create); + + WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(newWebView)); + g_assert(windowProperties); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(windowProperties)); + m_windowPropertiesChanged.clear(); + + g_signal_connect(windowProperties, "notify", G_CALLBACK(windowPropertiesNotifyCallback), this); + g_signal_connect(newWebView, "ready-to-show", G_CALLBACK(viewReadyToShowCallback), this); + g_signal_connect(newWebView, "close", G_CALLBACK(viewCloseCallback), this); + + return newWebView; + } + + virtual void viewReadyToShow(WebKitWebView* webView) + { + g_assert(webView != m_webView); + + WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(webView); + g_assert(windowProperties); + if (!m_windowProperties.isNull()) + WindowProperties(windowProperties).assertEqual(m_windowProperties); + + m_webViewEvents.append(ReadyToShow); + } + + virtual void viewClose(WebKitWebView* webView) + { + g_assert(webView != m_webView); + + m_webViewEvents.append(Close); + g_object_unref(webView); + + g_main_loop_quit(m_mainLoop); + } + + Vector<WebViewEvents> m_webViewEvents; + WebKitScriptDialogType m_scriptDialogType; + bool m_scriptDialogConfirmed; + bool m_allowPermissionRequests; + gboolean m_verifyMediaTypes; + gboolean m_expectedAudioMedia; + gboolean m_expectedVideoMedia; + WindowProperties m_windowProperties; + HashSet<WTF::String> m_windowPropertiesChanged; + GRefPtr<WebKitHitTestResult> m_mouseTargetHitTestResult; + unsigned m_mouseTargetModifiers; +}; + +static void testWebViewCreateReadyClose(UIClientTest* test, gconstpointer) +{ + test->loadHtml("<html><body onLoad=\"window.open().close();\"></html>", 0); + test->waitUntilMainLoopFinishes(); + + Vector<UIClientTest::WebViewEvents>& events = test->m_webViewEvents; + g_assert_cmpint(events.size(), ==, 3); + g_assert_cmpint(events[0], ==, UIClientTest::Create); + g_assert_cmpint(events[1], ==, UIClientTest::ReadyToShow); + g_assert_cmpint(events[2], ==, UIClientTest::Close); +} + +class CreateNavigationDataTest: public UIClientTest { +public: + MAKE_GLIB_TEST_FIXTURE(CreateNavigationDataTest); + + CreateNavigationDataTest() + : m_navigation(nullptr) + { + } + + ~CreateNavigationDataTest() + { + clearNavigation(); + } + + void clearNavigation() + { + if (m_navigation) + webkit_navigation_action_free(m_navigation); + m_navigation = nullptr; + } + + GtkWidget* viewCreate(WebKitWebView* webView, WebKitNavigationAction* navigation) + { + g_assert(navigation); + g_assert(!m_navigation); + m_navigation = webkit_navigation_action_copy(navigation); + g_main_loop_quit(m_mainLoop); + return nullptr; + } + + void loadHTML(const char* html) + { + clearNavigation(); + WebViewTest::loadHtml(html, nullptr); + } + + void clickAndWaitUntilMainLoopFinishes(int x, int y) + { + clearNavigation(); + clickMouseButton(x, y, 1); + g_main_loop_run(m_mainLoop); + } + + WebKitNavigationAction* m_navigation; +}; + +static void testWebViewCreateNavigationData(CreateNavigationDataTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + + test->loadHTML( + "<html><body>" + "<input style=\"position:absolute; left:0; top:0; margin:0; padding:0\" type=\"button\" value=\"click to show a popup\" onclick=\"window.open('data:foo');\"/>" + "<a style=\"position:absolute; left:20; top:20;\" href=\"data:bar\" target=\"_blank\">popup link</a>" + "</body></html>"); + test->waitUntilLoadFinished(); + + // Click on a button. + test->clickAndWaitUntilMainLoopFinishes(5, 5); + g_assert_cmpstr(webkit_uri_request_get_uri(webkit_navigation_action_get_request(test->m_navigation)), ==, "data:foo"); + g_assert_cmpuint(webkit_navigation_action_get_navigation_type(test->m_navigation), ==, WEBKIT_NAVIGATION_TYPE_OTHER); + // FIXME: This should be button 1. + g_assert_cmpuint(webkit_navigation_action_get_mouse_button(test->m_navigation), ==, 0); + g_assert_cmpuint(webkit_navigation_action_get_modifiers(test->m_navigation), ==, 0); + g_assert(webkit_navigation_action_is_user_gesture(test->m_navigation)); + + // Click on a link. + test->clickAndWaitUntilMainLoopFinishes(21, 21); + g_assert_cmpstr(webkit_uri_request_get_uri(webkit_navigation_action_get_request(test->m_navigation)), ==, "data:bar"); + g_assert_cmpuint(webkit_navigation_action_get_navigation_type(test->m_navigation), ==, WEBKIT_NAVIGATION_TYPE_LINK_CLICKED); + g_assert_cmpuint(webkit_navigation_action_get_mouse_button(test->m_navigation), ==, 1); + g_assert_cmpuint(webkit_navigation_action_get_modifiers(test->m_navigation), ==, 0); + g_assert(webkit_navigation_action_is_user_gesture(test->m_navigation)); + + // No user interaction. + test->loadHTML("<html><body onLoad=\"window.open();\"></html>"); + test->waitUntilMainLoopFinishes(); + + g_assert_cmpstr(webkit_uri_request_get_uri(webkit_navigation_action_get_request(test->m_navigation)), ==, ""); + g_assert_cmpuint(webkit_navigation_action_get_navigation_type(test->m_navigation), ==, WEBKIT_NAVIGATION_TYPE_OTHER); + g_assert_cmpuint(webkit_navigation_action_get_mouse_button(test->m_navigation), ==, 0); + g_assert_cmpuint(webkit_navigation_action_get_modifiers(test->m_navigation), ==, 0); + g_assert(!webkit_navigation_action_is_user_gesture(test->m_navigation)); +} + +static gboolean checkMimeTypeForFilter(GtkFileFilter* filter, const gchar* mimeType) +{ + GtkFileFilterInfo filterInfo; + filterInfo.contains = GTK_FILE_FILTER_MIME_TYPE; + filterInfo.mime_type = mimeType; + return gtk_file_filter_filter(filter, &filterInfo); +} + +class ModalDialogsTest: public UIClientTest { +public: + MAKE_GLIB_TEST_FIXTURE(ModalDialogsTest); + + static void dialogRunAsModalCallback(WebKitWebView* webView, ModalDialogsTest* test) + { + g_assert(webView != test->m_webView); + test->m_webViewEvents.append(RunAsModal); + } + + GtkWidget* viewCreate(WebKitWebView* webView, WebKitNavigationAction* navigation) + { + g_assert(webView == m_webView); + + GtkWidget* newWebView = UIClientTest::viewCreate(webView, navigation); + g_signal_connect(newWebView, "run-as-modal", G_CALLBACK(dialogRunAsModalCallback), this); + return newWebView; + } + + void viewReadyToShow(WebKitWebView* webView) + { + g_assert(webView != m_webView); + m_webViewEvents.append(ReadyToShow); + } +}; + +static void testWebViewAllowModalDialogs(ModalDialogsTest* test, gconstpointer) +{ + WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView); + webkit_settings_set_allow_modal_dialogs(settings, TRUE); + + test->loadHtml("<html><body onload=\"window.showModalDialog('data:text/html,<html><body/><script>window.close();</script></html>')\"></body></html>", 0); + test->waitUntilMainLoopFinishes(); + + Vector<UIClientTest::WebViewEvents>& events = test->m_webViewEvents; + g_assert_cmpint(events.size(), ==, 4); + g_assert_cmpint(events[0], ==, UIClientTest::Create); + g_assert_cmpint(events[1], ==, UIClientTest::ReadyToShow); + g_assert_cmpint(events[2], ==, UIClientTest::RunAsModal); + g_assert_cmpint(events[3], ==, UIClientTest::Close); +} + +static void testWebViewDisallowModalDialogs(ModalDialogsTest* test, gconstpointer) +{ + WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView); + webkit_settings_set_allow_modal_dialogs(settings, FALSE); + + test->loadHtml("<html><body onload=\"window.showModalDialog('data:text/html,<html><body/><script>window.close();</script></html>')\"></body></html>", 0); + // We need to use a timeout here because the viewClose() function + // won't ever be called as the dialog won't be created. + test->wait(1); + + Vector<UIClientTest::WebViewEvents>& events = test->m_webViewEvents; + g_assert_cmpint(events.size(), ==, 0); +} + +static void testWebViewJavaScriptDialogs(UIClientTest* test, gconstpointer) +{ + static const char* htmlOnLoadFormat = "<html><body onLoad=\"%s\"></body></html>"; + static const char* jsAlertFormat = "alert('%s')"; + static const char* jsConfirmFormat = "do { confirmed = confirm('%s'); } while (!confirmed); alert('confirmed');"; + static const char* jsPromptFormat = "alert(prompt('%s', 'default'));"; + static const char* htmlOnBeforeUnloadFormat = + "<html><body onbeforeunload=\"return beforeUnloadHandler();\"><script>function beforeUnloadHandler() { return \"%s\"; }</script></body></html>"; + + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_ALERT; + GUniquePtr<char> alertDialogMessage(g_strdup_printf(jsAlertFormat, kAlertDialogMessage)); + GUniquePtr<char> alertHTML(g_strdup_printf(htmlOnLoadFormat, alertDialogMessage.get())); + test->loadHtml(alertHTML.get(), 0); + test->waitUntilMainLoopFinishes(); + webkit_web_view_stop_loading(test->m_webView); + test->waitUntilLoadFinished(); + + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_CONFIRM; + GUniquePtr<char> confirmDialogMessage(g_strdup_printf(jsConfirmFormat, kConfirmDialogMessage)); + GUniquePtr<char> confirmHTML(g_strdup_printf(htmlOnLoadFormat, confirmDialogMessage.get())); + test->loadHtml(confirmHTML.get(), 0); + test->waitUntilMainLoopFinishes(); + webkit_web_view_stop_loading(test->m_webView); + test->waitUntilLoadFinished(); + + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_PROMPT; + GUniquePtr<char> promptDialogMessage(g_strdup_printf(jsPromptFormat, kPromptDialogMessage)); + GUniquePtr<char> promptHTML(g_strdup_printf(htmlOnLoadFormat, promptDialogMessage.get())); + test->loadHtml(promptHTML.get(), 0); + test->waitUntilMainLoopFinishes(); + webkit_web_view_stop_loading(test->m_webView); + test->waitUntilLoadFinished(); + + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM; + GUniquePtr<char> beforeUnloadDialogHTML(g_strdup_printf(htmlOnBeforeUnloadFormat, kBeforeUnloadConfirmDialogMessage)); + test->loadHtml(beforeUnloadDialogHTML.get(), nullptr); + test->waitUntilLoadFinished(); + + // Reload should trigger onbeforeunload. +#if 0 + // FIXME: reloading HTML data doesn't emit finished load event. + // See https://bugs.webkit.org/show_bug.cgi?id=139089. + test->m_scriptDialogConfirmed = false; + webkit_web_view_reload(test->m_webView); + test->waitUntilLoadFinished(); + g_assert(test->m_scriptDialogConfirmed); +#endif + + // Navigation should trigger onbeforeunload. + test->m_scriptDialogConfirmed = false; + test->loadHtml("<html></html>", nullptr); + test->waitUntilLoadFinished(); + g_assert(test->m_scriptDialogConfirmed); + + // Try close should trigger onbeforeunload. + test->m_scriptDialogConfirmed = false; + test->loadHtml(beforeUnloadDialogHTML.get(), nullptr); + test->waitUntilLoadFinished(); + test->tryCloseAndWaitUntilClosed(); + g_assert(test->m_scriptDialogConfirmed); + + // Try close on a page with no unload handlers should not trigger onbeforeunload, + // but should actually close the page. + test->m_scriptDialogConfirmed = false; + test->loadHtml("<html><body></body></html>", nullptr); + test->waitUntilLoadFinished(); + // We got a onbeforeunload of the previous page. + g_assert(test->m_scriptDialogConfirmed); + test->m_scriptDialogConfirmed = false; + test->tryCloseAndWaitUntilClosed(); + g_assert(!test->m_scriptDialogConfirmed); +} + +static void testWebViewWindowProperties(UIClientTest* test, gconstpointer) +{ + static const char* windowProrpertiesString = "left=100,top=150,width=400,height=400,location=no,menubar=no,status=no,toolbar=no,scrollbars=no"; + GdkRectangle geometry = { 100, 150, 400, 400 }; + test->setExpectedWindowProperties(UIClientTest::WindowProperties(&geometry, false, false, false, false, false, true, false)); + + GUniquePtr<char> htmlString(g_strdup_printf("<html><body onLoad=\"window.open('', '', '%s').close();\"></body></html>", windowProrpertiesString)); + test->loadHtml(htmlString.get(), 0); + test->waitUntilMainLoopFinishes(); + + static const char* propertiesChanged[] = { + "geometry", "locationbar-visible", "menubar-visible", "statusbar-visible", "toolbar-visible", "scrollbars-visible" + }; + for (size_t i = 0; i < G_N_ELEMENTS(propertiesChanged); ++i) + g_assert(test->m_windowPropertiesChanged.contains(propertiesChanged[i])); + + Vector<UIClientTest::WebViewEvents>& events = test->m_webViewEvents; + g_assert_cmpint(events.size(), ==, 3); + g_assert_cmpint(events[0], ==, UIClientTest::Create); + g_assert_cmpint(events[1], ==, UIClientTest::ReadyToShow); + g_assert_cmpint(events[2], ==, UIClientTest::Close); +} + +static void testWebViewMouseTarget(UIClientTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + + const char* linksHoveredHTML = + "<html><head>" + " <script>" + " window.onload = function () {" + " window.getSelection().removeAllRanges();" + " var select_range = document.createRange();" + " select_range.selectNodeContents(document.getElementById('text_to_select'));" + " window.getSelection().addRange(select_range);" + " }" + " </script>" + "</head><body>" + " <a style='position:absolute; left:1; top:1' href='http://www.webkitgtk.org' title='WebKitGTK+ Title'>WebKitGTK+ Website</a>" + " <img style='position:absolute; left:1; top:10' src='0xdeadbeef' width=5 height=5></img>" + " <a style='position:absolute; left:1; top:20' href='http://www.webkitgtk.org/logo' title='WebKitGTK+ Logo'><img src='0xdeadbeef' width=5 height=5></img></a>" + " <input style='position:absolute; left:1; top:30' size='10'></input>" + " <video style='position:absolute; left:1; top:100' width='300' height='300' controls='controls' preload='none'><source src='movie.ogg' type='video/ogg' /></video>" + " <p style='position:absolute; left:1; top:120' id='text_to_select'>Lorem ipsum.</p>" + "</body></html>"; + + test->loadHtml(linksHoveredHTML, "file:///"); + test->waitUntilLoadFinished(); + + // Move over link. + WebKitHitTestResult* hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(1, 1); + g_assert(webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + g_assert_cmpstr(webkit_hit_test_result_get_link_uri(hitTestResult), ==, "http://www.webkitgtk.org/"); + g_assert_cmpstr(webkit_hit_test_result_get_link_title(hitTestResult), ==, "WebKitGTK+ Title"); + g_assert_cmpstr(webkit_hit_test_result_get_link_label(hitTestResult), ==, "WebKitGTK+ Website"); + g_assert(!test->m_mouseTargetModifiers); + + // Move out of the link. + hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(0, 0); + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + g_assert(!test->m_mouseTargetModifiers); + + // Move over image with GDK_CONTROL_MASK. + hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(1, 10, GDK_CONTROL_MASK); + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult)); + g_assert_cmpstr(webkit_hit_test_result_get_image_uri(hitTestResult), ==, "file:///0xdeadbeef"); + g_assert(test->m_mouseTargetModifiers & GDK_CONTROL_MASK); + + // Move over image link. + hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(1, 20); + g_assert(webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + g_assert_cmpstr(webkit_hit_test_result_get_link_uri(hitTestResult), ==, "http://www.webkitgtk.org/logo"); + g_assert_cmpstr(webkit_hit_test_result_get_image_uri(hitTestResult), ==, "file:///0xdeadbeef"); + g_assert_cmpstr(webkit_hit_test_result_get_link_title(hitTestResult), ==, "WebKitGTK+ Logo"); + g_assert(!webkit_hit_test_result_get_link_label(hitTestResult)); + g_assert(!test->m_mouseTargetModifiers); + + // Move over media. + hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(1, 100); + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + g_assert_cmpstr(webkit_hit_test_result_get_media_uri(hitTestResult), ==, "file:///movie.ogg"); + g_assert(!test->m_mouseTargetModifiers); + + // Mover over input. + hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(5, 35); + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + g_assert(!test->m_mouseTargetModifiers); + + // Move over scrollbar. + hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(gtk_widget_get_allocated_width(GTK_WIDGET(test->m_webView)) - 4, 5); + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_scrollbar(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult)); + g_assert(!test->m_mouseTargetModifiers); + + // Move over selection. + hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(2, 145); + g_assert(!webkit_hit_test_result_context_is_link(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_image(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_media(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult)); + g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult)); + g_assert(webkit_hit_test_result_context_is_selection(hitTestResult)); + g_assert(!test->m_mouseTargetModifiers); + +} + +static void testWebViewGeolocationPermissionRequests(UIClientTest* test, gconstpointer) +{ + // Some versions of geoclue give a runtime warning because it tries + // to register the error quark twice. See https://bugs.webkit.org/show_bug.cgi?id=89858. + // Make warnings non-fatal for this test to make it pass. + test->removeLogFatalFlag(G_LOG_LEVEL_WARNING); + test->showInWindowAndWaitUntilMapped(); + static const char* geolocationRequestHTML = + "<html>" + " <script>" + " function runTest()" + " {" + " navigator.geolocation.getCurrentPosition(function(p) { document.title = \"OK\" }," + " function(e) { document.title = e.code });" + " }" + " </script>" + " <body onload='runTest();'></body>" + "</html>"; + + // Test denying a permission request. + test->m_allowPermissionRequests = false; + test->loadHtml(geolocationRequestHTML, "http://foo.com/bar"); + test->waitUntilTitleChanged(); + + // According to the Geolocation API specification, '1' is the + // error code returned for the PERMISSION_DENIED error. + // http://dev.w3.org/geo/api/spec-source.html#position_error_interface + const gchar* result = webkit_web_view_get_title(test->m_webView); + g_assert_cmpstr(result, ==, "1"); + + // Test allowing a permission request. + test->m_allowPermissionRequests = true; + test->loadHtml(geolocationRequestHTML, 0); + test->waitUntilTitleChanged(); + + // Check that we did not get the PERMISSION_DENIED error now. + result = webkit_web_view_get_title(test->m_webView); + g_assert_cmpstr(result, !=, "1"); + test->addLogFatalFlag(G_LOG_LEVEL_WARNING); +} + +#if ENABLE(MEDIA_STREAM) +static void testWebViewUserMediaPermissionRequests(UIClientTest* test, gconstpointer) +{ + WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView); + gboolean enabled = webkit_settings_get_enable_media_stream(settings); + webkit_settings_set_enable_media_stream(settings, TRUE); + + test->showInWindowAndWaitUntilMapped(); + static const char* userMediaRequestHTML = + "<html>" + " <script>" + " function runTest()" + " {" + " navigator.webkitGetUserMedia({audio: true, video: true}," + " function(s) { document.title = \"OK\" }," + " function(e) { document.title = e.name });" + " }" + " </script>" + " <body onload='runTest();'></body>" + "</html>"; + + test->m_verifyMediaTypes = TRUE; + test->m_expectedAudioMedia = TRUE; + test->m_expectedVideoMedia = TRUE; + + // Test denying a permission request. + test->m_allowPermissionRequests = false; + test->loadHtml(userMediaRequestHTML, nullptr); + test->waitUntilTitleChangedTo("PermissionDeniedError"); + + // Test allowing a permission request. + test->m_allowPermissionRequests = true; + test->loadHtml(userMediaRequestHTML, nullptr); + test->waitUntilTitleChangedTo("OK"); + + webkit_settings_set_enable_media_stream(settings, enabled); +} + +static void testWebViewAudioOnlyUserMediaPermissionRequests(UIClientTest* test, gconstpointer) +{ + WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView); + gboolean enabled = webkit_settings_get_enable_media_stream(settings); + webkit_settings_set_enable_media_stream(settings, TRUE); + + test->showInWindowAndWaitUntilMapped(); + static const char* userMediaRequestHTML = + "<html>" + " <script>" + " function runTest()" + " {" + " navigator.webkitGetUserMedia({audio: true, video: false}," + " function(s) { document.title = \"OK\" }," + " function(e) { document.title = e.name });" + " }" + " </script>" + " <body onload='runTest();'></body>" + "</html>"; + + test->m_verifyMediaTypes = TRUE; + test->m_expectedAudioMedia = TRUE; + test->m_expectedVideoMedia = FALSE; + + // Test denying a permission request. + test->m_allowPermissionRequests = false; + test->loadHtml(userMediaRequestHTML, nullptr); + test->waitUntilTitleChangedTo("PermissionDeniedError"); + + webkit_settings_set_enable_media_stream(settings, enabled); +} +#endif // ENABLE(MEDIA_STREAM) + +class FileChooserTest: public UIClientTest { +public: + MAKE_GLIB_TEST_FIXTURE(FileChooserTest); + + FileChooserTest() + { + g_signal_connect(m_webView, "run-file-chooser", G_CALLBACK(runFileChooserCallback), this); + } + + static gboolean runFileChooserCallback(WebKitWebView*, WebKitFileChooserRequest* request, FileChooserTest* test) + { + test->runFileChooser(request); + return TRUE; + } + + void runFileChooser(WebKitFileChooserRequest* request) + { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + m_fileChooserRequest = request; + g_main_loop_quit(m_mainLoop); + } + + WebKitFileChooserRequest* clickMouseButtonAndWaitForFileChooserRequest(int x, int y) + { + clickMouseButton(x, y); + g_main_loop_run(m_mainLoop); + return m_fileChooserRequest.get(); + } + +private: + GRefPtr<WebKitFileChooserRequest> m_fileChooserRequest; +}; + +static void testWebViewFileChooserRequest(FileChooserTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + static const char* fileChooserHTMLFormat = "<html><body><input style='position:absolute;left:0;top:0;margin:0;padding:0' type='file' %s/></body></html>"; + + // Multiple selections not allowed, no MIME filtering. + GUniquePtr<char> simpleFileUploadHTML(g_strdup_printf(fileChooserHTMLFormat, "")); + test->loadHtml(simpleFileUploadHTML.get(), 0); + test->waitUntilLoadFinished(); + WebKitFileChooserRequest* fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5); + g_assert(!webkit_file_chooser_request_get_select_multiple(fileChooserRequest)); + + const gchar* const* mimeTypes = webkit_file_chooser_request_get_mime_types(fileChooserRequest); + g_assert(!mimeTypes); + GtkFileFilter* filter = webkit_file_chooser_request_get_mime_types_filter(fileChooserRequest); + g_assert(!filter); + const gchar* const* selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest); + g_assert(!selectedFiles); + webkit_file_chooser_request_cancel(fileChooserRequest); + + // Multiple selections allowed, no MIME filtering, some pre-selected files. + GUniquePtr<char> multipleSelectionFileUploadHTML(g_strdup_printf(fileChooserHTMLFormat, "multiple")); + test->loadHtml(multipleSelectionFileUploadHTML.get(), 0); + test->waitUntilLoadFinished(); + fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5); + g_assert(webkit_file_chooser_request_get_select_multiple(fileChooserRequest)); + + mimeTypes = webkit_file_chooser_request_get_mime_types(fileChooserRequest); + g_assert(!mimeTypes); + filter = webkit_file_chooser_request_get_mime_types_filter(fileChooserRequest); + g_assert(!filter); + selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest); + g_assert(!selectedFiles); + + // Select some files. + const gchar* filesToSelect[4] = { "/foo", "/foo/bar", "/foo/bar/baz", 0 }; + webkit_file_chooser_request_select_files(fileChooserRequest, filesToSelect); + + // Check the files that have been just selected. + selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest); + g_assert(selectedFiles); + g_assert_cmpstr(selectedFiles[0], ==, "/foo"); + g_assert_cmpstr(selectedFiles[1], ==, "/foo/bar"); + g_assert_cmpstr(selectedFiles[2], ==, "/foo/bar/baz"); + g_assert(!selectedFiles[3]); + + // Perform another request to check if the list of files selected + // in the previous step appears now as part of the new request. + fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5); + selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest); + g_assert(selectedFiles); + g_assert_cmpstr(selectedFiles[0], ==, "/foo"); + g_assert_cmpstr(selectedFiles[1], ==, "/foo/bar"); + g_assert_cmpstr(selectedFiles[2], ==, "/foo/bar/baz"); + g_assert(!selectedFiles[3]); + webkit_file_chooser_request_cancel(fileChooserRequest); + + // Multiple selections not allowed, only accept images, audio and video files.. + GUniquePtr<char> mimeFilteredFileUploadHTML(g_strdup_printf(fileChooserHTMLFormat, "accept='audio/*,video/*,image/*'")); + test->loadHtml(mimeFilteredFileUploadHTML.get(), 0); + test->waitUntilLoadFinished(); + fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5); + g_assert(!webkit_file_chooser_request_get_select_multiple(fileChooserRequest)); + + mimeTypes = webkit_file_chooser_request_get_mime_types(fileChooserRequest); + g_assert(mimeTypes); + g_assert_cmpstr(mimeTypes[0], ==, "audio/*"); + g_assert_cmpstr(mimeTypes[1], ==, "video/*"); + g_assert_cmpstr(mimeTypes[2], ==, "image/*"); + g_assert(!mimeTypes[3]); + + filter = webkit_file_chooser_request_get_mime_types_filter(fileChooserRequest); + g_assert(GTK_IS_FILE_FILTER(filter)); + g_assert(checkMimeTypeForFilter(filter, "audio/*")); + g_assert(checkMimeTypeForFilter(filter, "video/*")); + g_assert(checkMimeTypeForFilter(filter, "image/*")); + + selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest); + g_assert(!selectedFiles); + webkit_file_chooser_request_cancel(fileChooserRequest); +} + +class ColorChooserTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(ColorChooserTest); + + static gboolean runColorChooserCallback(WebKitWebView*, WebKitColorChooserRequest* request, ColorChooserTest* test) + { + test->runColorChooser(request); + return TRUE; + } + + static void requestFinishedCallback(WebKitColorChooserRequest* request, ColorChooserTest* test) + { + g_assert(test->m_request.get() == request); + test->m_request = nullptr; + if (g_main_loop_is_running(test->m_mainLoop)) + g_main_loop_quit(test->m_mainLoop); + } + + ColorChooserTest() + { + g_signal_connect(m_webView, "run-color-chooser", G_CALLBACK(runColorChooserCallback), this); + } + + void runColorChooser(WebKitColorChooserRequest* request) + { + g_assert(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + m_request = request; + g_signal_connect(request, "finished", G_CALLBACK(requestFinishedCallback), this); + g_main_loop_quit(m_mainLoop); + } + + void finishRequest() + { + g_assert(m_request.get()); + webkit_color_chooser_request_finish(m_request.get()); + g_assert(!m_request); + } + + void cancelRequest() + { + g_assert(m_request.get()); + webkit_color_chooser_request_cancel(m_request.get()); + g_assert(!m_request); + } + + WebKitColorChooserRequest* clickMouseButtonAndWaitForColorChooserRequest(int x, int y) + { + clickMouseButton(x, y); + g_main_loop_run(m_mainLoop); + g_assert(m_request.get()); + return m_request.get(); + } + +private: + GRefPtr<WebKitColorChooserRequest> m_request; +}; + +static void testWebViewColorChooserRequest(ColorChooserTest* test, gconstpointer) +{ + static const char* colorChooserHTMLFormat = "<html><body><input style='position:absolute;left:1;top:1;margin:0;padding:0;width:45;height:25' type='color' %s/></body></html>"; + test->showInWindowAndWaitUntilMapped(); + + GUniquePtr<char> defaultColorHTML(g_strdup_printf(colorChooserHTMLFormat, "")); + test->loadHtml(defaultColorHTML.get(), nullptr); + test->waitUntilLoadFinished(); + WebKitColorChooserRequest* request = test->clickMouseButtonAndWaitForColorChooserRequest(5, 5); + + // Default color is black (#000000). + GdkRGBA rgba1; + GdkRGBA rgba2 = { 0., 0., 0., 1. }; + webkit_color_chooser_request_get_rgba(request, &rgba1); + g_assert(gdk_rgba_equal(&rgba1, &rgba2)); + + // Set a different color. + rgba2.green = 1; + webkit_color_chooser_request_set_rgba(request, &rgba2); + webkit_color_chooser_request_get_rgba(request, &rgba1); + g_assert(gdk_rgba_equal(&rgba1, &rgba2)); + + GdkRectangle rect; + webkit_color_chooser_request_get_element_rectangle(request, &rect); + g_assert_cmpint(rect.x, == , 1); + g_assert_cmpint(rect.y, == , 1); + g_assert_cmpint(rect.width, == , 45); + g_assert_cmpint(rect.height, == , 25); + + test->finishRequest(); + + // Use an initial color. + GUniquePtr<char> initialColorHTML(g_strdup_printf(colorChooserHTMLFormat, "value='#FF00FF'")); + test->loadHtml(initialColorHTML.get(), nullptr); + test->waitUntilLoadFinished(); + request = test->clickMouseButtonAndWaitForColorChooserRequest(5, 5); + + webkit_color_chooser_request_get_rgba(request, &rgba1); + GdkRGBA rgba3 = { 1., 0., 1., 1. }; + g_assert(gdk_rgba_equal(&rgba1, &rgba3)); + + test->cancelRequest(); +} + +void beforeAll() +{ + UIClientTest::add("WebKitWebView", "create-ready-close", testWebViewCreateReadyClose); + CreateNavigationDataTest::add("WebKitWebView", "create-navigation-data", testWebViewCreateNavigationData); + ModalDialogsTest::add("WebKitWebView", "allow-modal-dialogs", testWebViewAllowModalDialogs); + ModalDialogsTest::add("WebKitWebView", "disallow-modal-dialogs", testWebViewDisallowModalDialogs); + UIClientTest::add("WebKitWebView", "javascript-dialogs", testWebViewJavaScriptDialogs); + UIClientTest::add("WebKitWebView", "window-properties", testWebViewWindowProperties); + UIClientTest::add("WebKitWebView", "mouse-target", testWebViewMouseTarget); + UIClientTest::add("WebKitWebView", "geolocation-permission-requests", testWebViewGeolocationPermissionRequests); +#if ENABLE(MEDIA_STREAM) + UIClientTest::add("WebKitWebView", "usermedia-permission-requests", testWebViewUserMediaPermissionRequests); + UIClientTest::add("WebKitWebView", "audio-usermedia-permission-request", testWebViewAudioOnlyUserMediaPermissionRequests); +#endif + FileChooserTest::add("WebKitWebView", "file-chooser-request", testWebViewFileChooserRequest); + ColorChooserTest::add("WebKitWebView", "color-chooser-request", testWebViewColorChooserRequest); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebExtensions.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebExtensions.cpp new file mode 100644 index 000000000..b41e5eb82 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebExtensions.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebKitTestBus.h" +#include "WebViewTest.h" +#include <wtf/glib/GRefPtr.h> + +static const char* webExtensionsUserData = "Web Extensions user data"; +static WebKitTestBus* bus; +static GUniquePtr<char> scriptDialogResult; + +static void testWebExtensionGetTitle(WebViewTest* test, gconstpointer) +{ + test->loadHtml("<html><head><title>WebKitGTK+ Web Extensions Test</title></head><body></body></html>", 0); + test->waitUntilLoadFinished(); + + GUniquePtr<char> extensionBusName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", Test::s_webExtensionID)); + GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy(extensionBusName.get(), + "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", test->m_mainLoop)); + GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync( + proxy.get(), + "GetTitle", + g_variant_new("(t)", webkit_web_view_get_page_id(test->m_webView)), + G_DBUS_CALL_FLAGS_NONE, + -1, 0, 0)); + g_assert(result); + + const char* title; + g_variant_get(result.get(), "(&s)", &title); + g_assert_cmpstr(title, ==, "WebKitGTK+ Web Extensions Test"); +} + +static void documentLoadedCallback(GDBusConnection*, const char*, const char*, const char*, const char*, GVariant*, WebViewTest* test) +{ + g_main_loop_quit(test->m_mainLoop); +} + +static void testDocumentLoadedSignal(WebViewTest* test, gconstpointer) +{ + GUniquePtr<char> extensionBusName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", Test::s_webExtensionID)); + GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy(extensionBusName.get(), + "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", test->m_mainLoop)); + GDBusConnection* connection = g_dbus_proxy_get_connection(proxy.get()); + guint id = g_dbus_connection_signal_subscribe(connection, + 0, + "org.webkit.gtk.WebExtensionTest", + "DocumentLoaded", + "/org/webkit/gtk/WebExtensionTest", + 0, + G_DBUS_SIGNAL_FLAGS_NONE, + reinterpret_cast<GDBusSignalCallback>(documentLoadedCallback), + test, + 0); + g_assert(id); + + test->loadHtml("<html><head><title>WebKitGTK+ Web Extensions Test</title></head><body></body></html>", 0); + g_main_loop_run(test->m_mainLoop); + g_dbus_connection_signal_unsubscribe(connection, id); +} + +static gboolean webProcessCrashedCallback(WebKitWebView*, WebViewTest* test) +{ + test->quitMainLoop(); + + return FALSE; +} + +static void testWebKitWebViewProcessCrashed(WebViewTest* test, gconstpointer) +{ + test->loadHtml("<html></html>", 0); + test->waitUntilLoadFinished(); + + g_signal_connect_after(test->m_webView, "web-process-crashed", + G_CALLBACK(webProcessCrashedCallback), test); + + test->m_expectedWebProcessCrash = true; + + GUniquePtr<char> extensionBusName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", Test::s_webExtensionID)); + GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy(extensionBusName.get(), + "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", test->m_mainLoop)); + + GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync( + proxy.get(), + "AbortProcess", + 0, + G_DBUS_CALL_FLAGS_NONE, + -1, 0, 0)); + g_assert(!result); + g_main_loop_run(test->m_mainLoop); + test->m_expectedWebProcessCrash = false; +} + +static void testWebExtensionWindowObjectCleared(WebViewTest* test, gconstpointer) +{ + test->loadHtml("<html><header></header><body></body></html>", 0); + test->waitUntilLoadFinished(); + + GUniqueOutPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.echo('Foo');", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "Foo"); +} + +static gboolean scriptDialogCallback(WebKitWebView*, WebKitScriptDialog* dialog, gpointer) +{ + g_assert_cmpuint(webkit_script_dialog_get_dialog_type(dialog), ==, WEBKIT_SCRIPT_DIALOG_ALERT); + scriptDialogResult.reset(g_strdup(webkit_script_dialog_get_message(dialog))); + return TRUE; +} + +static void runJavaScriptInIsolatedWorldFinishedCallback(GDBusProxy* proxy, GAsyncResult* result, WebViewTest* test) +{ + g_dbus_proxy_call_finish(proxy, result, 0); + g_main_loop_quit(test->m_mainLoop); +} + +static void testWebExtensionIsolatedWorld(WebViewTest* test, gconstpointer) +{ + test->loadHtml("<html><header></header><body><div id='console'></div></body></html>", 0); + test->waitUntilLoadFinished(); + + gulong scriptDialogID = g_signal_connect(test->m_webView, "script-dialog", G_CALLBACK(scriptDialogCallback), nullptr); + + static const char* mainWorldScript = + "top.foo = 'Foo';\n" + "document.getElementById('console').innerHTML = top.foo;\n" + "window.open = function () { alert('Main World'); }\n" + "document.open(1, 2, 3);"; + test->runJavaScriptAndWaitUntilFinished(mainWorldScript, 0); + g_assert_cmpstr(scriptDialogResult.get(), ==, "Main World"); + + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementById('console').innerHTML", 0); + g_assert(javascriptResult); + GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "Foo"); + + static const char* isolatedWorldScript = + "document.getElementById('console').innerHTML = top.foo;\n" + "window.open = function () { alert('Isolated World'); }\n" + "document.open(1, 2, 3);"; + GUniquePtr<char> extensionBusName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", Test::s_webExtensionID)); + GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy(extensionBusName.get(), + "/org/webkit/gtk/WebExtensionTest" , "org.webkit.gtk.WebExtensionTest", test->m_mainLoop)); + g_dbus_proxy_call(proxy.get(), + "RunJavaScriptInIsolatedWorld", + g_variant_new("(t&s)", webkit_web_view_get_page_id(test->m_webView), isolatedWorldScript), + G_DBUS_CALL_FLAGS_NONE, + -1, 0, + reinterpret_cast<GAsyncReadyCallback>(runJavaScriptInIsolatedWorldFinishedCallback), + test); + g_main_loop_run(test->m_mainLoop); + g_assert_cmpstr(scriptDialogResult.get(), ==, "Isolated World"); + + // Check that 'top.foo' defined in main world is not visible in isolated world. + javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementById('console').innerHTML", 0); + g_assert(javascriptResult); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "undefined"); + + g_signal_handler_disconnect(test->m_webView, scriptDialogID); +} + +static gboolean permissionRequestCallback(WebKitWebView*, WebKitPermissionRequest* request, WebViewTest* test) +{ + if (!WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)) + return FALSE; + + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + WebKitInstallMissingMediaPluginsPermissionRequest* missingPluginsRequest = WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request); + g_assert(webkit_install_missing_media_plugins_permission_request_get_description(missingPluginsRequest)); + webkit_permission_request_deny(request); + test->quitMainLoop(); + + return TRUE; +} + +static void testInstallMissingPluginsPermissionRequest(WebViewTest* test, gconstpointer) +{ + GUniquePtr<char> extensionBusName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", Test::s_webExtensionID)); + GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy(extensionBusName.get(), + "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", test->m_mainLoop)); + GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(proxy.get(), "RemoveAVPluginsFromGSTRegistry", + nullptr, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, nullptr)); + + test->showInWindowAndWaitUntilMapped(); + + gulong permissionRequestSignalID = g_signal_connect(test->m_webView, "permission-request", G_CALLBACK(permissionRequestCallback), test); + // FIXME: the base URI needs to finish with / to work, that shouldn't happen. + GUniquePtr<char> baseURI(g_strconcat("file://", Test::getResourcesDir(Test::WebKit2Resources).data(), "/", nullptr)); + test->loadHtml("<html><body><video src=\"test.mp4\" autoplay></video></body></html>", baseURI.get()); + g_main_loop_run(test->m_mainLoop); + g_signal_handler_disconnect(test->m_webView, permissionRequestSignalID); +} + +void beforeAll() +{ + bus = new WebKitTestBus(); + if (!bus->run()) + return; + + WebViewTest::add("WebKitWebExtension", "dom-document-title", testWebExtensionGetTitle); + WebViewTest::add("WebKitWebExtension", "document-loaded-signal", testDocumentLoadedSignal); + WebViewTest::add("WebKitWebView", "web-process-crashed", testWebKitWebViewProcessCrashed); + WebViewTest::add("WebKitWebExtension", "window-object-cleared", testWebExtensionWindowObjectCleared); + WebViewTest::add("WebKitWebExtension", "isolated-world", testWebExtensionIsolatedWorld); + WebViewTest::add("WebKitWebView", "install-missing-plugins-permission-request", testInstallMissingPluginsPermissionRequest); +} + +void afterAll() +{ + delete bus; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitAccessibility.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitAccessibility.cpp new file mode 100644 index 000000000..ea4a8125f --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitAccessibility.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "TestMain.h" +#include "WebViewTest.h" + +// The libatspi headers don't use G_BEGIN_DECLS +extern "C" { +#include <atspi/atspi.h> +} + +#include <errno.h> +#include <fcntl.h> +#include <glib.h> +#include <signal.h> +#include <unistd.h> +#include <wtf/PassRefPtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> + +// Name of the test server application creating the webView object. +static const char* kTestServerAppName = "AccessibilityTestServer"; + +// Max seconds to wait for the test server before inspecting it. +static const int kMaxWaitForChild = 5; + +// The PID for the test server running, so we can kill it if needed. +static GPid kChildProcessPid = 0; + +// Whether the child has replied and it's ready. +static bool kChildIsReady = false; + +static void stopTestServer() +{ + // Do nothing if there's no server running. + if (!kChildProcessPid) + return; + + g_spawn_close_pid(kChildProcessPid); + kill(kChildProcessPid, SIGTERM); + kChildProcessPid = 0; +} + +static void sigAbortHandler(int sigNum) +{ + // Just stop the test server if SIGABRT was received. + stopTestServer(); +} + +static gpointer testServerMonitorThreadFunc(gpointer) +{ + // Wait for the specified timeout to happen. + g_usleep(kMaxWaitForChild * G_USEC_PER_SEC); + + // Kill the child process if not ready yet. + if (!kChildIsReady) + stopTestServer(); + + g_thread_exit(0); + return 0; +} + +static void startTestServerMonitor() +{ + kChildIsReady = false; + g_thread_new("TestServerMonitor", testServerMonitorThreadFunc, 0); +} + +static void startTestServer() +{ + // Prepare argv[] for spawning the server process. + GUniquePtr<char> testServerPath(g_build_filename(WEBKIT_EXEC_PATH, "TestWebKitAPI", "WebKit2Gtk", kTestServerAppName, nullptr)); + + char* testServerArgv[2]; + testServerArgv[0] = testServerPath.get(); + testServerArgv[1] = 0; + + // Spawn the server, getting its stdout file descriptor to set a + // communication channel, so we know when it's ready. + int childStdout = 0; + if (!g_spawn_async_with_pipes(0, testServerArgv, 0, static_cast<GSpawnFlags>(0), 0, 0, &kChildProcessPid, 0, &childStdout, 0, 0)) { + close(childStdout); + return; + } + + // Start monitoring the test server (in a separate thread) to + // ensure we don't block on the child process more than a timeout. + startTestServerMonitor(); + + char msg[2]; + GIOChannel* ioChannel = g_io_channel_unix_new(childStdout); + if (g_io_channel_read_chars(ioChannel, msg, 2, 0, 0) == G_IO_STATUS_NORMAL) { + // Check whether the server sent a message saying it's ready + // and store the result globally, so the monitor can see it. + kChildIsReady = msg[0] == 'O' && msg[1] == 'K'; + } + g_io_channel_unref(ioChannel); + close(childStdout); + + // The timeout was reached and the server is not ready yet, so + // stop it inmediately, and let the unit tests fail. + if (!kChildIsReady) + stopTestServer(); +} + +static void checkAtspiAccessible(AtspiAccessible* accessible, const char* targetName, AtspiRole targetRole) +{ + g_assert(ATSPI_IS_ACCESSIBLE(accessible)); + + GUniquePtr<char> name(atspi_accessible_get_name(accessible, 0)); + g_assert_cmpstr(targetName, ==, name.get()); + g_assert_cmpint(targetRole, ==, atspi_accessible_get_role(accessible, 0)); +} + +static GRefPtr<AtspiAccessible> findTestServerApplication() +{ + // Only one desktop is supported by ATSPI at the moment. + GRefPtr<AtspiAccessible> desktop = adoptGRef(atspi_get_desktop(0)); + + // Look for the server application in the list of apps. + GRefPtr<AtspiAccessible> current; + int childCount = atspi_accessible_get_child_count(desktop.get(), 0); + for (int i = 0; i < childCount; i++) { + current = adoptGRef(atspi_accessible_get_child_at_index(desktop.get(), i, 0)); + if (!g_strcmp0(atspi_accessible_get_name(current.get(), 0), kTestServerAppName)) + return current; + } + + return 0; +} + +static void testAtspiBasicHierarchy(WebViewTest* test, gconstpointer) +{ + // The test server's accessibility object (UI Process). + GRefPtr<AtspiAccessible> testServerApp = findTestServerApplication(); + g_assert(ATSPI_IS_ACCESSIBLE(testServerApp.get())); + checkAtspiAccessible(testServerApp.get(), "AccessibilityTestServer", ATSPI_ROLE_APPLICATION); + + // The main window's accessibility object (UI Process). + GRefPtr<AtspiAccessible> currentParent = testServerApp; + GRefPtr<AtspiAccessible> currentChild = adoptGRef(atspi_accessible_get_child_at_index(currentParent.get(), 0, 0)); + g_assert(ATSPI_IS_ACCESSIBLE(currentChild.get())); + checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_FRAME); + + // The WebView's accessibility object (UI Process). + currentParent = currentChild; + currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); + g_assert(ATSPI_IS_ACCESSIBLE(currentChild.get())); + checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_FILLER); + + // The WebPage's accessibility object (Web Process). + currentParent = currentChild; + currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); + g_assert(ATSPI_IS_ACCESSIBLE(currentChild.get())); + checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_FILLER); + + // HTML root element's accessible element (Web Process). + currentParent = currentChild; + currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); + g_assert(ATSPI_IS_ACCESSIBLE(currentChild.get())); + + // HTML body's accessible element (Web Process). + currentParent = currentChild; + currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); + g_assert(ATSPI_IS_ACCESSIBLE(currentChild.get())); + checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_DOCUMENT_WEB); + + // HTML H1's accessible element (Web Process). + currentParent = currentChild; + currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); + g_assert(ATSPI_IS_ACCESSIBLE(currentChild.get())); + checkAtspiAccessible(currentChild.get(), "This is a test", ATSPI_ROLE_HEADING); + + // HTML first paragraph's accessible element (Web Process). + currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 1, 0); + g_assert(ATSPI_IS_ACCESSIBLE(currentChild.get())); + checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_PARAGRAPH); + + // HTML second paragraph's accessible element (Web Process). + currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 2, 0); + g_assert(ATSPI_IS_ACCESSIBLE(currentChild.get())); + checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_PARAGRAPH); + + // HTML link's accessible element (Web Process). + currentParent = currentChild; + currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); + g_assert(ATSPI_IS_ACCESSIBLE(currentChild.get())); + checkAtspiAccessible(currentChild.get(), "a link", ATSPI_ROLE_LINK); +} + +void beforeAll() +{ + // We install a handler to ensure that we kill the child process + // if the parent dies because of whatever the reason is. + signal(SIGABRT, sigAbortHandler); + + // Start the accessibility test server and load the tests. + startTestServer(); + WebViewTest::add("WebKitAccessibility", "atspi-basic-hierarchy", testAtspiBasicHierarchy); +} + +void afterAll() +{ + // Ensure we stop the server. + stopTestServer(); +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitFaviconDatabase.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitFaviconDatabase.cpp new file mode 100644 index 000000000..8d5be9250 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitFaviconDatabase.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebKitTestServer.h" +#include "WebViewTest.h" +#include <glib/gstdio.h> +#include <libsoup/soup.h> +#include <wtf/glib/GUniquePtr.h> + +static WebKitTestServer* kServer; + +class FaviconDatabaseTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(FaviconDatabaseTest); + + FaviconDatabaseTest() + : m_favicon(nullptr) + , m_faviconNotificationReceived(false) + { + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(m_webContext.get()); + g_signal_connect(database, "favicon-changed", G_CALLBACK(faviconChangedCallback), this); + } + + ~FaviconDatabaseTest() + { + if (m_favicon) + cairo_surface_destroy(m_favicon); + + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(m_webContext.get()); + g_signal_handlers_disconnect_matched(database, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + static void faviconChangedCallback(WebKitFaviconDatabase* database, const char* pageURI, const char* faviconURI, FaviconDatabaseTest* test) + { + if (!g_strcmp0(webkit_web_view_get_uri(test->m_webView), pageURI)) + test->m_faviconURI = faviconURI; + } + + static void viewFaviconChangedCallback(WebKitWebView* webView, GParamSpec* pspec, gpointer data) + { + FaviconDatabaseTest* test = static_cast<FaviconDatabaseTest*>(data); + g_assert(test->m_webView == webView); + test->m_faviconNotificationReceived = true; + test->quitMainLoop(); + } + + static void getFaviconCallback(GObject* sourceObject, GAsyncResult* result, void* data) + { + FaviconDatabaseTest* test = static_cast<FaviconDatabaseTest*>(data); + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(test->m_webContext.get()); + test->m_favicon = webkit_favicon_database_get_favicon_finish(database, result, &test->m_error.outPtr()); + test->quitMainLoop(); + } + + void waitUntilFaviconChanged() + { + m_faviconNotificationReceived = false; + unsigned long handlerID = g_signal_connect(m_webView, "notify::favicon", G_CALLBACK(viewFaviconChangedCallback), this); + g_main_loop_run(m_mainLoop); + g_signal_handler_disconnect(m_webView, handlerID); + } + + void getFaviconForPageURIAndWaitUntilReady(const char* pageURI) + { + if (m_favicon) { + cairo_surface_destroy(m_favicon); + m_favicon = 0; + } + + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(m_webContext.get()); + webkit_favicon_database_get_favicon(database, pageURI, 0, getFaviconCallback, this); + g_main_loop_run(m_mainLoop); + } + + cairo_surface_t* m_favicon; + CString m_faviconURI; + GUniqueOutPtr<GError> m_error; + bool m_faviconNotificationReceived; +}; + +static void +serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable* query, SoupClientContext* context, void* data) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + if (g_str_equal(path, "/favicon.ico")) { + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); + soup_message_body_complete(message->response_body); + return; + } + + char* contents; + gsize length; + if (g_str_equal(path, "/icon/favicon.ico")) { + GUniquePtr<char> pathToFavicon(g_build_filename(Test::getResourcesDir().data(), "blank.ico", nullptr)); + g_file_get_contents(pathToFavicon.get(), &contents, &length, 0); + soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, length); + } else if (g_str_equal(path, "/nofavicon")) { + static const char* noFaviconHTML = "<html><head><body>test</body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, noFaviconHTML, strlen(noFaviconHTML)); + } else { + static const char* contentsHTML = "<html><head><link rel='icon' href='/icon/favicon.ico' type='image/x-ico; charset=binary'></head><body>test</body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, contentsHTML, strlen(contentsHTML)); + } + + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_complete(message->response_body); +} + +static void testNotInitialized(FaviconDatabaseTest* test) +{ + // Try to retrieve a valid favicon from a not initialized database. + test->getFaviconForPageURIAndWaitUntilReady(kServer->getURIForPath("/foo").data()); + g_assert(!test->m_favicon); + g_assert(test->m_error); + g_assert_cmpint(test->m_error->code, ==, WEBKIT_FAVICON_DATABASE_ERROR_NOT_INITIALIZED); +} + +static void testSetDirectory(FaviconDatabaseTest* test) +{ + webkit_web_context_set_favicon_database_directory(test->m_webContext.get(), Test::dataDirectory()); + g_assert_cmpstr(Test::dataDirectory(), ==, webkit_web_context_get_favicon_database_directory(test->m_webContext.get())); +} + +static void testClearDatabase(FaviconDatabaseTest* test) +{ + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(test->m_webContext.get()); + webkit_favicon_database_clear(database); + + GUniquePtr<char> iconURI(webkit_favicon_database_get_favicon_uri(database, kServer->getURIForPath("/foo").data())); + g_assert(!iconURI); +} + +static void testGetFavicon(FaviconDatabaseTest* test) +{ + // We need to load the page first to ensure the icon data will be + // in the database in case there's an associated favicon. + test->loadURI(kServer->getURIForPath("/foo").data()); + test->waitUntilFaviconChanged(); + CString faviconURI = kServer->getURIForPath("/icon/favicon.ico"); + + // Check the API retrieving a valid favicon. + test->getFaviconForPageURIAndWaitUntilReady(kServer->getURIForPath("/foo").data()); + g_assert(test->m_favicon); + g_assert_cmpstr(test->m_faviconURI.data(), ==, faviconURI.data()); + g_assert(!test->m_error); + + // Check that width and height match those from blank.ico (16x16 favicon). + g_assert_cmpint(cairo_image_surface_get_width(test->m_favicon), ==, 16); + g_assert_cmpint(cairo_image_surface_get_height(test->m_favicon), ==, 16); + + // Check that another page with the same favicon return the same icon. + cairo_surface_t* favicon = cairo_surface_reference(test->m_favicon); + test->loadURI(kServer->getURIForPath("/bar").data()); + // It's a new page in the database, so favicon will change twice, first to reset it + // and then when the icon is loaded. + test->waitUntilFaviconChanged(); + test->waitUntilFaviconChanged(); + test->getFaviconForPageURIAndWaitUntilReady(kServer->getURIForPath("/bar").data()); + g_assert(test->m_favicon); + g_assert_cmpstr(test->m_faviconURI.data(), ==, faviconURI.data()); + g_assert(test->m_favicon == favicon); + g_assert(!test->m_error); + cairo_surface_destroy(favicon); + + // Check the API retrieving an invalid favicon. + test->loadURI(kServer->getURIForPath("/nofavicon").data()); + test->waitUntilFaviconChanged(); + + test->getFaviconForPageURIAndWaitUntilReady(kServer->getURIForPath("/nofavicon").data()); + g_assert(!test->m_favicon); + g_assert(test->m_error); +} + +static void testGetFaviconURI(FaviconDatabaseTest* test) +{ + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(test->m_webContext.get()); + + CString baseURI = kServer->getURIForPath("/foo"); + GUniquePtr<char> iconURI(webkit_favicon_database_get_favicon_uri(database, baseURI.data())); + ASSERT_CMP_CSTRING(iconURI.get(), ==, kServer->getURIForPath("/icon/favicon.ico")); +} + +static void testWebViewFavicon(FaviconDatabaseTest* test) +{ + test->m_faviconURI = CString(); + + cairo_surface_t* iconFromWebView = webkit_web_view_get_favicon(test->m_webView); + g_assert(!iconFromWebView); + + test->loadURI(kServer->getURIForPath("/foo").data()); + test->waitUntilFaviconChanged(); + g_assert(test->m_faviconNotificationReceived); + // The icon is known and hasn't changed in the database, so notify::favicon is emitted + // but WebKitFaviconDatabase::icon-changed isn't. + g_assert(test->m_faviconURI.isNull()); + + iconFromWebView = webkit_web_view_get_favicon(test->m_webView); + g_assert(iconFromWebView); + g_assert_cmpuint(cairo_image_surface_get_width(iconFromWebView), ==, 16); + g_assert_cmpuint(cairo_image_surface_get_height(iconFromWebView), ==, 16); +} + +static void testFaviconDatabase(FaviconDatabaseTest* test, gconstpointer) +{ + // These tests depend on this order to run properly so we declare them in a single one. + // See https://bugs.webkit.org/show_bug.cgi?id=111434. + testNotInitialized(test); + testSetDirectory(test); + testGetFavicon(test); + testGetFaviconURI(test); + testWebViewFavicon(test); + testClearDatabase(test); +} + +void beforeAll() +{ + // Start a soup server for testing. + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + + // Add tests to the suite. + FaviconDatabaseTest::add("WebKitFaviconDatabase", "favicon-database-test", testFaviconDatabase); +} + +void afterAll() +{ + delete kServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitFindController.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitFindController.cpp new file mode 100644 index 000000000..7289fd37f --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitFindController.cpp @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "LoadTrackingTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> +#include <wtf/glib/GRefPtr.h> + +static const char* testString = "<html><body>first testing second testing secondHalf</body></html>"; + +class FindControllerTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(FindControllerTest); + + FindControllerTest() + : m_findController(webkit_web_view_get_find_controller(m_webView)) + , m_runFindUntilCompletion(false) + { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_findController.get())); + } + + ~FindControllerTest() + { + if (m_findController) + g_signal_handlers_disconnect_matched(m_findController.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + void find(const char* searchText, guint32 findOptions, guint maxMatchCount) + { + g_signal_connect(m_findController.get(), "found-text", G_CALLBACK(foundTextCallback), this); + g_signal_connect(m_findController.get(), "failed-to-find-text", G_CALLBACK(failedToFindTextCallback), this); + webkit_find_controller_search(m_findController.get(), searchText, findOptions, maxMatchCount); + } + + void count(const char* searchText, guint32 findOptions, guint maxMatchCount) + { + g_signal_connect(m_findController.get(), "counted-matches", G_CALLBACK(countedMatchesCallback), this); + webkit_find_controller_count_matches(m_findController.get(), searchText, findOptions, maxMatchCount); + } + + void waitUntilFindFinished() + { + m_runFindUntilCompletion = true; + g_main_loop_run(m_mainLoop); + } + + GRefPtr<WebKitFindController> m_findController; + bool m_textFound; + unsigned m_matchCount; + +private: + bool m_runFindUntilCompletion; + + static void foundTextCallback(WebKitFindController*, guint matchCount, FindControllerTest* test) + { + test->m_textFound = true; + test->m_matchCount = matchCount; + if (test->m_runFindUntilCompletion) + g_main_loop_quit(test->m_mainLoop); + } + + static void failedToFindTextCallback(WebKitFindController*, FindControllerTest* test) + { + test->m_textFound = false; + if (test->m_runFindUntilCompletion) + g_main_loop_quit(test->m_mainLoop); + } + + static void countedMatchesCallback(WebKitFindController*, guint matchCount, FindControllerTest* test) + { + test->m_matchCount = matchCount; + if (test->m_runFindUntilCompletion) + g_main_loop_quit(test->m_mainLoop); + } +}; + +static void testFindControllerTextFound(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); +} + +static void testFindControllerTextNotFound(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("notFound", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); +} + +static void testFindControllerMatchCount(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 2); + g_assert(test->m_textFound); +} + +static void testFindControllerMaxMatchCount(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == G_MAXUINT); + g_assert(test->m_textFound); +} + +static void testFindControllerNext(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 2); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 1); + g_assert(!(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS)); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + g_assert(test->m_matchCount == 1); + g_assert(!(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS)); +} + +static void testFindControllerPrevious(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 2); + g_assert(test->m_textFound); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 1); + g_assert(!(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS)); + + webkit_find_controller_search_previous(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 1); + g_assert(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS); +} + +static void testFindControllerCountedMatches(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->count("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 2); + + test->count("first", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 1); + + test->count("notFound", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_matchCount); +} + +static void testFindControllerOptions(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("Testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + + test->find("Testing", WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + + test->find("esting", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + + test->find("esting", WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + + test->find("Half", WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + + test->find("Half", WEBKIT_FIND_OPTIONS_AT_WORD_STARTS | WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + + test->find("testing", WEBKIT_FIND_OPTIONS_WRAP_AROUND, 3); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); +} + +static void testFindControllerHide(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->showInWindowAndWaitUntilMapped(); + + cairo_surface_t* originalSurface = cairo_surface_reference( + test->getSnapshotAndWaitUntilReady(WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT, WEBKIT_SNAPSHOT_OPTIONS_NONE)); + g_assert(originalSurface); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); + + cairo_surface_t* highlightSurface = cairo_surface_reference( + test->getSnapshotAndWaitUntilReady(WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT, WEBKIT_SNAPSHOT_OPTIONS_NONE)); + g_assert(highlightSurface); + g_assert(!Test::cairoSurfacesEqual(originalSurface, highlightSurface)); + + WebKitFindController* findController = webkit_web_view_get_find_controller(test->m_webView); + webkit_find_controller_search_finish(findController); + webkit_web_view_execute_editing_command(test->m_webView, "Unselect"); + + cairo_surface_t* unhighlightSurface = cairo_surface_reference( + test->getSnapshotAndWaitUntilReady(WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT, WEBKIT_SNAPSHOT_OPTIONS_NONE)); + g_assert(unhighlightSurface); + g_assert(Test::cairoSurfacesEqual(originalSurface, unhighlightSurface)); + + cairo_surface_destroy(originalSurface); + cairo_surface_destroy(highlightSurface); + cairo_surface_destroy(unhighlightSurface); +} + +static void testFindControllerInstance(FindControllerTest* test, gconstpointer) +{ + WebKitFindController* findController1 = webkit_web_view_get_find_controller(test->m_webView); + WebKitFindController* findController2 = webkit_web_view_get_find_controller(test->m_webView); + + g_assert(findController1 == findController2); +} + +static void testFindControllerGetters(FindControllerTest* test, gconstpointer) +{ + const char* searchText = "testing"; + guint maxMatchCount = 1; + guint32 findOptions = WEBKIT_FIND_OPTIONS_WRAP_AROUND | WEBKIT_FIND_OPTIONS_AT_WORD_STARTS; + WebKitFindController* findController = webkit_web_view_get_find_controller(test->m_webView); + + webkit_find_controller_search(findController, searchText, findOptions, maxMatchCount); + g_assert(webkit_find_controller_get_web_view(findController) == test->m_webView); + g_assert(!g_strcmp0(webkit_find_controller_get_search_text(findController), searchText)); + g_assert(webkit_find_controller_get_max_match_count(findController) == maxMatchCount); + g_assert(webkit_find_controller_get_options(findController) == findOptions); +} + +void beforeAll() +{ + FindControllerTest::add("WebKitFindController", "getters", testFindControllerGetters); + FindControllerTest::add("WebKitFindController", "instance", testFindControllerInstance); + FindControllerTest::add("WebKitFindController", "text-found", testFindControllerTextFound); + FindControllerTest::add("WebKitFindController", "text-not-found", testFindControllerTextNotFound); + FindControllerTest::add("WebKitFindController", "match-count", testFindControllerMatchCount); + FindControllerTest::add("WebKitFindController", "max-match-count", testFindControllerMaxMatchCount); + FindControllerTest::add("WebKitFindController", "next", testFindControllerNext); + FindControllerTest::add("WebKitFindController", "previous", testFindControllerPrevious); + FindControllerTest::add("WebKitFindController", "counted-matches", testFindControllerCountedMatches); + FindControllerTest::add("WebKitFindController", "options", testFindControllerOptions); + FindControllerTest::add("WebKitFindController", "hide", testFindControllerHide); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitPolicyClient.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitPolicyClient.cpp new file mode 100644 index 000000000..9f9515123 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitPolicyClient.cpp @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "LoadTrackingTest.h" +#include "WebKitTestServer.h" +#include <wtf/glib/GRefPtr.h> +#include <wtf/text/CString.h> + +static WebKitTestServer* kServer; + +class PolicyClientTest: public LoadTrackingTest { +public: + MAKE_GLIB_TEST_FIXTURE(PolicyClientTest); + + enum PolicyDecisionResponse { + Use, + Ignore, + Download, + None + }; + + PolicyClientTest() + : LoadTrackingTest() + , m_policyDecisionResponse(None) + , m_policyDecisionTypeFilter(0) + , m_respondToPolicyDecisionAsynchronously(false) + , m_haltMainLoopAfterMakingDecision(false) + { + g_signal_connect(m_webView, "decide-policy", G_CALLBACK(decidePolicyCallback), this); + } + + static gboolean quitMainLoopLater(GMainLoop* loop) + { + g_main_loop_quit(loop); + return FALSE; + } + + static void respondToPolicyDecision(PolicyClientTest* test, WebKitPolicyDecision* decision) + { + switch (test->m_policyDecisionResponse) { + case Use: + webkit_policy_decision_use(decision); + break; + case Ignore: + webkit_policy_decision_ignore(decision); + break; + case Download: + webkit_policy_decision_download(decision); + break; + case None: + break; + } + + if (test->m_haltMainLoopAfterMakingDecision) + g_idle_add(reinterpret_cast<GSourceFunc>(quitMainLoopLater), test->m_mainLoop); + } + + static gboolean respondToPolicyDecisionLater(PolicyClientTest* test) + { + respondToPolicyDecision(test, test->m_previousPolicyDecision.get()); + test->m_previousPolicyDecision = 0; + return FALSE; + } + + static gboolean decidePolicyCallback(WebKitWebView* webView, WebKitPolicyDecision* decision, WebKitPolicyDecisionType type, PolicyClientTest* test) + { + if (test->m_policyDecisionTypeFilter != type) + return FALSE; + + test->m_previousPolicyDecision = decision; + if (test->m_respondToPolicyDecisionAsynchronously) { + g_idle_add(reinterpret_cast<GSourceFunc>(respondToPolicyDecisionLater), test); + return TRUE; + } + + respondToPolicyDecision(test, decision); + + // We return FALSE here to ensure that the default policy decision + // handler doesn't override whatever we use here. + return FALSE; + } + + PolicyDecisionResponse m_policyDecisionResponse; + int m_policyDecisionTypeFilter; + bool m_respondToPolicyDecisionAsynchronously; + bool m_haltMainLoopAfterMakingDecision; + GRefPtr<WebKitPolicyDecision> m_previousPolicyDecision; +}; + +static void testNavigationPolicy(PolicyClientTest* test, gconstpointer) +{ + test->m_policyDecisionTypeFilter = WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION; + + test->m_policyDecisionResponse = PolicyClientTest::Use; + test->loadHtml("<html/>", "http://webkitgtk.org/"); + test->waitUntilLoadFinished(); + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + + // Ideally we'd like to have a more intensive test here, but it's still pretty tricky + // to trigger different types of navigations with the GTK+ WebKit2 API. + WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(test->m_previousPolicyDecision.get()); + WebKitNavigationAction* navigationAction = webkit_navigation_policy_decision_get_navigation_action(decision); + g_assert_cmpint(webkit_navigation_action_get_navigation_type(navigationAction), ==, WEBKIT_NAVIGATION_TYPE_OTHER); + g_assert_cmpint(webkit_navigation_action_get_mouse_button(navigationAction), ==, 0); + g_assert_cmpint(webkit_navigation_action_get_modifiers(navigationAction), ==, 0); + g_assert(!webkit_navigation_policy_decision_get_frame_name(decision)); + WebKitURIRequest* request = webkit_navigation_action_get_request(navigationAction); + g_assert_cmpstr(webkit_uri_request_get_uri(request), ==, "http://webkitgtk.org/"); + + test->m_policyDecisionResponse = PolicyClientTest::Use; + test->m_respondToPolicyDecisionAsynchronously = true; + test->loadHtml("<html/>", "http://webkitgtk.org/"); + test->waitUntilLoadFinished(); + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + + // If we are waiting until load completion, it will never complete if we ignore the + // navigation. So we tell the main loop to quit sometime later. + test->m_policyDecisionResponse = PolicyClientTest::Ignore; + test->m_respondToPolicyDecisionAsynchronously = false; + test->m_haltMainLoopAfterMakingDecision = true; + test->loadHtml("<html/>", "http://webkitgtk.org/"); + test->waitUntilLoadFinished(); + g_assert_cmpint(test->m_loadEvents.size(), ==, 0); + + test->m_policyDecisionResponse = PolicyClientTest::Ignore; + test->loadHtml("<html/>", "http://webkitgtk.org/"); + test->waitUntilLoadFinished(); + g_assert_cmpint(test->m_loadEvents.size(), ==, 0); +} + +static void testResponsePolicy(PolicyClientTest* test, gconstpointer) +{ + test->m_policyDecisionTypeFilter = WEBKIT_POLICY_DECISION_TYPE_RESPONSE; + + test->m_policyDecisionResponse = PolicyClientTest::Use; + test->loadURI(kServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + + WebKitResponsePolicyDecision* decision = WEBKIT_RESPONSE_POLICY_DECISION(test->m_previousPolicyDecision.get()); + WebKitURIRequest* request = webkit_response_policy_decision_get_request(decision); + g_assert(WEBKIT_IS_URI_REQUEST(request)); + ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, kServer->getURIForPath("/")); + WebKitURIResponse* response = webkit_response_policy_decision_get_response(decision); + g_assert(WEBKIT_IS_URI_RESPONSE(response)); + ASSERT_CMP_CSTRING(webkit_uri_response_get_uri(response), ==, kServer->getURIForPath("/")); + g_assert(webkit_web_view_can_show_mime_type(test->m_webView, webkit_uri_response_get_mime_type(response)) == + webkit_response_policy_decision_is_mime_type_supported(decision)); + + test->m_respondToPolicyDecisionAsynchronously = true; + test->loadURI(kServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); + + test->m_respondToPolicyDecisionAsynchronously = false; + test->m_policyDecisionResponse = PolicyClientTest::Ignore; + test->loadURI(kServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + + g_assert_cmpint(test->m_loadEvents.size(), ==, 3); + g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); + g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed); + g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); +} + +struct CreateCallbackData { + bool triedToOpenWindow; + GMainLoop* mainLoop; +}; + +static WebKitWebView* createCallback(WebKitWebView* webView, WebKitNavigationAction*, CreateCallbackData* data) +{ + data->triedToOpenWindow = true; + g_main_loop_quit(data->mainLoop); + return 0; +} + +static void testNewWindowPolicy(PolicyClientTest* test, gconstpointer) +{ + static const char* windowOpeningHTML = + "<html><body>" + " <a id=\"link\" href=\"http://www.google.com\" target=\"_blank\">Link</a>" + " <script>" + " var event = document.createEvent('MouseEvents');" + " event.initEvent('click', true, false);" + " document.getElementById('link').dispatchEvent(event);" + " </script>" + "</body></html>"; + test->m_policyDecisionTypeFilter = WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION; + webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(test->m_webView), TRUE); + + CreateCallbackData data; + data.triedToOpenWindow = false; + data.mainLoop = test->m_mainLoop; + + g_signal_connect(test->m_webView, "create", G_CALLBACK(createCallback), &data); + test->m_policyDecisionResponse = PolicyClientTest::Use; + test->loadHtml(windowOpeningHTML, "http://webkitgtk.org/"); + test->wait(1); + g_assert(data.triedToOpenWindow); + + WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(test->m_previousPolicyDecision.get()); + g_assert_cmpstr(webkit_navigation_policy_decision_get_frame_name(decision), ==, "_blank"); + + // Using a short timeout is a bit ugly here, but it's hard to get around because if we block + // the new window signal we cannot halt the main loop in the create callback. If we + // halt the main loop in the policy decision, the create callback never executes. + data.triedToOpenWindow = false; + test->m_policyDecisionResponse = PolicyClientTest::Ignore; + test->loadHtml(windowOpeningHTML, "http://webkitgtk.org/"); + test->wait(.2); + g_assert(!data.triedToOpenWindow); +} + +static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + if (g_str_equal(path, "/")) { + static const char* responseString = "<html><body>Testing!</body></html>"; + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, responseString, strlen(responseString)); + soup_message_body_complete(message->response_body); + } else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); +} + +void beforeAll() +{ + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + + PolicyClientTest::add("WebKitPolicyClient", "navigation-policy", testNavigationPolicy); + PolicyClientTest::add("WebKitPolicyClient", "response-policy", testResponsePolicy); + PolicyClientTest::add("WebKitPolicyClient", "new-window-policy", testNewWindowPolicy); +} + +void afterAll() +{ + delete kServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitSettings.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitSettings.cpp new file mode 100644 index 000000000..b3a377270 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitSettings.cpp @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2011 Motorola Mobility, 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 Motorola Mobility, 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 HOLDER 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 "TestMain.h" +#include "WebViewTest.h" +#include "WebKitTestServer.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> +#include <wtf/glib/GRefPtr.h> + +static WebKitTestServer* gServer; + +static void testWebKitSettings(Test*, gconstpointer) +{ + WebKitSettings* settings = webkit_settings_new(); + + // JavaScript is enabled by default. + g_assert(webkit_settings_get_enable_javascript(settings)); + webkit_settings_set_enable_javascript(settings, FALSE); + g_assert(!webkit_settings_get_enable_javascript(settings)); + + // By default auto-load-image is true. + g_assert(webkit_settings_get_auto_load_images(settings)); + webkit_settings_set_auto_load_images(settings, FALSE); + g_assert(!webkit_settings_get_auto_load_images(settings)); + + // load-icons-ignoring-image-load-setting is false by default. + g_assert(!webkit_settings_get_load_icons_ignoring_image_load_setting(settings)); + webkit_settings_set_load_icons_ignoring_image_load_setting(settings, TRUE); + g_assert(webkit_settings_get_load_icons_ignoring_image_load_setting(settings)); + + // Offline application cache is true by default. + g_assert(webkit_settings_get_enable_offline_web_application_cache(settings)); + webkit_settings_set_enable_offline_web_application_cache(settings, FALSE); + g_assert(!webkit_settings_get_enable_offline_web_application_cache(settings)); + + // Local storage is enable by default. + g_assert(webkit_settings_get_enable_html5_local_storage(settings)); + webkit_settings_set_enable_html5_local_storage(settings, FALSE); + g_assert(!webkit_settings_get_enable_html5_local_storage(settings)); + + // HTML5 database is enabled by default. + g_assert(webkit_settings_get_enable_html5_database(settings)); + webkit_settings_set_enable_html5_database(settings, FALSE); + g_assert(!webkit_settings_get_enable_html5_database(settings)); + + // XSS Auditor is enabled by default. + g_assert(webkit_settings_get_enable_xss_auditor(settings)); + webkit_settings_set_enable_xss_auditor(settings, FALSE); + g_assert(!webkit_settings_get_enable_xss_auditor(settings)); + + // Frame flattening is disabled by default. + g_assert(!webkit_settings_get_enable_frame_flattening(settings)); + webkit_settings_set_enable_frame_flattening(settings, TRUE); + g_assert(webkit_settings_get_enable_frame_flattening(settings)); + + // Plugins are enabled by default. + g_assert(webkit_settings_get_enable_plugins(settings)); + webkit_settings_set_enable_plugins(settings, FALSE); + g_assert(!webkit_settings_get_enable_plugins(settings)); + + // Java is enabled by default. + g_assert(webkit_settings_get_enable_java(settings)); + webkit_settings_set_enable_java(settings, FALSE); + g_assert(!webkit_settings_get_enable_java(settings)); + + // By default, JavaScript can open windows automatically is disabled. + g_assert(!webkit_settings_get_javascript_can_open_windows_automatically(settings)); + webkit_settings_set_javascript_can_open_windows_automatically(settings, TRUE); + g_assert(webkit_settings_get_javascript_can_open_windows_automatically(settings)); + + // By default hyper link auditing is disabled. + g_assert(!webkit_settings_get_enable_hyperlink_auditing(settings)); + webkit_settings_set_enable_hyperlink_auditing(settings, TRUE); + g_assert(webkit_settings_get_enable_hyperlink_auditing(settings)); + + // Default font family is "sans-serif". + g_assert_cmpstr(webkit_settings_get_default_font_family(settings), ==, "sans-serif"); + webkit_settings_set_default_font_family(settings, "monospace"); + g_assert_cmpstr(webkit_settings_get_default_font_family(settings), ==, "monospace"); + + // Default monospace font family font family is "monospace". + g_assert_cmpstr(webkit_settings_get_monospace_font_family(settings), ==, "monospace"); + webkit_settings_set_monospace_font_family(settings, "sans-serif"); + g_assert_cmpstr(webkit_settings_get_monospace_font_family(settings), ==, "sans-serif"); + + // Default serif font family is "serif". + g_assert_cmpstr(webkit_settings_get_serif_font_family(settings), ==, "serif"); + webkit_settings_set_serif_font_family(settings, "sans-serif"); + g_assert_cmpstr(webkit_settings_get_serif_font_family(settings), ==, "sans-serif"); + + // Default sans serif font family is "sans-serif". + g_assert_cmpstr(webkit_settings_get_sans_serif_font_family(settings), ==, "sans-serif"); + webkit_settings_set_sans_serif_font_family(settings, "serif"); + g_assert_cmpstr(webkit_settings_get_sans_serif_font_family(settings), ==, "serif"); + + // Default cursive font family "serif". + g_assert_cmpstr(webkit_settings_get_cursive_font_family(settings), ==, "serif"); + webkit_settings_set_cursive_font_family(settings, "sans-serif"); + g_assert_cmpstr(webkit_settings_get_cursive_font_family(settings), ==, "sans-serif"); + + // Default fantasy font family is "serif". + g_assert_cmpstr(webkit_settings_get_fantasy_font_family(settings), ==, "serif"); + webkit_settings_set_fantasy_font_family(settings, "sans-serif"); + g_assert_cmpstr(webkit_settings_get_fantasy_font_family(settings), ==, "sans-serif"); + + // Default pictograph font family is "serif". + g_assert_cmpstr(webkit_settings_get_pictograph_font_family(settings), ==, "serif"); + webkit_settings_set_pictograph_font_family(settings, "sans-serif"); + g_assert_cmpstr(webkit_settings_get_pictograph_font_family(settings), ==, "sans-serif"); + + // Default font size is 16. + g_assert_cmpuint(webkit_settings_get_default_font_size(settings), ==, 16); + webkit_settings_set_default_font_size(settings, 14); + g_assert_cmpuint(webkit_settings_get_default_font_size(settings), ==, 14); + + // Default monospace font size is 13. + g_assert_cmpuint(webkit_settings_get_default_monospace_font_size(settings), ==, 13); + webkit_settings_set_default_monospace_font_size(settings, 10); + g_assert_cmpuint(webkit_settings_get_default_monospace_font_size(settings), ==, 10); + + // Default minimum font size is 0. + g_assert_cmpuint(webkit_settings_get_minimum_font_size(settings), ==, 0); + webkit_settings_set_minimum_font_size(settings, 7); + g_assert_cmpuint(webkit_settings_get_minimum_font_size(settings), ==, 7); + + // Default charset is "iso-8859-1". + g_assert_cmpstr(webkit_settings_get_default_charset(settings), ==, "iso-8859-1"); + webkit_settings_set_default_charset(settings, "utf8"); + g_assert_cmpstr(webkit_settings_get_default_charset(settings), ==, "utf8"); + + g_assert(!webkit_settings_get_enable_private_browsing(settings)); + webkit_settings_set_enable_private_browsing(settings, TRUE); + g_assert(webkit_settings_get_enable_private_browsing(settings)); + + g_assert(!webkit_settings_get_enable_developer_extras(settings)); + webkit_settings_set_enable_developer_extras(settings, TRUE); + g_assert(webkit_settings_get_enable_developer_extras(settings)); + + g_assert(webkit_settings_get_enable_resizable_text_areas(settings)); + webkit_settings_set_enable_resizable_text_areas(settings, FALSE); + g_assert(!webkit_settings_get_enable_resizable_text_areas(settings)); + + g_assert(webkit_settings_get_enable_tabs_to_links(settings)); + webkit_settings_set_enable_tabs_to_links(settings, FALSE); + g_assert(!webkit_settings_get_enable_tabs_to_links(settings)); + + g_assert(!webkit_settings_get_enable_dns_prefetching(settings)); + webkit_settings_set_enable_dns_prefetching(settings, TRUE); + g_assert(webkit_settings_get_enable_dns_prefetching(settings)); + + // Caret browsing is disabled by default. + g_assert(!webkit_settings_get_enable_caret_browsing(settings)); + webkit_settings_set_enable_caret_browsing(settings, TRUE); + g_assert(webkit_settings_get_enable_caret_browsing(settings)); + + // Fullscreen JavaScript API is enabled by default. + g_assert(webkit_settings_get_enable_fullscreen(settings)); + webkit_settings_set_enable_fullscreen(settings, FALSE); + g_assert(!webkit_settings_get_enable_fullscreen(settings)); + + // Print backgrounds is enabled by default + g_assert(webkit_settings_get_print_backgrounds(settings)); + webkit_settings_set_print_backgrounds(settings, FALSE); + g_assert(!webkit_settings_get_print_backgrounds(settings)); + + // WebAudio is disabled by default. + g_assert(!webkit_settings_get_enable_webaudio(settings)); + webkit_settings_set_enable_webaudio(settings, TRUE); + g_assert(webkit_settings_get_enable_webaudio(settings)); + + // WebGL is disabled by default. + g_assert(!webkit_settings_get_enable_webgl(settings)); + webkit_settings_set_enable_webgl(settings, TRUE); + g_assert(webkit_settings_get_enable_webgl(settings)); + + // Allow Modal Dialogs is disabled by default. + g_assert(!webkit_settings_get_allow_modal_dialogs(settings)); + webkit_settings_set_allow_modal_dialogs(settings, TRUE); + g_assert(webkit_settings_get_allow_modal_dialogs(settings)); + + // Zoom text only is disabled by default. + g_assert(!webkit_settings_get_zoom_text_only(settings)); + webkit_settings_set_zoom_text_only(settings, TRUE); + g_assert(webkit_settings_get_zoom_text_only(settings)); + + // By default, JavaScript cannot access the clipboard. + g_assert(!webkit_settings_get_javascript_can_access_clipboard(settings)); + webkit_settings_set_javascript_can_access_clipboard(settings, TRUE); + g_assert(webkit_settings_get_javascript_can_access_clipboard(settings)); + + // By default, media playback doesn't require user gestures. + g_assert(!webkit_settings_get_media_playback_requires_user_gesture(settings)); + webkit_settings_set_media_playback_requires_user_gesture(settings, TRUE); + g_assert(webkit_settings_get_media_playback_requires_user_gesture(settings)); + + // By default, inline media playback is allowed + g_assert(webkit_settings_get_media_playback_allows_inline(settings)); + webkit_settings_set_media_playback_allows_inline(settings, FALSE); + g_assert(!webkit_settings_get_media_playback_allows_inline(settings)); + + // By default, debug indicators are disabled. + g_assert(!webkit_settings_get_draw_compositing_indicators(settings)); + webkit_settings_set_draw_compositing_indicators(settings, TRUE); + g_assert(webkit_settings_get_draw_compositing_indicators(settings)); + + // By default, site specific quirks are enabled. + g_assert(webkit_settings_get_enable_site_specific_quirks(settings)); + webkit_settings_set_enable_site_specific_quirks(settings, FALSE); + g_assert(!webkit_settings_get_enable_site_specific_quirks(settings)); + + // By default, page cache is enabled. + g_assert(webkit_settings_get_enable_page_cache(settings)); + webkit_settings_set_enable_page_cache(settings, FALSE); + g_assert(!webkit_settings_get_enable_page_cache(settings)); + + // By default, smooth scrolling is disabled. + g_assert(!webkit_settings_get_enable_smooth_scrolling(settings)); + webkit_settings_set_enable_smooth_scrolling(settings, TRUE); + g_assert(webkit_settings_get_enable_smooth_scrolling(settings)); + + // By default, accelerated 2D canvas is disabled. + g_assert(!webkit_settings_get_enable_accelerated_2d_canvas(settings)); + webkit_settings_set_enable_accelerated_2d_canvas(settings, TRUE); + g_assert(webkit_settings_get_enable_accelerated_2d_canvas(settings)); + + // By default, writing of console messages to stdout is disabled. + g_assert(!webkit_settings_get_enable_write_console_messages_to_stdout(settings)); + webkit_settings_set_enable_write_console_messages_to_stdout(settings, TRUE); + g_assert(webkit_settings_get_enable_write_console_messages_to_stdout(settings)); + + // MediaStream is disabled by default. + g_assert(!webkit_settings_get_enable_media_stream(settings)); + webkit_settings_set_enable_media_stream(settings, TRUE); + g_assert(webkit_settings_get_enable_media_stream(settings)); + + // By default, SpatialNavigation is disabled + g_assert(!webkit_settings_get_enable_spatial_navigation(settings)); + webkit_settings_set_enable_spatial_navigation(settings, TRUE); + g_assert(webkit_settings_get_enable_spatial_navigation(settings)); + + // MediaSource is disabled by default + g_assert(!webkit_settings_get_enable_mediasource(settings)); + webkit_settings_set_enable_mediasource(settings, TRUE); + g_assert(webkit_settings_get_enable_mediasource(settings)); + + // File access from file URLs is not allowed by default. + g_assert(!webkit_settings_get_allow_file_access_from_file_urls(settings)); + webkit_settings_set_allow_file_access_from_file_urls(settings, TRUE); + g_assert(webkit_settings_get_allow_file_access_from_file_urls(settings)); + + g_object_unref(G_OBJECT(settings)); +} + +void testWebKitSettingsNewWithSettings(Test* test, gconstpointer) +{ + GRefPtr<WebKitSettings> settings = adoptGRef(webkit_settings_new_with_settings( + "enable-javascript", FALSE, + "auto-load-images", FALSE, + "load-icons-ignoring-image-load-setting", TRUE, + nullptr)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(settings.get())); + g_assert(!webkit_settings_get_enable_javascript(settings.get())); + g_assert(!webkit_settings_get_auto_load_images(settings.get())); + g_assert(webkit_settings_get_load_icons_ignoring_image_load_setting(settings.get())); +} + +static CString convertWebViewMainResourceDataToCString(WebViewTest* test) +{ + size_t mainResourceDataSize = 0; + const char* mainResourceData = test->mainResourceData(mainResourceDataSize); + return CString(mainResourceData, mainResourceDataSize); +} + +static void assertThatUserAgentIsSentInHeaders(WebViewTest* test, const CString& userAgent) +{ + test->loadURI(gServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + ASSERT_CMP_CSTRING(convertWebViewMainResourceDataToCString(test), ==, userAgent); +} + +static void testWebKitSettingsUserAgent(WebViewTest* test, gconstpointer) +{ + GRefPtr<WebKitSettings> settings = adoptGRef(webkit_settings_new()); + CString defaultUserAgent = webkit_settings_get_user_agent(settings.get()); + webkit_web_view_set_settings(test->m_webView, settings.get()); + + g_assert(g_strstr_len(defaultUserAgent.data(), -1, "AppleWebKit")); + g_assert(g_strstr_len(defaultUserAgent.data(), -1, "Safari")); + + webkit_settings_set_user_agent(settings.get(), 0); + g_assert_cmpstr(defaultUserAgent.data(), ==, webkit_settings_get_user_agent(settings.get())); + assertThatUserAgentIsSentInHeaders(test, defaultUserAgent.data()); + + webkit_settings_set_user_agent(settings.get(), ""); + g_assert_cmpstr(defaultUserAgent.data(), ==, webkit_settings_get_user_agent(settings.get())); + + const char* funkyUserAgent = "Funky!"; + webkit_settings_set_user_agent(settings.get(), funkyUserAgent); + g_assert_cmpstr(funkyUserAgent, ==, webkit_settings_get_user_agent(settings.get())); + assertThatUserAgentIsSentInHeaders(test, funkyUserAgent); + + webkit_settings_set_user_agent_with_application_details(settings.get(), "WebKitGTK+", 0); + const char* userAgentWithNullVersion = webkit_settings_get_user_agent(settings.get()); + g_assert_cmpstr(g_strstr_len(userAgentWithNullVersion, -1, defaultUserAgent.data()), ==, userAgentWithNullVersion); + g_assert(g_strstr_len(userAgentWithNullVersion, -1, "WebKitGTK+")); + + webkit_settings_set_user_agent_with_application_details(settings.get(), "WebKitGTK+", ""); + g_assert_cmpstr(webkit_settings_get_user_agent(settings.get()), ==, userAgentWithNullVersion); + + webkit_settings_set_user_agent_with_application_details(settings.get(), "WebCatGTK+", "3.4.5"); + const char* newUserAgent = webkit_settings_get_user_agent(settings.get()); + g_assert(g_strstr_len(newUserAgent, -1, "3.4.5")); + g_assert(g_strstr_len(newUserAgent, -1, "WebCatGTK+")); + + GUniquePtr<char> applicationUserAgent(g_strdup_printf("%s %s", defaultUserAgent.data(), "WebCatGTK+/3.4.5")); + g_assert_cmpstr(applicationUserAgent.get(), ==, webkit_settings_get_user_agent(settings.get())); +} + +static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + if (g_str_equal(path, "/")) { + const char* userAgent = soup_message_headers_get_one(message->request_headers, "User-Agent"); + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, userAgent, strlen(userAgent)); + soup_message_body_complete(message->response_body); + } else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); +} + +void beforeAll() +{ + gServer = new WebKitTestServer(); + gServer->run(serverCallback); + + Test::add("WebKitSettings", "webkit-settings", testWebKitSettings); + Test::add("WebKitSettings", "new-with-settings", testWebKitSettingsNewWithSettings); + WebViewTest::add("WebKitSettings", "user-agent", testWebKitSettingsUserAgent); +} + +void afterAll() +{ + delete gServer; +} + diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitUserContentManager.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitUserContentManager.cpp new file mode 100644 index 000000000..e84cb5c20 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitUserContentManager.cpp @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2013-2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "WebKitTestServer.h" +#include "WebViewTest.h" +#include <cstdarg> +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> + +class UserContentManagerTest : public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(UserContentManagerTest); + + UserContentManagerTest() + : WebViewTest(webkit_user_content_manager_new()) + { + // A reference is leaked when passing the result of webkit_user_content_manager_new() + // directly to webkit_web_view_new_with_user_content_manager() above. Adopting the + // reference here avoids the leak. + m_userContentManager = adoptGRef(webkit_web_view_get_user_content_manager(m_webView)); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_userContentManager.get())); + } + + GRefPtr<WebKitUserContentManager> m_userContentManager; +}; + +static WebKitTestServer* kServer; + +// These are all here so that they can be changed easily, if necessary. +static const char* kStyleSheetHTML = "<html><div id=\"styledElement\">Sweet stylez!</div></html>"; +static const char* kInjectedStyleSheet = "#styledElement { font-weight: bold; }"; +static const char* kStyleSheetTestScript = "getComputedStyle(document.getElementById('styledElement'))['font-weight']"; +static const char* kStyleSheetTestScriptResult = "bold"; +static const char* kInjectedScript = "document.write('<div id=\"item\">Generated by a script</div>')"; +static const char* kScriptTestScript = "document.getElementById('item').innerText"; +static const char* kScriptTestScriptResult = "Generated by a script"; + +static void testWebViewNewWithUserContentManager(Test* test, gconstpointer) +{ + GRefPtr<WebKitUserContentManager> userContentManager1 = adoptGRef(webkit_user_content_manager_new()); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(userContentManager1.get())); + GRefPtr<WebKitWebView> webView1 = WEBKIT_WEB_VIEW(webkit_web_view_new_with_user_content_manager(userContentManager1.get())); + g_assert(webkit_web_view_get_user_content_manager(webView1.get()) == userContentManager1.get()); + + GRefPtr<WebKitWebView> webView2 = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_assert(webkit_web_view_get_user_content_manager(webView2.get()) != userContentManager1.get()); +} + +static bool isStyleSheetInjectedForURLAtPath(WebViewTest* test, const char* path) +{ + test->loadURI(kServer->getURIForPath(path).data()); + test->waitUntilLoadFinished(); + + GUniqueOutPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished(kStyleSheetTestScript, &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + + GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult)); + return !g_strcmp0(resultString.get(), kStyleSheetTestScriptResult); +} + +static bool isScriptInjectedForURLAtPath(WebViewTest* test, const char* path) +{ + test->loadURI(kServer->getURIForPath(path).data()); + test->waitUntilLoadFinished(); + + GUniqueOutPtr<GError> error; + if (WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished(kScriptTestScript, &error.outPtr())) { + g_assert(!error.get()); + + GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult)); + return !g_strcmp0(resultString.get(), kScriptTestScriptResult); + } + return false; +} + +static void fillURLListFromPaths(char** list, const char* path, ...) +{ + va_list argumentList; + va_start(argumentList, path); + + int i = 0; + while (path) { + // FIXME: We must use a wildcard for the host here until http://wkbug.com/112476 is fixed. + // Until that time patterns with port numbers in them will not properly match URLs with port numbers. + list[i++] = g_strdup_printf("http://*/%s*", path); + path = va_arg(argumentList, const char*); + } +} + +static void removeOldInjectedContentAndResetLists(WebKitUserContentManager* userContentManager, char** whitelist, char** blacklist) +{ + webkit_user_content_manager_remove_all_style_sheets(userContentManager); + webkit_user_content_manager_remove_all_scripts(userContentManager); + + while (*whitelist) { + g_free(*whitelist); + *whitelist = 0; + whitelist++; + } + + while (*blacklist) { + g_free(*blacklist); + *blacklist = 0; + blacklist++; + } +} + +static void testUserContentManagerInjectedStyleSheet(UserContentManagerTest* test, gconstpointer) +{ + char* whitelist[3] = { 0, 0, 0 }; + char* blacklist[3] = { 0, 0, 0 }; + + removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist); + + // Without a whitelist or a blacklist all URLs should have the injected style sheet. + static const char* randomPath = "somerandompath"; + g_assert(!isStyleSheetInjectedForURLAtPath(test, randomPath)); + WebKitUserStyleSheet* styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, nullptr, nullptr); + webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet); + webkit_user_style_sheet_unref(styleSheet); + g_assert(isStyleSheetInjectedForURLAtPath(test, randomPath)); + + removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist); + + fillURLListFromPaths(blacklist, randomPath, 0); + styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, nullptr, blacklist); + webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet); + webkit_user_style_sheet_unref(styleSheet); + g_assert(!isStyleSheetInjectedForURLAtPath(test, randomPath)); + g_assert(isStyleSheetInjectedForURLAtPath(test, "someotherrandompath")); + + removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist); + + static const char* inTheWhiteList = "inthewhitelist"; + static const char* notInWhitelist = "notinthewhitelist"; + static const char* inTheWhiteListAndBlackList = "inthewhitelistandblacklist"; + + fillURLListFromPaths(whitelist, inTheWhiteList, inTheWhiteListAndBlackList, 0); + fillURLListFromPaths(blacklist, inTheWhiteListAndBlackList, 0); + styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, whitelist, blacklist); + webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet); + webkit_user_style_sheet_unref(styleSheet); + g_assert(isStyleSheetInjectedForURLAtPath(test, inTheWhiteList)); + g_assert(!isStyleSheetInjectedForURLAtPath(test, inTheWhiteListAndBlackList)); + g_assert(!isStyleSheetInjectedForURLAtPath(test, notInWhitelist)); + + // It's important to clean up the environment before other tests. + removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist); +} + +static void testUserContentManagerInjectedScript(UserContentManagerTest* test, gconstpointer) +{ + char* whitelist[3] = { 0, 0, 0 }; + char* blacklist[3] = { 0, 0, 0 }; + + removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist); + + // Without a whitelist or a blacklist all URLs should have the injected script. + static const char* randomPath = "somerandompath"; + g_assert(!isScriptInjectedForURLAtPath(test, randomPath)); + WebKitUserScript* script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, nullptr, nullptr); + webkit_user_content_manager_add_script(test->m_userContentManager.get(), script); + webkit_user_script_unref(script); + g_assert(isScriptInjectedForURLAtPath(test, randomPath)); + + removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist); + + fillURLListFromPaths(blacklist, randomPath, 0); + script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, nullptr, blacklist); + webkit_user_content_manager_add_script(test->m_userContentManager.get(), script); + webkit_user_script_unref(script); + g_assert(!isScriptInjectedForURLAtPath(test, randomPath)); + g_assert(isScriptInjectedForURLAtPath(test, "someotherrandompath")); + + removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist); + + static const char* inTheWhiteList = "inthewhitelist"; + static const char* notInWhitelist = "notinthewhitelist"; + static const char* inTheWhiteListAndBlackList = "inthewhitelistandblacklist"; + + fillURLListFromPaths(whitelist, inTheWhiteList, inTheWhiteListAndBlackList, 0); + fillURLListFromPaths(blacklist, inTheWhiteListAndBlackList, 0); + script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, whitelist, blacklist); + webkit_user_content_manager_add_script(test->m_userContentManager.get(), script); + webkit_user_script_unref(script); + g_assert(isScriptInjectedForURLAtPath(test, inTheWhiteList)); + g_assert(!isScriptInjectedForURLAtPath(test, inTheWhiteListAndBlackList)); + g_assert(!isScriptInjectedForURLAtPath(test, notInWhitelist)); + + // It's important to clean up the environment before other tests. + removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist); +} + +class UserScriptMessageTest : public UserContentManagerTest { +public: + MAKE_GLIB_TEST_FIXTURE(UserScriptMessageTest); + + UserScriptMessageTest() + : UserContentManagerTest() + , m_userScriptMessage(nullptr) + { + } + + ~UserScriptMessageTest() + { + if (m_userScriptMessage) + webkit_javascript_result_unref(m_userScriptMessage); + } + + bool registerHandler(const char* handlerName) + { + return webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), handlerName); + } + + void unregisterHandler(const char* handlerName) + { + webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), handlerName); + } + + static void scriptMessageReceived(WebKitUserContentManager* userContentManager, WebKitJavascriptResult* jsResult, UserScriptMessageTest* test) + { + g_signal_handlers_disconnect_by_func(userContentManager, reinterpret_cast<gpointer>(scriptMessageReceived), test); + g_main_loop_quit(test->m_mainLoop); + + g_assert(!test->m_userScriptMessage); + test->m_userScriptMessage = webkit_javascript_result_ref(jsResult); + } + + WebKitJavascriptResult* waitUntilMessageReceived(const char* handlerName) + { + if (m_userScriptMessage) { + webkit_javascript_result_unref(m_userScriptMessage); + m_userScriptMessage = nullptr; + } + + GUniquePtr<char> signalName(g_strdup_printf("script-message-received::%s", handlerName)); + g_signal_connect(m_userContentManager.get(), signalName.get(), G_CALLBACK(scriptMessageReceived), this); + + g_main_loop_run(m_mainLoop); + g_assert(m_userScriptMessage); + return m_userScriptMessage; + } + + WebKitJavascriptResult* postMessageAndWaitUntilReceived(const char* handlerName, const char* javascriptValueAsText) + { + GUniquePtr<char> javascriptSnippet(g_strdup_printf("window.webkit.messageHandlers.%s.postMessage(%s);", handlerName, javascriptValueAsText)); + webkit_web_view_run_javascript(m_webView, javascriptSnippet.get(), nullptr, nullptr, nullptr); + return waitUntilMessageReceived(handlerName); + } + +private: + WebKitJavascriptResult* m_userScriptMessage; +}; + +static void testUserContentManagerScriptMessageReceived(UserScriptMessageTest* test, gconstpointer) +{ + g_assert(test->registerHandler("msg")); + + // Trying to register the same handler a second time must fail. + g_assert(!test->registerHandler("msg")); + + test->loadHtml("<html></html>", nullptr); + test->waitUntilLoadFinished(); + + // Check that the "window.webkit.messageHandlers" namespace exists. + GUniqueOutPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers ? 'y' : 'n';", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "y"); + + // Check that the "document.webkit.messageHandlers.msg" namespace exists. + javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg ? 'y' : 'n';", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "y"); + + valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'user message'"))); + g_assert_cmpstr(valueString.get(), ==, "user message"); + + // Messages should arrive despite of other handlers being registered. + g_assert(test->registerHandler("anotherHandler")); + + // Check that the "document.webkit.messageHandlers.msg" namespace still exists. + javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg ? 'y' : 'n';", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "y"); + + // Check that the "document.webkit.messageHandlers.anotherHandler" namespace exists. + javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.anotherHandler ? 'y' : 'n';", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "y"); + + valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'handler: msg'"))); + g_assert_cmpstr(valueString.get(), ==, "handler: msg"); + + valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("anotherHandler", "'handler: anotherHandler'"))); + g_assert_cmpstr(valueString.get(), ==, "handler: anotherHandler"); + + // Unregistering a handler and re-registering again under the same name should work. + test->unregisterHandler("msg"); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg.postMessage('42');", &error.outPtr()); + g_assert(!javascriptResult); + g_assert(error.get()); + + // Re-registering a handler that has been unregistered must work + g_assert(test->registerHandler("msg")); + valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'handler: msg'"))); + g_assert_cmpstr(valueString.get(), ==, "handler: msg"); + + test->unregisterHandler("anotherHandler"); +} + +static void testUserContentManagerScriptMessageFromDOMBindings(UserScriptMessageTest* test, gconstpointer) +{ + g_assert(test->registerHandler("dom")); + + test->loadHtml("<html>1</html>", nullptr); + WebKitJavascriptResult* javascriptResult = test->waitUntilMessageReceived("dom"); + g_assert(javascriptResult); + GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "DocumentLoaded"); + + test->unregisterHandler("dom"); + + g_assert(test->registerHandler("dom-convenience")); + + test->loadHtml("<html>2</html>", nullptr); + javascriptResult = test->waitUntilMessageReceived("dom-convenience"); + g_assert(javascriptResult); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "DocumentLoaded"); + + test->unregisterHandler("dom-convenience"); +} + +static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kStyleSheetHTML, strlen(kStyleSheetHTML)); + soup_message_body_complete(message->response_body); +} + +void beforeAll() +{ + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + + Test::add("WebKitWebView", "new-with-user-content-manager", testWebViewNewWithUserContentManager); + UserContentManagerTest::add("WebKitUserContentManager", "injected-style-sheet", testUserContentManagerInjectedStyleSheet); + UserContentManagerTest::add("WebKitUserContentManager", "injected-script", testUserContentManagerInjectedScript); + UserScriptMessageTest::add("WebKitUserContentManager", "script-message-received", testUserContentManagerScriptMessageReceived); + UserScriptMessageTest::add("WebKitUserContentManager", "script-message-from-dom-bindings", testUserContentManagerScriptMessageFromDOMBindings); +} + +void afterAll() +{ + delete kServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitVersion.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitVersion.cpp new file mode 100644 index 000000000..e747ff962 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitVersion.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "TestMain.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> + + +static void testWebKitVersion(Test*, gconstpointer) +{ + g_assert_cmpuint(webkit_get_major_version(), ==, WEBKIT_MAJOR_VERSION); + g_assert_cmpuint(webkit_get_minor_version(), ==, WEBKIT_MINOR_VERSION); + g_assert_cmpuint(webkit_get_micro_version(), ==, WEBKIT_MICRO_VERSION); +} + +static void testWebKitCheckVersion(Test*, gconstpointer) +{ + g_assert(WEBKIT_CHECK_VERSION(WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION)); + g_assert(!WEBKIT_CHECK_VERSION(WEBKIT_MAJOR_VERSION + 1, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION)); + g_assert(!WEBKIT_CHECK_VERSION(WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION + 1, WEBKIT_MICRO_VERSION)); + g_assert(!WEBKIT_CHECK_VERSION(WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION + 1)); +} + +void beforeAll() +{ + Test::add("WebKitVersion", "version", testWebKitVersion); + Test::add("WebKitVersion", "check-version", testWebKitCheckVersion); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp new file mode 100644 index 000000000..2d1d216f4 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp @@ -0,0 +1,655 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "LoadTrackingTest.h" +#include "WebKitTestServer.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> +#include <wtf/HashMap.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> +#include <wtf/text/StringBuilder.h> +#include <wtf/text/StringHash.h> + +static WebKitTestServer* kServer; + +static void testWebContextDefault(Test* test, gconstpointer) +{ + // Check there's a single instance of the default web context. + g_assert(webkit_web_context_get_default() == webkit_web_context_get_default()); + g_assert(webkit_web_context_get_default() != test->m_webContext.get()); +} + +static void testWebContextConfiguration(WebViewTest* test, gconstpointer) +{ + WebKitWebsiteDataManager* manager = webkit_web_context_get_website_data_manager(test->m_webContext.get()); + g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(manager)); + + // Base directories are not used by TestMain. + g_assert(!webkit_website_data_manager_get_base_data_directory(manager)); + g_assert(!webkit_website_data_manager_get_base_cache_directory(manager)); + + GUniquePtr<char> localStorageDirectory(g_build_filename(Test::dataDirectory(), "local-storage", nullptr)); + g_assert_cmpstr(localStorageDirectory.get(), ==, webkit_website_data_manager_get_local_storage_directory(manager)); + g_assert(g_file_test(localStorageDirectory.get(), G_FILE_TEST_IS_DIR)); + + test->loadURI(kServer->getURIForPath("/empty").data()); + test->waitUntilLoadFinished(); + test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');", nullptr); + GUniquePtr<char> indexedDBDirectory(g_build_filename(Test::dataDirectory(), "indexeddb", nullptr)); + g_assert_cmpstr(indexedDBDirectory.get(), ==, webkit_website_data_manager_get_indexeddb_directory(manager)); + g_assert(g_file_test(indexedDBDirectory.get(), G_FILE_TEST_IS_DIR)); + + test->loadURI(kServer->getURIForPath("/appcache").data()); + test->waitUntilLoadFinished(); + GUniquePtr<char> applicationCacheDirectory(g_build_filename(Test::dataDirectory(), "appcache", nullptr)); + g_assert_cmpstr(applicationCacheDirectory.get(), ==, webkit_website_data_manager_get_offline_application_cache_directory(manager)); + GUniquePtr<char> applicationCacheDatabase(g_build_filename(applicationCacheDirectory.get(), "ApplicationCache.db", nullptr)); + unsigned triesCount = 4; + while (!g_file_test(applicationCacheDatabase.get(), G_FILE_TEST_IS_REGULAR) && --triesCount) + test->wait(0.25); + g_assert(triesCount); + + + GUniquePtr<char> webSQLDirectory(g_build_filename(Test::dataDirectory(), "websql", nullptr)); + g_assert_cmpstr(webSQLDirectory.get(), ==, webkit_website_data_manager_get_websql_directory(manager)); + test->runJavaScriptAndWaitUntilFinished("db = openDatabase(\"TestDatabase\", \"1.0\", \"TestDatabase\", 1);", nullptr); + g_assert(g_file_test(webSQLDirectory.get(), G_FILE_TEST_IS_DIR)); + + GUniquePtr<char> diskCacheDirectory(g_build_filename(Test::dataDirectory(), "disk-cache", nullptr)); + g_assert_cmpstr(diskCacheDirectory.get(), ==, webkit_website_data_manager_get_disk_cache_directory(manager)); + g_assert(g_file_test(diskCacheDirectory.get(), G_FILE_TEST_IS_DIR)); + + // The default context should have a different manager with different configuration. + WebKitWebsiteDataManager* defaultManager = webkit_web_context_get_website_data_manager(webkit_web_context_get_default()); + g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(defaultManager)); + g_assert(manager != defaultManager); + g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(manager), !=, webkit_website_data_manager_get_local_storage_directory(defaultManager)); + g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(manager), !=, webkit_website_data_manager_get_indexeddb_directory(defaultManager)); + g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(manager), !=, webkit_website_data_manager_get_disk_cache_directory(defaultManager)); + g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(manager), !=, webkit_website_data_manager_get_offline_application_cache_directory(defaultManager)); + g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(manager), !=, webkit_website_data_manager_get_websql_directory(defaultManager)); + + // Using Test::dataDirectory() we get the default configuration but for a differrent prefix. + GRefPtr<WebKitWebsiteDataManager> baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(), nullptr)); + g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(baseDataManager.get())); + + localStorageDirectory.reset(g_build_filename(Test::dataDirectory(), "localstorage", nullptr)); + g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get()); + + indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "databases", "indexeddb", nullptr)); + g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get()); + + applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "applications", nullptr)); + g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get()); + + webSQLDirectory.reset(g_build_filename(Test::dataDirectory(), "databases", nullptr)); + g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get()); + + g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory()); + + // Any specific configuration provided takes precedence over base dirs. + indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomindexeddb", nullptr)); + applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomappcache", nullptr)); + baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(), + "indexeddb-directory", indexedDBDirectory.get(), "offline-application-cache-directory", applicationCacheDirectory.get(), nullptr)); + g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get()); + g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get()); + // The resutl should be the same as previous manager. + g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get()); + g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get()); + g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory()); +} + +class PluginsTest: public Test { +public: + MAKE_GLIB_TEST_FIXTURE(PluginsTest); + + PluginsTest() + : m_mainLoop(g_main_loop_new(nullptr, TRUE)) + , m_plugins(nullptr) + { + webkit_web_context_set_additional_plugins_directory(m_webContext.get(), WEBKIT_TEST_PLUGIN_DIR); + } + + ~PluginsTest() + { + g_main_loop_unref(m_mainLoop); + g_list_free_full(m_plugins, g_object_unref); + } + + static void getPluginsAsyncReadyCallback(GObject*, GAsyncResult* result, PluginsTest* test) + { + test->m_plugins = webkit_web_context_get_plugins_finish(test->m_webContext.get(), result, nullptr); + g_main_loop_quit(test->m_mainLoop); + } + + GList* getPlugins() + { + g_list_free_full(m_plugins, g_object_unref); + webkit_web_context_get_plugins(m_webContext.get(), nullptr, reinterpret_cast<GAsyncReadyCallback>(getPluginsAsyncReadyCallback), this); + g_main_loop_run(m_mainLoop); + return m_plugins; + } + + GMainLoop* m_mainLoop; + GList* m_plugins; +}; + +static void testWebContextGetPlugins(PluginsTest* test, gconstpointer) +{ + GList* plugins = test->getPlugins(); + g_assert(plugins); + + GRefPtr<WebKitPlugin> testPlugin; + for (GList* item = plugins; item; item = g_list_next(item)) { + WebKitPlugin* plugin = WEBKIT_PLUGIN(item->data); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(plugin)); + if (!g_strcmp0(webkit_plugin_get_name(plugin), "WebKit Test PlugIn")) { + testPlugin = plugin; + break; + } + } + g_assert(WEBKIT_IS_PLUGIN(testPlugin.get())); + + GUniquePtr<char> pluginPath(g_build_filename(WEBKIT_TEST_PLUGIN_DIR, "libTestNetscapePlugin.so", nullptr)); + g_assert_cmpstr(webkit_plugin_get_path(testPlugin.get()), ==, pluginPath.get()); + g_assert_cmpstr(webkit_plugin_get_description(testPlugin.get()), ==, "Simple Netscape® plug-in that handles test content for WebKit"); + GList* mimeInfoList = webkit_plugin_get_mime_info_list(testPlugin.get()); + g_assert(mimeInfoList); + g_assert_cmpuint(g_list_length(mimeInfoList), ==, 2); + + WebKitMimeInfo* mimeInfo = static_cast<WebKitMimeInfo*>(mimeInfoList->data); + g_assert_cmpstr(webkit_mime_info_get_mime_type(mimeInfo), ==, "image/png"); + g_assert_cmpstr(webkit_mime_info_get_description(mimeInfo), ==, "png image"); + const gchar* const* extensions = webkit_mime_info_get_extensions(mimeInfo); + g_assert(extensions); + g_assert_cmpstr(extensions[0], ==, "png"); + + mimeInfoList = g_list_next(mimeInfoList); + mimeInfo = static_cast<WebKitMimeInfo*>(mimeInfoList->data); + g_assert_cmpstr(webkit_mime_info_get_mime_type(mimeInfo), ==, "application/x-webkit-test-netscape"); + g_assert_cmpstr(webkit_mime_info_get_description(mimeInfo), ==, "test netscape content"); + extensions = webkit_mime_info_get_extensions(mimeInfo); + g_assert(extensions); + g_assert_cmpstr(extensions[0], ==, "testnetscape"); +} + +static const char* kBarHTML = "<html><body>Bar</body></html>"; +static const char* kEchoHTMLFormat = "<html><body>%s</body></html>"; +static const char* errorDomain = "test"; +static const int errorCode = 10; + +static const char* genericErrorMessage = "Error message."; +static const char* beforeReceiveResponseErrorMessage = "Error before didReceiveResponse."; +static const char* afterInitialChunkErrorMessage = "Error after reading the initial chunk."; + +class URISchemeTest: public LoadTrackingTest { +public: + MAKE_GLIB_TEST_FIXTURE(URISchemeTest); + + struct URISchemeHandler { + URISchemeHandler() + : replyLength(0) + { + } + + URISchemeHandler(const char* reply, int replyLength, const char* mimeType) + : reply(reply) + , replyLength(replyLength) + , mimeType(mimeType) + { + } + + CString reply; + int replyLength; + CString mimeType; + }; + + static void uriSchemeRequestCallback(WebKitURISchemeRequest* request, gpointer userData) + { + URISchemeTest* test = static_cast<URISchemeTest*>(userData); + test->m_uriSchemeRequest = request; + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + + g_assert(webkit_uri_scheme_request_get_web_view(request) == test->m_webView); + + const char* scheme = webkit_uri_scheme_request_get_scheme(request); + g_assert(scheme); + g_assert(test->m_handlersMap.contains(String::fromUTF8(scheme))); + + const URISchemeHandler& handler = test->m_handlersMap.get(String::fromUTF8(scheme)); + + GRefPtr<GInputStream> inputStream = adoptGRef(g_memory_input_stream_new()); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(inputStream.get())); + + const gchar* requestPath = webkit_uri_scheme_request_get_path(request); + + if (!g_strcmp0(scheme, "error")) { + if (!g_strcmp0(requestPath, "before-response")) { + GUniquePtr<GError> error(g_error_new_literal(g_quark_from_string(errorDomain), errorCode, beforeReceiveResponseErrorMessage)); + // We call finish() and then finish_error() to make sure that not even + // the didReceiveResponse message is processed at the time of failing. + webkit_uri_scheme_request_finish(request, G_INPUT_STREAM(inputStream.get()), handler.replyLength, handler.mimeType.data()); + webkit_uri_scheme_request_finish_error(request, error.get()); + } else if (!g_strcmp0(requestPath, "after-first-chunk")) { + g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(inputStream.get()), handler.reply.data(), handler.reply.length(), 0); + webkit_uri_scheme_request_finish(request, inputStream.get(), handler.replyLength, handler.mimeType.data()); + // We need to wait until we reach the load-committed state before calling webkit_uri_scheme_request_finish_error(), + // so we rely on the test using finishOnCommittedAndWaitUntilLoadFinished() to actually call it from loadCommitted(). + } else { + GUniquePtr<GError> error(g_error_new_literal(g_quark_from_string(errorDomain), errorCode, genericErrorMessage)); + webkit_uri_scheme_request_finish_error(request, error.get()); + } + return; + } + + if (!g_strcmp0(scheme, "echo")) { + char* replyHTML = g_strdup_printf(handler.reply.data(), requestPath); + g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(inputStream.get()), replyHTML, strlen(replyHTML), g_free); + } else if (!g_strcmp0(scheme, "closed")) + g_input_stream_close(inputStream.get(), 0, 0); + else if (!handler.reply.isNull()) + g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(inputStream.get()), handler.reply.data(), handler.reply.length(), 0); + + webkit_uri_scheme_request_finish(request, inputStream.get(), handler.replyLength, handler.mimeType.data()); + } + + void registerURISchemeHandler(const char* scheme, const char* reply, int replyLength, const char* mimeType) + { + m_handlersMap.set(String::fromUTF8(scheme), URISchemeHandler(reply, replyLength, mimeType)); + webkit_web_context_register_uri_scheme(m_webContext.get(), scheme, uriSchemeRequestCallback, this, 0); + } + + virtual void loadCommitted() override + { + if (m_finishOnCommitted) { + GUniquePtr<GError> error(g_error_new_literal(g_quark_from_string(errorDomain), errorCode, afterInitialChunkErrorMessage)); + webkit_uri_scheme_request_finish_error(m_uriSchemeRequest.get(), error.get()); + } + + LoadTrackingTest::loadCommitted(); + } + + void finishOnCommittedAndWaitUntilLoadFinished() + { + m_finishOnCommitted = true; + waitUntilLoadFinished(); + m_finishOnCommitted = false; + } + + GRefPtr<WebKitURISchemeRequest> m_uriSchemeRequest; + HashMap<String, URISchemeHandler> m_handlersMap; + bool m_finishOnCommitted { false }; +}; + +String generateHTMLContent(unsigned contentLength) +{ + String baseString("abcdefghijklmnopqrstuvwxyz0123457890"); + unsigned baseLength = baseString.length(); + + StringBuilder builder; + builder.append("<html><body>"); + + if (contentLength <= baseLength) + builder.append(baseString, 0, contentLength); + else { + unsigned currentLength = 0; + while (currentLength < contentLength) { + if ((currentLength + baseLength) <= contentLength) + builder.append(baseString); + else + builder.append(baseString, 0, contentLength - currentLength); + + // Account for the 12 characters of the '<html><body>' prefix. + currentLength = builder.length() - 12; + } + } + builder.append("</body></html>"); + + return builder.toString(); +} + +static void testWebContextURIScheme(URISchemeTest* test, gconstpointer) +{ + test->registerURISchemeHandler("foo", kBarHTML, strlen(kBarHTML), "text/html"); + test->loadURI("foo:blank"); + test->waitUntilLoadFinished(); + size_t mainResourceDataSize = 0; + const char* mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpint(mainResourceDataSize, ==, strlen(kBarHTML)); + g_assert(!strncmp(mainResourceData, kBarHTML, mainResourceDataSize)); + + test->registerURISchemeHandler("echo", kEchoHTMLFormat, -1, "text/html"); + test->loadURI("echo:hello-world"); + test->waitUntilLoadFinished(); + GUniquePtr<char> echoHTML(g_strdup_printf(kEchoHTMLFormat, webkit_uri_scheme_request_get_path(test->m_uriSchemeRequest.get()))); + mainResourceDataSize = 0; + mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpint(mainResourceDataSize, ==, strlen(echoHTML.get())); + g_assert(!strncmp(mainResourceData, echoHTML.get(), mainResourceDataSize)); + + test->loadURI("echo:with#fragment"); + test->waitUntilLoadFinished(); + g_assert_cmpstr(webkit_uri_scheme_request_get_path(test->m_uriSchemeRequest.get()), ==, "with"); + g_assert_cmpstr(webkit_uri_scheme_request_get_uri(test->m_uriSchemeRequest.get()), ==, "echo:with#fragment"); + echoHTML.reset(g_strdup_printf(kEchoHTMLFormat, webkit_uri_scheme_request_get_path(test->m_uriSchemeRequest.get()))); + mainResourceDataSize = 0; + mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpint(mainResourceDataSize, ==, strlen(echoHTML.get())); + g_assert(!strncmp(mainResourceData, echoHTML.get(), mainResourceDataSize)); + + test->registerURISchemeHandler("nomime", kBarHTML, -1, 0); + test->m_loadEvents.clear(); + test->loadURI("nomime:foo-bar"); + test->waitUntilLoadFinished(); + g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + + test->registerURISchemeHandler("empty", 0, 0, "text/html"); + test->m_loadEvents.clear(); + test->loadURI("empty:nothing"); + test->waitUntilLoadFinished(); + g_assert(!test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadFailed)); + + // Anything over 8192 bytes will get multiple calls to g_input_stream_read_async in + // WebKitURISchemeRequest when reading data, but we still need way more than that to + // ensure that we reach the load-committed state before failing, so we use an 8MB HTML. + String longHTMLContent = generateHTMLContent(8 * 1024 * 1024); + test->registerURISchemeHandler("error", longHTMLContent.utf8().data(), -1, "text/html"); + test->m_loadEvents.clear(); + test->loadURI("error:error"); + test->waitUntilLoadFinished(); + g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + g_assert(test->m_loadFailed); + g_assert_error(test->m_error.get(), g_quark_from_string(errorDomain), errorCode); + g_assert_cmpstr(test->m_error->message, ==, genericErrorMessage); + + test->m_loadEvents.clear(); + test->loadURI("error:before-response"); + test->waitUntilLoadFinished(); + g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + g_assert(test->m_loadFailed); + g_assert_error(test->m_error.get(), g_quark_from_string(errorDomain), errorCode); + g_assert_cmpstr(test->m_error->message, ==, beforeReceiveResponseErrorMessage); + + test->m_loadEvents.clear(); + test->loadURI("error:after-first-chunk"); + test->finishOnCommittedAndWaitUntilLoadFinished(); + g_assert(!test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + g_assert(test->m_loadEvents.contains(LoadTrackingTest::LoadFailed)); + g_assert(test->m_loadFailed); + g_assert_error(test->m_error.get(), g_quark_from_string(errorDomain), errorCode); + g_assert_cmpstr(test->m_error->message, ==, afterInitialChunkErrorMessage); + + test->registerURISchemeHandler("closed", 0, 0, 0); + test->m_loadEvents.clear(); + test->loadURI("closed:input-stream"); + test->waitUntilLoadFinished(); + g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); + g_assert(test->m_loadFailed); + g_assert_error(test->m_error.get(), G_IO_ERROR, G_IO_ERROR_CLOSED); +} + +static void testWebContextSpellChecker(Test* test, gconstpointer) +{ + WebKitWebContext* webContext = test->m_webContext.get(); + + // Check what happens if no spell checking language has been set. + const gchar* const* currentLanguage = webkit_web_context_get_spell_checking_languages(webContext); + g_assert(!currentLanguage); + + // Set the language to a specific one. + GRefPtr<GPtrArray> languages = adoptGRef(g_ptr_array_new()); + g_ptr_array_add(languages.get(), const_cast<gpointer>(static_cast<const void*>("en_US"))); + g_ptr_array_add(languages.get(), 0); + webkit_web_context_set_spell_checking_languages(webContext, reinterpret_cast<const char* const*>(languages->pdata)); + currentLanguage = webkit_web_context_get_spell_checking_languages(webContext); + g_assert_cmpuint(g_strv_length(const_cast<char**>(currentLanguage)), ==, 1); + g_assert_cmpstr(currentLanguage[0], ==, "en_US"); + + // Set the language string to list of valid languages. + g_ptr_array_remove_index_fast(languages.get(), languages->len - 1); + g_ptr_array_add(languages.get(), const_cast<gpointer>(static_cast<const void*>("en_GB"))); + g_ptr_array_add(languages.get(), 0); + webkit_web_context_set_spell_checking_languages(webContext, reinterpret_cast<const char* const*>(languages->pdata)); + currentLanguage = webkit_web_context_get_spell_checking_languages(webContext); + g_assert_cmpuint(g_strv_length(const_cast<char**>(currentLanguage)), ==, 2); + g_assert_cmpstr(currentLanguage[0], ==, "en_US"); + g_assert_cmpstr(currentLanguage[1], ==, "en_GB"); + + // Try passing a wrong language along with good ones. + g_ptr_array_remove_index_fast(languages.get(), languages->len - 1); + g_ptr_array_add(languages.get(), const_cast<gpointer>(static_cast<const void*>("bd_WR"))); + g_ptr_array_add(languages.get(), 0); + webkit_web_context_set_spell_checking_languages(webContext, reinterpret_cast<const char* const*>(languages->pdata)); + currentLanguage = webkit_web_context_get_spell_checking_languages(webContext); + g_assert_cmpuint(g_strv_length(const_cast<char**>(currentLanguage)), ==, 2); + g_assert_cmpstr(currentLanguage[0], ==, "en_US"); + g_assert_cmpstr(currentLanguage[1], ==, "en_GB"); + + // Try passing a list with only wrong languages. + languages = adoptGRef(g_ptr_array_new()); + g_ptr_array_add(languages.get(), const_cast<gpointer>(static_cast<const void*>("bd_WR"))); + g_ptr_array_add(languages.get(), const_cast<gpointer>(static_cast<const void*>("wr_BD"))); + g_ptr_array_add(languages.get(), 0); + webkit_web_context_set_spell_checking_languages(webContext, reinterpret_cast<const char* const*>(languages->pdata)); + currentLanguage = webkit_web_context_get_spell_checking_languages(webContext); + g_assert(!currentLanguage); + + // Check disabling and re-enabling spell checking. + webkit_web_context_set_spell_checking_enabled(webContext, FALSE); + g_assert(!webkit_web_context_get_spell_checking_enabled(webContext)); + webkit_web_context_set_spell_checking_enabled(webContext, TRUE); + g_assert(webkit_web_context_get_spell_checking_enabled(webContext)); +} + +static void testWebContextLanguages(WebViewTest* test, gconstpointer) +{ + static const char* expectedDefaultLanguage = "en"; + test->loadURI(kServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + size_t mainResourceDataSize = 0; + const char* mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpuint(mainResourceDataSize, ==, strlen(expectedDefaultLanguage)); + g_assert(!strncmp(mainResourceData, expectedDefaultLanguage, mainResourceDataSize)); + + GRefPtr<GPtrArray> languages = adoptGRef(g_ptr_array_new()); + g_ptr_array_add(languages.get(), const_cast<gpointer>(static_cast<const void*>("en"))); + g_ptr_array_add(languages.get(), const_cast<gpointer>(static_cast<const void*>("ES_es"))); + g_ptr_array_add(languages.get(), const_cast<gpointer>(static_cast<const void*>("dE"))); + g_ptr_array_add(languages.get(), 0); + webkit_web_context_set_preferred_languages(test->m_webContext.get(), reinterpret_cast<const char* const*>(languages->pdata)); + + static const char* expectedLanguages = "en, es-es;q=0.90, de;q=0.80"; + test->loadURI(kServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + mainResourceDataSize = 0; + mainResourceData = test->mainResourceData(mainResourceDataSize); + g_assert_cmpuint(mainResourceDataSize, ==, strlen(expectedLanguages)); + g_assert(!strncmp(mainResourceData, expectedLanguages, mainResourceDataSize)); +} + +static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + if (g_str_equal(path, "/")) { + const char* acceptLanguage = soup_message_headers_get_one(message->request_headers, "Accept-Language"); + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, acceptLanguage, strlen(acceptLanguage)); + soup_message_body_complete(message->response_body); + } else if (g_str_equal(path, "/empty")) { + const char* emptyHTML = "<html><body></body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, emptyHTML, strlen(emptyHTML)); + soup_message_body_complete(message->response_body); + soup_message_set_status(message, SOUP_STATUS_OK); + } else if (g_str_equal(path, "/appcache")) { + const char* appcacheHTML = "<html manifest=appcache.manifest><body></body></html>"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheHTML, strlen(appcacheHTML)); + soup_message_body_complete(message->response_body); + soup_message_set_status(message, SOUP_STATUS_OK); + } else if (g_str_equal(path, "/appcache.manifest")) { + const char* appcacheManifest = "CACHE MANIFEST\nCACHE:\nappcache/foo.txt\n"; + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheManifest, strlen(appcacheManifest)); + soup_message_body_complete(message->response_body); + soup_message_set_status(message, SOUP_STATUS_OK); + } else if (g_str_equal(path, "/appcache/foo.txt")) { + soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, "foo", 3); + soup_message_body_complete(message->response_body); + soup_message_set_status(message, SOUP_STATUS_OK); + } else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); +} + +class SecurityPolicyTest: public Test { +public: + MAKE_GLIB_TEST_FIXTURE(SecurityPolicyTest); + + enum SecurityPolicy { + Local = 1 << 1, + NoAccess = 1 << 2, + DisplayIsolated = 1 << 3, + Secure = 1 << 4, + CORSEnabled = 1 << 5, + EmptyDocument = 1 << 6 + }; + + SecurityPolicyTest() + : m_manager(webkit_web_context_get_security_manager(m_webContext.get())) + { + } + + void verifyThatSchemeMatchesPolicy(const char* scheme, unsigned policy) + { + if (policy & Local) + g_assert(webkit_security_manager_uri_scheme_is_local(m_manager, scheme)); + else + g_assert(!webkit_security_manager_uri_scheme_is_local(m_manager, scheme)); + if (policy & NoAccess) + g_assert(webkit_security_manager_uri_scheme_is_no_access(m_manager, scheme)); + else + g_assert(!webkit_security_manager_uri_scheme_is_no_access(m_manager, scheme)); + if (policy & DisplayIsolated) + g_assert(webkit_security_manager_uri_scheme_is_display_isolated(m_manager, scheme)); + else + g_assert(!webkit_security_manager_uri_scheme_is_display_isolated(m_manager, scheme)); + if (policy & Secure) + g_assert(webkit_security_manager_uri_scheme_is_secure(m_manager, scheme)); + else + g_assert(!webkit_security_manager_uri_scheme_is_secure(m_manager, scheme)); + if (policy & CORSEnabled) + g_assert(webkit_security_manager_uri_scheme_is_cors_enabled(m_manager, scheme)); + else + g_assert(!webkit_security_manager_uri_scheme_is_cors_enabled(m_manager, scheme)); + if (policy & EmptyDocument) + g_assert(webkit_security_manager_uri_scheme_is_empty_document(m_manager, scheme)); + else + g_assert(!webkit_security_manager_uri_scheme_is_empty_document(m_manager, scheme)); + } + + WebKitSecurityManager* m_manager; +}; + +static void testWebContextSecurityPolicy(SecurityPolicyTest* test, gconstpointer) +{ + // VerifyThatSchemeMatchesPolicy default policy for well known schemes. + test->verifyThatSchemeMatchesPolicy("http", SecurityPolicyTest::CORSEnabled); + test->verifyThatSchemeMatchesPolicy("https", SecurityPolicyTest::CORSEnabled | SecurityPolicyTest::Secure); + test->verifyThatSchemeMatchesPolicy("file", SecurityPolicyTest::Local); + test->verifyThatSchemeMatchesPolicy("data", SecurityPolicyTest::NoAccess | SecurityPolicyTest::Secure); + test->verifyThatSchemeMatchesPolicy("about", SecurityPolicyTest::NoAccess | SecurityPolicyTest::Secure | SecurityPolicyTest::EmptyDocument); + + // Custom scheme. + test->verifyThatSchemeMatchesPolicy("foo", 0); + + webkit_security_manager_register_uri_scheme_as_local(test->m_manager, "foo"); + test->verifyThatSchemeMatchesPolicy("foo", SecurityPolicyTest::Local); + webkit_security_manager_register_uri_scheme_as_no_access(test->m_manager, "foo"); + test->verifyThatSchemeMatchesPolicy("foo", SecurityPolicyTest::Local | SecurityPolicyTest::NoAccess); + webkit_security_manager_register_uri_scheme_as_display_isolated(test->m_manager, "foo"); + test->verifyThatSchemeMatchesPolicy("foo", SecurityPolicyTest::Local | SecurityPolicyTest::NoAccess | SecurityPolicyTest::DisplayIsolated); + webkit_security_manager_register_uri_scheme_as_secure(test->m_manager, "foo"); + test->verifyThatSchemeMatchesPolicy("foo", SecurityPolicyTest::Local | SecurityPolicyTest::NoAccess | SecurityPolicyTest::DisplayIsolated | SecurityPolicyTest::Secure); + webkit_security_manager_register_uri_scheme_as_cors_enabled(test->m_manager, "foo"); + test->verifyThatSchemeMatchesPolicy("foo", SecurityPolicyTest::Local | SecurityPolicyTest::NoAccess | SecurityPolicyTest::DisplayIsolated | SecurityPolicyTest::Secure + | SecurityPolicyTest::CORSEnabled); + webkit_security_manager_register_uri_scheme_as_empty_document(test->m_manager, "foo"); + test->verifyThatSchemeMatchesPolicy("foo", SecurityPolicyTest::Local | SecurityPolicyTest::NoAccess | SecurityPolicyTest::DisplayIsolated | SecurityPolicyTest::Secure + | SecurityPolicyTest::CORSEnabled | SecurityPolicyTest::EmptyDocument); +} + +static void testWebContextSecurityFileXHR(WebViewTest* test, gconstpointer) +{ + GUniquePtr<char> fileURL(g_strdup_printf("file://%s/simple.html", Test::getResourcesDir(Test::WebKit2Resources).data())); + test->loadURI(fileURL.get()); + test->waitUntilLoadFinished(); + + GUniquePtr<char> jsonURL(g_strdup_printf("file://%s/simple.json", Test::getResourcesDir().data())); + GUniquePtr<char> xhr(g_strdup_printf("var xhr = new XMLHttpRequest; xhr.open(\"GET\", \"%s\"); xhr.send();", jsonURL.get())); + + // By default file access is not allowed, this will fail with a cross-origin error. + GUniqueOutPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished(xhr.get(), &error.outPtr()); + g_assert(!javascriptResult); + g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED); + + // Allow file access from file URLs. + webkit_settings_set_allow_file_access_from_file_urls(webkit_web_view_get_settings(test->m_webView), TRUE); + test->loadURI(fileURL.get()); + test->waitUntilLoadFinished(); + javascriptResult = test->runJavaScriptAndWaitUntilFinished(xhr.get(), &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error); + + // It isn't still possible to load file from an HTTP URL. + test->loadURI(kServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + javascriptResult = test->runJavaScriptAndWaitUntilFinished(xhr.get(), &error.outPtr()); + g_assert(!javascriptResult); + g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED); + + webkit_settings_set_allow_file_access_from_file_urls(webkit_web_view_get_settings(test->m_webView), FALSE); +} + +void beforeAll() +{ + kServer = new WebKitTestServer(); + kServer->run(serverCallback); + + Test::add("WebKitWebContext", "default-context", testWebContextDefault); + WebViewTest::add("WebKitWebContext", "configuration", testWebContextConfiguration); + PluginsTest::add("WebKitWebContext", "get-plugins", testWebContextGetPlugins); + URISchemeTest::add("WebKitWebContext", "uri-scheme", testWebContextURIScheme); + Test::add("WebKitWebContext", "spell-checker", testWebContextSpellChecker); + WebViewTest::add("WebKitWebContext", "languages", testWebContextLanguages); + SecurityPolicyTest::add("WebKitSecurityManager", "security-policy", testWebContextSecurityPolicy); + WebViewTest::add("WebKitSecurityManager", "file-xhr", testWebContextSecurityFileXHR); +} + +void afterAll() +{ + delete kServer; +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebView.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebView.cpp new file mode 100644 index 000000000..9248097ab --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebView.cpp @@ -0,0 +1,894 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * Copyright (C) 2014 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitTestServer.h" +#include "WebViewTest.h" +#include <JavaScriptCore/JSStringRef.h> +#include <JavaScriptCore/JSValueRef.h> +#include <glib/gstdio.h> +#include <wtf/glib/GRefPtr.h> + +class IsPlayingAudioWebViewTest : public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(IsPlayingAudioWebViewTest); + + static void isPlayingAudioChanged(GObject*, GParamSpec*, IsPlayingAudioWebViewTest* test) + { + g_signal_handlers_disconnect_by_func(test->m_webView, reinterpret_cast<void*>(isPlayingAudioChanged), test); + g_main_loop_quit(test->m_mainLoop); + } + + void waitUntilIsPlayingAudioChanged() + { + g_signal_connect(m_webView, "notify::is-playing-audio", G_CALLBACK(isPlayingAudioChanged), this); + g_main_loop_run(m_mainLoop); + } +}; + +static WebKitTestServer* gServer; + +static void testWebViewWebContext(WebViewTest* test, gconstpointer) +{ + g_assert(webkit_web_view_get_context(test->m_webView) == test->m_webContext.get()); + g_assert(webkit_web_context_get_default() != test->m_webContext.get()); + + // Check that a web view created with g_object_new has the default context. + GRefPtr<WebKitWebView> webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, nullptr)); + g_assert(webkit_web_view_get_context(webView.get()) == webkit_web_context_get_default()); + + // Check that a web view created with a related view has the related view context. + webView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_related_view(test->m_webView)); + g_assert(webkit_web_view_get_context(webView.get()) == test->m_webContext.get()); + + // Check that a web context given as construct parameter is ignored if a related view is also provided. + webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, + "web-context", webkit_web_context_get_default(), "related-view", test->m_webView, nullptr)); + g_assert(webkit_web_view_get_context(webView.get()) == test->m_webContext.get()); +} + +static void testWebViewWebContextLifetime(WebViewTest* test, gconstpointer) +{ + WebKitWebContext* webContext = webkit_web_context_new(); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webContext)); + + GtkWidget* webView = webkit_web_view_new_with_context(webContext); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webView)); + + g_object_ref_sink(webView); + g_object_unref(webContext); + + // Check that the web view still has a valid context. + WebKitWebContext* tmpContext = webkit_web_view_get_context(WEBKIT_WEB_VIEW(webView)); + g_assert_true(WEBKIT_IS_WEB_CONTEXT(tmpContext)); + g_object_unref(webView); + + WebKitWebContext* webContext2 = webkit_web_context_new(); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webContext2)); + + GtkWidget* webView2 = webkit_web_view_new_with_context(webContext2); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webView2)); + + g_object_ref_sink(webView2); + g_object_unref(webView2); + + // Check that the context is still valid. + g_assert_true(WEBKIT_IS_WEB_CONTEXT(webContext2)); + g_object_unref(webContext2); +} + +static void testWebViewCustomCharset(WebViewTest* test, gconstpointer) +{ + test->loadURI(gServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + g_assert(!webkit_web_view_get_custom_charset(test->m_webView)); + webkit_web_view_set_custom_charset(test->m_webView, "utf8"); + // Changing the charset reloads the page, so wait until reloaded. + test->waitUntilLoadFinished(); + g_assert_cmpstr(webkit_web_view_get_custom_charset(test->m_webView), ==, "utf8"); + + // Go back to the default charset and wait until reloaded. + webkit_web_view_set_custom_charset(test->m_webView, nullptr); + test->waitUntilLoadFinished(); + g_assert(!webkit_web_view_get_custom_charset(test->m_webView)); +} + +static void testWebViewSettings(WebViewTest* test, gconstpointer) +{ + WebKitSettings* defaultSettings = webkit_web_view_get_settings(test->m_webView); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(defaultSettings)); + g_assert(defaultSettings); + g_assert(webkit_settings_get_enable_javascript(defaultSettings)); + + GRefPtr<WebKitSettings> newSettings = adoptGRef(webkit_settings_new()); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(newSettings.get())); + g_object_set(G_OBJECT(newSettings.get()), "enable-javascript", FALSE, NULL); + webkit_web_view_set_settings(test->m_webView, newSettings.get()); + + WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView); + g_assert(settings != defaultSettings); + g_assert(!webkit_settings_get_enable_javascript(settings)); + + GRefPtr<GtkWidget> webView2 = webkit_web_view_new(); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webView2.get())); + webkit_web_view_set_settings(WEBKIT_WEB_VIEW(webView2.get()), settings); + g_assert(webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webView2.get())) == settings); + + GRefPtr<WebKitSettings> newSettings2 = adoptGRef(webkit_settings_new()); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(newSettings2.get())); + webkit_web_view_set_settings(WEBKIT_WEB_VIEW(webView2.get()), newSettings2.get()); + settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webView2.get())); + g_assert(settings == newSettings2.get()); + g_assert(webkit_settings_get_enable_javascript(settings)); + + GRefPtr<GtkWidget> webView3 = webkit_web_view_new_with_settings(newSettings2.get()); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webView3.get())); + g_assert(webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webView3.get())) == newSettings2.get()); +} + +static void testWebViewZoomLevel(WebViewTest* test, gconstpointer) +{ + g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 1); + webkit_web_view_set_zoom_level(test->m_webView, 2.5); + g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 2.5); + + webkit_settings_set_zoom_text_only(webkit_web_view_get_settings(test->m_webView), TRUE); + // The zoom level shouldn't change when zoom-text-only setting changes. + g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 2.5); +} + +static void testWebViewRunJavaScript(WebViewTest* test, gconstpointer) +{ + static const char* html = "<html><body><a id='WebKitLink' href='http://www.webkitgtk.org/' title='WebKitGTK+ Title'>WebKitGTK+ Website</a></body></html>"; + test->loadHtml(html, 0); + test->waitUntilLoadFinished(); + + GUniqueOutPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').title;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "WebKitGTK+ Title"); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').href;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "http://www.webkitgtk.org/"); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').textContent", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "WebKitGTK+ Website"); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = 25;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 25); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = 2.5;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 2.5); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = true", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert(WebViewTest::javascriptResultToBoolean(javascriptResult)); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = false", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert(!WebViewTest::javascriptResultToBoolean(javascriptResult)); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = null", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert(WebViewTest::javascriptResultIsNull(javascriptResult)); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("function Foo() { a = 25; } Foo();", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert(WebViewTest::javascriptResultIsUndefined(javascriptResult)); + + javascriptResult = test->runJavaScriptFromGResourceAndWaitUntilFinished("/org/webkit/webkit2gtk/tests/link-title.js", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "WebKitGTK+ Title"); + + javascriptResult = test->runJavaScriptFromGResourceAndWaitUntilFinished("/wrong/path/to/resource.js", &error.outPtr()); + g_assert(!javascriptResult); + g_assert_error(error.get(), G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("foo();", &error.outPtr()); + g_assert(!javascriptResult); + g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED); +} + +class FullScreenClientTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(FullScreenClientTest); + + enum FullScreenEvent { + None, + Enter, + Leave + }; + + static gboolean viewEnterFullScreenCallback(WebKitWebView*, FullScreenClientTest* test) + { + test->m_event = Enter; + g_main_loop_quit(test->m_mainLoop); + return FALSE; + } + + static gboolean viewLeaveFullScreenCallback(WebKitWebView*, FullScreenClientTest* test) + { + test->m_event = Leave; + g_main_loop_quit(test->m_mainLoop); + return FALSE; + } + + FullScreenClientTest() + : m_event(None) + { + webkit_settings_set_enable_fullscreen(webkit_web_view_get_settings(m_webView), TRUE); + g_signal_connect(m_webView, "enter-fullscreen", G_CALLBACK(viewEnterFullScreenCallback), this); + g_signal_connect(m_webView, "leave-fullscreen", G_CALLBACK(viewLeaveFullScreenCallback), this); + } + + ~FullScreenClientTest() + { + g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + void requestFullScreenAndWaitUntilEnteredFullScreen() + { + m_event = None; + webkit_web_view_run_javascript(m_webView, "document.documentElement.webkitRequestFullScreen();", 0, 0, 0); + g_main_loop_run(m_mainLoop); + } + + static gboolean leaveFullScreenIdle(FullScreenClientTest* test) + { + test->keyStroke(GDK_KEY_Escape); + return FALSE; + } + + void leaveFullScreenAndWaitUntilLeftFullScreen() + { + m_event = None; + g_idle_add(reinterpret_cast<GSourceFunc>(leaveFullScreenIdle), this); + g_main_loop_run(m_mainLoop); + } + + FullScreenEvent m_event; +}; + +static void testWebViewFullScreen(FullScreenClientTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + test->loadHtml("<html><body>FullScreen test</body></html>", 0); + test->waitUntilLoadFinished(); + test->requestFullScreenAndWaitUntilEnteredFullScreen(); + g_assert_cmpint(test->m_event, ==, FullScreenClientTest::Enter); + test->leaveFullScreenAndWaitUntilLeftFullScreen(); + g_assert_cmpint(test->m_event, ==, FullScreenClientTest::Leave); +} + +static void testWebViewCanShowMIMEType(WebViewTest* test, gconstpointer) +{ + // Supported MIME types. + g_assert(webkit_web_view_can_show_mime_type(test->m_webView, "text/html")); + g_assert(webkit_web_view_can_show_mime_type(test->m_webView, "text/plain")); + g_assert(webkit_web_view_can_show_mime_type(test->m_webView, "image/jpeg")); + + // Unsupported MIME types. + g_assert(!webkit_web_view_can_show_mime_type(test->m_webView, "text/vcard")); + g_assert(!webkit_web_view_can_show_mime_type(test->m_webView, "application/zip")); + g_assert(!webkit_web_view_can_show_mime_type(test->m_webView, "application/octet-stream")); + + // Plugins are only supported when enabled. + webkit_web_context_set_additional_plugins_directory(webkit_web_view_get_context(test->m_webView), WEBKIT_TEST_PLUGIN_DIR); + g_assert(webkit_web_view_can_show_mime_type(test->m_webView, "application/x-webkit-test-netscape")); + webkit_settings_set_enable_plugins(webkit_web_view_get_settings(test->m_webView), FALSE); + g_assert(!webkit_web_view_can_show_mime_type(test->m_webView, "application/x-webkit-test-netscape")); +} + +class FormClientTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(FormClientTest); + + static void submitFormCallback(WebKitWebView*, WebKitFormSubmissionRequest* request, FormClientTest* test) + { + test->submitForm(request); + } + + FormClientTest() + : m_submitPositionX(0) + , m_submitPositionY(0) + { + g_signal_connect(m_webView, "submit-form", G_CALLBACK(submitFormCallback), this); + } + + ~FormClientTest() + { + g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + void submitForm(WebKitFormSubmissionRequest* request) + { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + m_request = request; + webkit_form_submission_request_submit(request); + quitMainLoop(); + } + + GHashTable* waitUntilFormSubmittedAndGetTextFields() + { + g_main_loop_run(m_mainLoop); + return webkit_form_submission_request_get_text_fields(m_request.get()); + } + + static gboolean doClickIdleCallback(FormClientTest* test) + { + test->clickMouseButton(test->m_submitPositionX, test->m_submitPositionY, 1); + return FALSE; + } + + void submitFormAtPosition(int x, int y) + { + m_submitPositionX = x; + m_submitPositionY = y; + g_idle_add(reinterpret_cast<GSourceFunc>(doClickIdleCallback), this); + } + + int m_submitPositionX; + int m_submitPositionY; + GRefPtr<WebKitFormSubmissionRequest> m_request; +}; + +static void testWebViewSubmitForm(FormClientTest* test, gconstpointer) +{ + test->showInWindowAndWaitUntilMapped(); + + const char* formHTML = + "<html><body>" + " <form action='#'>" + " <input type='text' name='text1' value='value1'>" + " <input type='text' name='text2' value='value2'>" + " <input type='password' name='password' value='secret'>" + " <textarea cols='5' rows='5' name='textarea'>Text</textarea>" + " <input type='hidden' name='hidden1' value='hidden1'>" + " <input type='submit' value='Submit' style='position:absolute; left:1; top:1' size='10'>" + " </form>" + "</body></html>"; + + test->loadHtml(formHTML, "file:///"); + test->waitUntilLoadFinished(); + + test->submitFormAtPosition(5, 5); + GHashTable* values = test->waitUntilFormSubmittedAndGetTextFields(); + g_assert(values); + g_assert_cmpuint(g_hash_table_size(values), ==, 3); + g_assert_cmpstr(static_cast<char*>(g_hash_table_lookup(values, "text1")), ==, "value1"); + g_assert_cmpstr(static_cast<char*>(g_hash_table_lookup(values, "text2")), ==, "value2"); + g_assert_cmpstr(static_cast<char*>(g_hash_table_lookup(values, "password")), ==, "secret"); +} + +class SaveWebViewTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(SaveWebViewTest); + + SaveWebViewTest() + : m_tempDirectory(g_dir_make_tmp("WebKit2SaveViewTest-XXXXXX", 0)) + { + } + + ~SaveWebViewTest() + { + if (G_IS_FILE(m_file.get())) + g_file_delete(m_file.get(), 0, 0); + + if (G_IS_INPUT_STREAM(m_inputStream.get())) + g_input_stream_close(m_inputStream.get(), 0, 0); + + if (m_tempDirectory) + g_rmdir(m_tempDirectory.get()); + } + + static void webViewSavedToStreamCallback(GObject* object, GAsyncResult* result, SaveWebViewTest* test) + { + GUniqueOutPtr<GError> error; + test->m_inputStream = adoptGRef(webkit_web_view_save_finish(test->m_webView, result, &error.outPtr())); + g_assert(G_IS_INPUT_STREAM(test->m_inputStream.get())); + g_assert(!error); + + test->quitMainLoop(); + } + + static void webViewSavedToFileCallback(GObject* object, GAsyncResult* result, SaveWebViewTest* test) + { + GUniqueOutPtr<GError> error; + g_assert(webkit_web_view_save_to_file_finish(test->m_webView, result, &error.outPtr())); + g_assert(!error); + + test->quitMainLoop(); + } + + void saveAndWaitForStream() + { + webkit_web_view_save(m_webView, WEBKIT_SAVE_MODE_MHTML, 0, reinterpret_cast<GAsyncReadyCallback>(webViewSavedToStreamCallback), this); + g_main_loop_run(m_mainLoop); + } + + void saveAndWaitForFile() + { + m_saveDestinationFilePath.reset(g_build_filename(m_tempDirectory.get(), "testWebViewSaveResult.mht", NULL)); + m_file = adoptGRef(g_file_new_for_path(m_saveDestinationFilePath.get())); + webkit_web_view_save_to_file(m_webView, m_file.get(), WEBKIT_SAVE_MODE_MHTML, 0, reinterpret_cast<GAsyncReadyCallback>(webViewSavedToFileCallback), this); + g_main_loop_run(m_mainLoop); + } + + GUniquePtr<char> m_tempDirectory; + GUniquePtr<char> m_saveDestinationFilePath; + GRefPtr<GInputStream> m_inputStream; + GRefPtr<GFile> m_file; +}; + +static void testWebViewSave(SaveWebViewTest* test, gconstpointer) +{ + test->loadHtml("<html>" + "<body>" + " <p>A paragraph with plain text</p>" + " <p>" + " A red box: <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AYWDTMVwnSZnwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAFklEQVQI12P8z8DAwMDAxMDAwMDAAAANHQEDK+mmyAAAAABJRU5ErkJggg=='></br>" + " A blue box: <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AYWDTMvBHhALQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAFklEQVQI12Nk4PnPwMDAxMDAwMDAAAALrwEPPIs1pgAAAABJRU5ErkJggg=='>" + " </p>" + "</body>" + "</html>", 0); + test->waitUntilLoadFinished(); + + // Write to a file and to an input stream. + test->saveAndWaitForFile(); + test->saveAndWaitForStream(); + + // We should have exactly the same amount of bytes in the file + // than those coming from the GInputStream. We don't compare the + // strings read since the 'Date' field and the boundaries will be + // different on each case. MHTML functionality will be tested by + // Layout tests, so checking the amount of bytes is enough. + GUniqueOutPtr<GError> error; + gchar buffer[512] = { 0 }; + gssize readBytes = 0; + gssize totalBytesFromStream = 0; + while ((readBytes = g_input_stream_read(test->m_inputStream.get(), &buffer, 512, 0, &error.outPtr()))) { + g_assert(!error); + totalBytesFromStream += readBytes; + } + + // Check that the file exists and that it contains the same amount of bytes. + GRefPtr<GFileInfo> fileInfo = adoptGRef(g_file_query_info(test->m_file.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), 0, 0)); + g_assert_cmpint(g_file_info_get_size(fileInfo.get()), ==, totalBytesFromStream); +} + +// To test page visibility API. Currently only 'visible', 'hidden' and 'prerender' states are implemented fully in WebCore. +// See also http://www.w3.org/TR/2011/WD-page-visibility-20110602/ and https://developers.google.com/chrome/whitepapers/pagevisibility +static void testWebViewPageVisibility(WebViewTest* test, gconstpointer) +{ + test->loadHtml("<html><title></title>" + "<body><p>Test Web Page Visibility</p>" + "<script>" + "document.addEventListener(\"visibilitychange\", onVisibilityChange, false);" + "function onVisibilityChange() {" + " document.title = document.visibilityState;" + "}" + "</script>" + "</body></html>", + 0); + + // Wait until the page is loaded. Initial visibility should be 'prerender'. + test->waitUntilLoadFinished(); + + GUniqueOutPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.visibilityState;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "prerender"); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.hidden;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert(WebViewTest::javascriptResultToBoolean(javascriptResult)); + + // Show the page. The visibility should be updated to 'visible'. + test->showInWindow(); + test->waitUntilTitleChanged(); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.visibilityState;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "visible"); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.hidden;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert(!WebViewTest::javascriptResultToBoolean(javascriptResult)); + + // Hide the page. The visibility should be updated to 'hidden'. + gtk_widget_hide(GTK_WIDGET(test->m_webView)); + test->waitUntilTitleChanged(); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.visibilityState;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(valueString.get(), ==, "hidden"); + + javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.hidden;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error.get()); + g_assert(WebViewTest::javascriptResultToBoolean(javascriptResult)); +} + +class SnapshotWebViewTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(SnapshotWebViewTest); + + static void onSnapshotCancelledReady(WebKitWebView* web_view, GAsyncResult* res, SnapshotWebViewTest* test) + { + GUniqueOutPtr<GError> error; + test->m_surface = webkit_web_view_get_snapshot_finish(web_view, res, &error.outPtr()); + g_assert(!test->m_surface); + g_assert_error(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED); + test->quitMainLoop(); + } + + gboolean getSnapshotAndCancel() + { + if (m_surface) + cairo_surface_destroy(m_surface); + m_surface = 0; + GRefPtr<GCancellable> cancellable = adoptGRef(g_cancellable_new()); + webkit_web_view_get_snapshot(m_webView, WEBKIT_SNAPSHOT_REGION_VISIBLE, WEBKIT_SNAPSHOT_OPTIONS_NONE, cancellable.get(), reinterpret_cast<GAsyncReadyCallback>(onSnapshotCancelledReady), this); + g_cancellable_cancel(cancellable.get()); + g_main_loop_run(m_mainLoop); + + return true; + } + +}; + +static void testWebViewSnapshot(SnapshotWebViewTest* test, gconstpointer) +{ + test->loadHtml("<html><head><style>html { width: 200px; height: 100px; } ::-webkit-scrollbar { display: none; }</style></head><body><p>Whatever</p></body></html>", nullptr); + test->waitUntilLoadFinished(); + + // WEBKIT_SNAPSHOT_REGION_VISIBLE returns a null surface when the view is not visible. + cairo_surface_t* surface1 = test->getSnapshotAndWaitUntilReady(WEBKIT_SNAPSHOT_REGION_VISIBLE, WEBKIT_SNAPSHOT_OPTIONS_NONE); + g_assert(!surface1); + + // WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT works even if the window is not visible. + surface1 = test->getSnapshotAndWaitUntilReady(WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT, WEBKIT_SNAPSHOT_OPTIONS_NONE); + g_assert(surface1); + g_assert_cmpuint(cairo_surface_get_type(surface1), ==, CAIRO_SURFACE_TYPE_IMAGE); + g_assert_cmpint(cairo_image_surface_get_width(surface1), ==, 200); + g_assert_cmpint(cairo_image_surface_get_height(surface1), ==, 100); + + // Show the WebView in a popup widow of 50x50 and try again with WEBKIT_SNAPSHOT_REGION_VISIBLE. + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_POPUP, 50, 50); + surface1 = cairo_surface_reference(test->getSnapshotAndWaitUntilReady(WEBKIT_SNAPSHOT_REGION_VISIBLE, WEBKIT_SNAPSHOT_OPTIONS_NONE)); + g_assert(surface1); + g_assert_cmpuint(cairo_surface_get_type(surface1), ==, CAIRO_SURFACE_TYPE_IMAGE); + g_assert_cmpint(cairo_image_surface_get_width(surface1), ==, 50); + g_assert_cmpint(cairo_image_surface_get_height(surface1), ==, 50); + + // Select all text in the WebView, request a snapshot ignoring selection. + test->selectAll(); + cairo_surface_t* surface2 = test->getSnapshotAndWaitUntilReady(WEBKIT_SNAPSHOT_REGION_VISIBLE, WEBKIT_SNAPSHOT_OPTIONS_NONE); + g_assert(surface2); + g_assert(Test::cairoSurfacesEqual(surface1, surface2)); + + // Request a new snapshot, including the selection this time. The size should be the same but the result + // must be different to the one previously obtained. + surface2 = test->getSnapshotAndWaitUntilReady(WEBKIT_SNAPSHOT_REGION_VISIBLE, WEBKIT_SNAPSHOT_OPTIONS_INCLUDE_SELECTION_HIGHLIGHTING); + g_assert_cmpuint(cairo_surface_get_type(surface2), ==, CAIRO_SURFACE_TYPE_IMAGE); + g_assert_cmpint(cairo_image_surface_get_width(surface1), ==, cairo_image_surface_get_width(surface2)); + g_assert_cmpint(cairo_image_surface_get_height(surface1), ==, cairo_image_surface_get_height(surface2)); + g_assert(!Test::cairoSurfacesEqual(surface1, surface2)); + + // Get a snpashot with a transparent background, the result must be different. + surface2 = test->getSnapshotAndWaitUntilReady(WEBKIT_SNAPSHOT_REGION_VISIBLE, WEBKIT_SNAPSHOT_OPTIONS_TRANSPARENT_BACKGROUND); + g_assert_cmpuint(cairo_surface_get_type(surface2), ==, CAIRO_SURFACE_TYPE_IMAGE); + g_assert_cmpint(cairo_image_surface_get_width(surface1), ==, cairo_image_surface_get_width(surface2)); + g_assert_cmpint(cairo_image_surface_get_height(surface1), ==, cairo_image_surface_get_height(surface2)); + g_assert(!Test::cairoSurfacesEqual(surface1, surface2)); + cairo_surface_destroy(surface1); + + // Test that cancellation works. + g_assert(test->getSnapshotAndCancel()); +} + +class NotificationWebViewTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(NotificationWebViewTest); + + enum NotificationEvent { + None, + Permission, + Shown, + Clicked, + OnClicked, + Closed, + OnClosed, + }; + + static gboolean permissionRequestCallback(WebKitWebView*, WebKitPermissionRequest *request, NotificationWebViewTest* test) + { + g_assert(WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(request)); + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request)); + + test->m_event = Permission; + + webkit_permission_request_allow(request); + + g_main_loop_quit(test->m_mainLoop); + + return TRUE; + } + + static gboolean notificationClosedCallback(WebKitNotification* notification, NotificationWebViewTest* test) + { + g_assert(test->m_notification == notification); + test->m_notification = nullptr; + test->m_event = Closed; + if (g_main_loop_is_running(test->m_mainLoop)) + g_main_loop_quit(test->m_mainLoop); + return TRUE; + } + + static gboolean notificationClickedCallback(WebKitNotification* notification, NotificationWebViewTest* test) + { + g_assert(test->m_notification == notification); + test->m_event = Clicked; + return TRUE; + } + + static gboolean showNotificationCallback(WebKitWebView*, WebKitNotification* notification, NotificationWebViewTest* test) + { + test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(notification)); + test->m_notification = notification; + g_signal_connect(notification, "closed", G_CALLBACK(notificationClosedCallback), test); + g_signal_connect(notification, "clicked", G_CALLBACK(notificationClickedCallback), test); + test->m_event = Shown; + g_main_loop_quit(test->m_mainLoop); + return TRUE; + } + + static void notificationsMessageReceivedCallback(WebKitUserContentManager* userContentManager, WebKitJavascriptResult* javascriptResult, NotificationWebViewTest* test) + { + GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult)); + + if (g_str_equal(valueString.get(), "clicked")) + test->m_event = OnClicked; + else if (g_str_equal(valueString.get(), "closed")) + test->m_event = OnClosed; + + g_main_loop_quit(test->m_mainLoop); + } + + NotificationWebViewTest() + : WebViewTest(webkit_user_content_manager_new()) + , m_notification(nullptr) + , m_event(None) + { + g_signal_connect(m_webView, "permission-request", G_CALLBACK(permissionRequestCallback), this); + g_signal_connect(m_webView, "show-notification", G_CALLBACK(showNotificationCallback), this); + WebKitUserContentManager* manager = webkit_web_view_get_user_content_manager(m_webView); + webkit_user_content_manager_register_script_message_handler(manager, "notifications"); + g_signal_connect(manager, "script-message-received::notifications", G_CALLBACK(notificationsMessageReceivedCallback), this); + } + + ~NotificationWebViewTest() + { + g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + WebKitUserContentManager* manager = webkit_web_view_get_user_content_manager(m_webView); + g_signal_handlers_disconnect_matched(manager, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + webkit_user_content_manager_unregister_script_message_handler(manager, "notifications"); + } + + void requestPermissionAndWaitUntilGiven() + { + m_event = None; + webkit_web_view_run_javascript(m_webView, "Notification.requestPermission();", nullptr, nullptr, nullptr); + g_main_loop_run(m_mainLoop); + } + + void requestNotificationAndWaitUntilShown(const char* title, const char* body) + { + m_event = None; + + GUniquePtr<char> jscode(g_strdup_printf("n = new Notification('%s', { body: '%s'});", title, body)); + webkit_web_view_run_javascript(m_webView, jscode.get(), nullptr, nullptr, nullptr); + + g_main_loop_run(m_mainLoop); + } + + void clickNotificationAndWaitUntilClicked() + { + m_event = None; + runJavaScriptAndWaitUntilFinished("n.onclick = function() { window.webkit.messageHandlers.notifications.postMessage('clicked'); }", nullptr); + webkit_notification_clicked(m_notification); + g_assert(m_event == Clicked); + g_main_loop_run(m_mainLoop); + } + + void closeNotificationAndWaitUntilClosed() + { + m_event = None; + webkit_web_view_run_javascript(m_webView, "n.close()", nullptr, nullptr, nullptr); + g_main_loop_run(m_mainLoop); + } + + void closeNotificationAndWaitUntilOnClosed() + { + g_assert(m_notification); + m_event = None; + runJavaScriptAndWaitUntilFinished("n.onclose = function() { window.webkit.messageHandlers.notifications.postMessage('closed'); }", nullptr); + webkit_notification_close(m_notification); + g_assert(m_event == Closed); + g_main_loop_run(m_mainLoop); + } + + NotificationEvent m_event; + WebKitNotification* m_notification; +}; + +static void testWebViewNotification(NotificationWebViewTest* test, gconstpointer) +{ + // Notifications don't work with local or special schemes. + test->loadURI(gServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + + test->requestPermissionAndWaitUntilGiven(); + g_assert(test->m_event == NotificationWebViewTest::Permission); + + static const char* title = "This is a notification"; + static const char* body = "This is the body."; + test->requestNotificationAndWaitUntilShown(title, body); + + g_assert(test->m_event == NotificationWebViewTest::Shown); + g_assert(test->m_notification); + g_assert_cmpstr(webkit_notification_get_title(test->m_notification), ==, title); + g_assert_cmpstr(webkit_notification_get_body(test->m_notification), ==, body); + + test->clickNotificationAndWaitUntilClicked(); + g_assert(test->m_event == NotificationWebViewTest::OnClicked); + + test->closeNotificationAndWaitUntilClosed(); + g_assert(test->m_event == NotificationWebViewTest::Closed); + + test->requestNotificationAndWaitUntilShown(title, body); + g_assert(test->m_event == NotificationWebViewTest::Shown); + + test->closeNotificationAndWaitUntilOnClosed(); + g_assert(test->m_event == NotificationWebViewTest::OnClosed); + + test->requestNotificationAndWaitUntilShown(title, body); + g_assert(test->m_event == NotificationWebViewTest::Shown); + + test->loadURI(gServer->getURIForPath("/").data()); + test->waitUntilLoadFinished(); + g_assert(test->m_event == NotificationWebViewTest::Closed); +} + +static void testWebViewIsPlayingAudio(IsPlayingAudioWebViewTest* test, gconstpointer) +{ + // The web view must be realized for the video to start playback and + // trigger changes in WebKitWebView::is-playing-audio. + test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL); + + // Initially, web views should always report no audio being played. + g_assert(!webkit_web_view_is_playing_audio(test->m_webView)); + + GUniquePtr<char> resourcePath(g_build_filename(Test::getResourcesDir(Test::WebKit2Resources).data(), "file-with-video.html", nullptr)); + GUniquePtr<char> resourceURL(g_filename_to_uri(resourcePath.get(), nullptr, nullptr)); + webkit_web_view_load_uri(test->m_webView, resourceURL.get()); + test->waitUntilLoadFinished(); + g_assert(!webkit_web_view_is_playing_audio(test->m_webView)); + + webkit_web_view_run_javascript(test->m_webView, "playVideo();", nullptr, nullptr, nullptr); + test->waitUntilIsPlayingAudioChanged(); + g_assert(webkit_web_view_is_playing_audio(test->m_webView)); + + // Pause the video, and check again. + webkit_web_view_run_javascript(test->m_webView, "document.getElementById('test-video').pause();", nullptr, nullptr, nullptr); + test->waitUntilIsPlayingAudioChanged(); + g_assert(!webkit_web_view_is_playing_audio(test->m_webView)); +} + +static void testWebViewBackgroundColor(WebViewTest* test, gconstpointer) +{ + // White is the default background. + GdkRGBA rgba; + webkit_web_view_get_background_color(test->m_webView, &rgba); + g_assert_cmpfloat(rgba.red, ==, 1); + g_assert_cmpfloat(rgba.green, ==, 1); + g_assert_cmpfloat(rgba.blue, ==, 1); + g_assert_cmpfloat(rgba.alpha, ==, 1); + + // Set a different (semi-transparent red). + rgba.red = 1; + rgba.green = 0; + rgba.blue = 0; + rgba.alpha = 0.5; + webkit_web_view_set_background_color(test->m_webView, &rgba); + g_assert_cmpfloat(rgba.red, ==, 1); + g_assert_cmpfloat(rgba.green, ==, 0); + g_assert_cmpfloat(rgba.blue, ==, 0); + g_assert_cmpfloat(rgba.alpha, ==, 0.5); + + // The actual rendering can't be tested using unit tests, use + // MiniBrowser --bg-color="<color-value>" for manually testing this API. +} + +static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer) +{ + if (message->method != SOUP_METHOD_GET) { + soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + if (g_str_equal(path, "/")) { + soup_message_set_status(message, SOUP_STATUS_OK); + soup_message_body_complete(message->response_body); + } else + soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); +} + +void beforeAll() +{ + gServer = new WebKitTestServer(); + gServer->run(serverCallback); + + WebViewTest::add("WebKitWebView", "web-context", testWebViewWebContext); + WebViewTest::add("WebKitWebView", "web-context-lifetime", testWebViewWebContextLifetime); + WebViewTest::add("WebKitWebView", "custom-charset", testWebViewCustomCharset); + WebViewTest::add("WebKitWebView", "settings", testWebViewSettings); + WebViewTest::add("WebKitWebView", "zoom-level", testWebViewZoomLevel); + WebViewTest::add("WebKitWebView", "run-javascript", testWebViewRunJavaScript); + FullScreenClientTest::add("WebKitWebView", "fullscreen", testWebViewFullScreen); + WebViewTest::add("WebKitWebView", "can-show-mime-type", testWebViewCanShowMIMEType); + FormClientTest::add("WebKitWebView", "submit-form", testWebViewSubmitForm); + SaveWebViewTest::add("WebKitWebView", "save", testWebViewSave); + SnapshotWebViewTest::add("WebKitWebView", "snapshot", testWebViewSnapshot); + WebViewTest::add("WebKitWebView", "page-visibility", testWebViewPageVisibility); + NotificationWebViewTest::add("WebKitWebView", "notification", testWebViewNotification); + IsPlayingAudioWebViewTest::add("WebKitWebView", "is-playing-audio", testWebViewIsPlayingAudio); + WebViewTest::add("WebKitWebView", "background-color", testWebViewBackgroundColor); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebViewEditor.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebViewEditor.cpp new file mode 100644 index 000000000..d20c7944f --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebViewEditor.cpp @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebViewTest.h" +#include <wtf/glib/GRefPtr.h> + +class EditorTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(EditorTest); + + static const unsigned kClipboardWaitTimeout = 50; + static const unsigned kClipboardWaitMaxTries = 2; + + EditorTest() + : m_clipboard(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)) + , m_canExecuteEditingCommand(false) + , m_triesCount(0) + , m_editorState(nullptr) + { + gtk_clipboard_clear(m_clipboard); + } + + static void canExecuteEditingCommandReadyCallback(GObject*, GAsyncResult* result, EditorTest* test) + { + GUniqueOutPtr<GError> error; + test->m_canExecuteEditingCommand = webkit_web_view_can_execute_editing_command_finish(test->m_webView, result, &error.outPtr()); + g_assert(!error.get()); + g_main_loop_quit(test->m_mainLoop); + } + + bool canExecuteEditingCommand(const char* command) + { + m_canExecuteEditingCommand = false; + webkit_web_view_can_execute_editing_command(m_webView, command, 0, reinterpret_cast<GAsyncReadyCallback>(canExecuteEditingCommandReadyCallback), this); + g_main_loop_run(m_mainLoop); + return m_canExecuteEditingCommand; + } + + static gboolean waitForClipboardText(EditorTest* test) + { + test->m_triesCount++; + if (gtk_clipboard_wait_is_text_available(test->m_clipboard) || test->m_triesCount > kClipboardWaitMaxTries) { + g_main_loop_quit(test->m_mainLoop); + return FALSE; + } + + return TRUE; + } + + void copyClipboard() + { + webkit_web_view_execute_editing_command(m_webView, WEBKIT_EDITING_COMMAND_COPY); + // There's no way to know when the selection has been copied to + // the clipboard, so use a timeout source to query the clipboard. + m_triesCount = 0; + g_timeout_add(kClipboardWaitTimeout, reinterpret_cast<GSourceFunc>(waitForClipboardText), this); + g_main_loop_run(m_mainLoop); + } + + gchar* cutSelection() + { + g_assert(canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT)); + g_assert(canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE)); + + webkit_web_view_execute_editing_command(m_webView, WEBKIT_EDITING_COMMAND_CUT); + // There's no way to know when the selection has been cut to + // the clipboard, so use a timeout source to query the clipboard. + m_triesCount = 0; + g_timeout_add(kClipboardWaitTimeout, reinterpret_cast<GSourceFunc>(waitForClipboardText), this); + g_main_loop_run(m_mainLoop); + + return gtk_clipboard_wait_for_text(m_clipboard); + } + + WebKitEditorState* editorState() + { + if (m_editorState) + return m_editorState; + + m_editorState = webkit_web_view_get_editor_state(m_webView); + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_editorState)); + return m_editorState; + } + + static void quitMainLoopInCallback(EditorTest* test) + { + g_main_loop_quit(test->m_mainLoop); + } + + unsigned typingAttributes() + { + return webkit_editor_state_get_typing_attributes(editorState()); + } + + unsigned waitUntilTypingAttributesChanged() + { + unsigned long handlerID = g_signal_connect_swapped(editorState(), "notify::typing-attributes", G_CALLBACK(quitMainLoopInCallback), this); + g_main_loop_run(m_mainLoop); + g_signal_handler_disconnect(m_editorState, handlerID); + return typingAttributes(); + } + + GtkClipboard* m_clipboard; + bool m_canExecuteEditingCommand; + size_t m_triesCount; + WebKitEditorState* m_editorState; +}; + +static const char* selectedSpanHTMLFormat = + "<html><body contentEditable=\"%s\">" + "<span id=\"mainspan\">All work and no play <span id=\"subspan\">make Jack a dull</span> boy.</span>" + "<script>document.getSelection().collapse();\n" + "document.getSelection().selectAllChildren(document.getElementById('subspan'));\n" + "</script></body></html>"; + +static void testWebViewEditorCutCopyPasteNonEditable(EditorTest* test, gconstpointer) +{ + // Nothing loaded yet. + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT)); + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_COPY)); + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE)); + + GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false")); + test->loadHtml(selectedSpanHTML.get(), nullptr); + test->waitUntilLoadFinished(); + + g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_COPY)); + // It's not possible to cut and paste when content is not editable + // even if there's a selection. + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT)); + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE)); + + test->copyClipboard(); + GUniquePtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard)); + g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull"); +} + +static void testWebViewEditorCutCopyPasteEditable(EditorTest* test, gconstpointer) +{ + // Nothing loaded yet. + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT)); + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_COPY)); + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE)); + + g_assert(!test->isEditable()); + test->setEditable(true); + g_assert(test->isEditable()); + + GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false")); + test->loadHtml(selectedSpanHTML.get(), nullptr); + test->waitUntilLoadFinished(); + + // There's a selection. + g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT)); + g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_COPY)); + g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE)); + + test->copyClipboard(); + GUniquePtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard)); + g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull"); +} + +static void testWebViewEditorSelectAllNonEditable(EditorTest* test, gconstpointer) +{ + g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL)); + + GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false")); + test->loadHtml(selectedSpanHTML.get(), nullptr); + test->waitUntilLoadFinished(); + + g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL)); + + test->copyClipboard(); + GUniquePtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard)); + + // Initially only the subspan is selected. + g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull"); + + webkit_web_view_execute_editing_command(test->m_webView, WEBKIT_EDITING_COMMAND_SELECT_ALL); + test->copyClipboard(); + clipboardText.reset(gtk_clipboard_wait_for_text(test->m_clipboard)); + + // The mainspan should be selected after calling SELECT_ALL. + g_assert_cmpstr(clipboardText.get(), ==, "All work and no play make Jack a dull boy."); +} + +static void testWebViewEditorSelectAllEditable(EditorTest* test, gconstpointer) +{ + g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL)); + + g_assert(!test->isEditable()); + test->setEditable(true); + g_assert(test->isEditable()); + + GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false")); + test->loadHtml(selectedSpanHTML.get(), nullptr); + test->waitUntilLoadFinished(); + + g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL)); + + test->copyClipboard(); + GUniquePtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard)); + + // Initially only the subspan is selected. + g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull"); + + webkit_web_view_execute_editing_command(test->m_webView, WEBKIT_EDITING_COMMAND_SELECT_ALL); + test->copyClipboard(); + clipboardText.reset(gtk_clipboard_wait_for_text(test->m_clipboard)); + + // The mainspan should be selected after calling SELECT_ALL. + g_assert_cmpstr(clipboardText.get(), ==, "All work and no play make Jack a dull boy."); +} + +static void loadContentsAndTryToCutSelection(EditorTest* test, bool contentEditable) +{ + // View is not editable by default. + g_assert(!test->isEditable()); + + GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, contentEditable ? "true" : "false")); + test->loadHtml(selectedSpanHTML.get(), nullptr); + test->waitUntilLoadFinished(); + + g_assert(!test->isEditable()); + test->setEditable(true); + g_assert(test->isEditable()); + + // Cut the selection to the clipboard to see if the view is indeed editable. + GUniquePtr<char> clipboardText(test->cutSelection()); + g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull"); + + // Reset the editable for next test. + test->setEditable(false); + g_assert(!test->isEditable()); +} + +static void testWebViewEditorNonEditable(EditorTest* test) +{ + GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false")); + test->loadHtml(selectedSpanHTML.get(), nullptr); + test->waitUntilLoadFinished(); + + g_assert(!test->isEditable()); + test->setEditable(true); + g_assert(test->isEditable()); + test->setEditable(false); + g_assert(!test->isEditable()); + + // Check if view is indeed non-editable. + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT)); + g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE)); +} + +static void testWebViewEditorEditable(EditorTest* test, gconstpointer) +{ + testWebViewEditorNonEditable(test); + + // Reset the editable for next test. + test->setEditable(false); + g_assert(!test->isEditable()); + + loadContentsAndTryToCutSelection(test, true); + + // Reset the editable for next test. + test->setEditable(false); + g_assert(!test->isEditable()); + + loadContentsAndTryToCutSelection(test, false); +} + +static void testWebViewEditorEditorStateTypingAttributes(EditorTest* test, gconstpointer) +{ + static const char* typingAttributesHTML = + "<html><body>" + "normal <b>bold </b><i>italic </i><u>underline </u><strike>strike </strike>" + "<b><i>boldanditalic </i></b>" + "</body></html>"; + + test->loadHtml(typingAttributesHTML, nullptr); + test->waitUntilLoadFinished(); + test->setEditable(true); + + unsigned typingAttributes = test->typingAttributes(); + g_assert_cmpuint(typingAttributes, ==, WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH)); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD)); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH)); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC)); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH)); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE)); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH)); + + // Selections. + webkit_web_view_execute_editing_command(test->m_webView, "MoveToBeginningOfDocument"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert_cmpuint(typingAttributes, ==, WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH)); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD)); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH)); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC)); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH)); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE)); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH); + + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveForward"); + webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD); + g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE)); + g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH)); + + webkit_web_view_execute_editing_command(test->m_webView, "SelectAll"); + typingAttributes = test->waitUntilTypingAttributesChanged(); + g_assert_cmpuint(typingAttributes, ==, WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE); +} + +static void testWebViewEditorInsertImage(EditorTest* test, gconstpointer) +{ + test->loadHtml("<html><body></body></html>", "file:///"); + test->waitUntilLoadFinished(); + test->setEditable(true); + + GUniquePtr<char> imagePath(g_build_filename(Test::getResourcesDir().data(), "blank.ico", nullptr)); + GUniquePtr<char> imageURI(g_filename_to_uri(imagePath.get(), nullptr, nullptr)); + webkit_web_view_execute_editing_command_with_argument(test->m_webView, WEBKIT_EDITING_COMMAND_INSERT_IMAGE, imageURI.get()); + GUniqueOutPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('IMG')[0].src", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error); + GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(resultString.get(), ==, imageURI.get()); +} + +static void testWebViewEditorCreateLink(EditorTest* test, gconstpointer) +{ + test->loadHtml("<html><body onload=\"document.getSelection().selectAllChildren(document.body);\">webkitgtk.org</body></html>", nullptr); + test->waitUntilLoadFinished(); + test->setEditable(true); + + static const char* webkitGTKURL = "http://www.webkitgtk.org/"; + webkit_web_view_execute_editing_command_with_argument(test->m_webView, WEBKIT_EDITING_COMMAND_CREATE_LINK, webkitGTKURL); + GUniqueOutPtr<GError> error; + WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('A')[0].href;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error); + GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(resultString.get(), ==, webkitGTKURL); + javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('A')[0].innerText;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error); + resultString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(resultString.get(), ==, "webkitgtk.org"); + + // When there isn't text selected, the URL is used as link text. + webkit_web_view_execute_editing_command(test->m_webView, "MoveToEndOfLine"); + webkit_web_view_execute_editing_command_with_argument(test->m_webView, WEBKIT_EDITING_COMMAND_CREATE_LINK, webkitGTKURL); + javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('A')[1].href;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error); + resultString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(resultString.get(), ==, webkitGTKURL); + javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('A')[1].innerText;", &error.outPtr()); + g_assert(javascriptResult); + g_assert(!error); + resultString.reset(WebViewTest::javascriptResultToCString(javascriptResult)); + g_assert_cmpstr(resultString.get(), ==, webkitGTKURL); +} + +void beforeAll() +{ + EditorTest::add("WebKitWebView", "editable/editable", testWebViewEditorEditable); + EditorTest::add("WebKitWebView", "cut-copy-paste/non-editable", testWebViewEditorCutCopyPasteNonEditable); + EditorTest::add("WebKitWebView", "cut-copy-paste/editable", testWebViewEditorCutCopyPasteEditable); + EditorTest::add("WebKitWebView", "select-all/non-editable", testWebViewEditorSelectAllNonEditable); + EditorTest::add("WebKitWebView", "select-all/editable", testWebViewEditorSelectAllEditable); + EditorTest::add("WebKitWebView", "editor-state/typing-attributes", testWebViewEditorEditorStateTypingAttributes); + EditorTest::add("WebKitWebView", "insert/image", testWebViewEditorInsertImage); + EditorTest::add("WebKitWebView", "insert/link", testWebViewEditorCreateLink); +} + +void afterAll() +{ +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp new file mode 100644 index 000000000..372cfea7c --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include <JavaScriptCore/JSContextRef.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <gio/gio.h> +#include <gst/gst.h> +#include <stdlib.h> +#include <string.h> +#include <webkit2/webkit-web-extension.h> +#include <wtf/Deque.h> +#include <wtf/ProcessID.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> +#include <wtf/text/CString.h> + +#define WEBKIT_DOM_USE_UNSTABLE_API +#include <webkitdom/WebKitDOMWebKitNamespace.h> +#include <webkitdom/WebKitDOMUserMessageHandlersNamespace.h> +#include <webkitdom/WebKitDOMUserMessageHandler.h> + +static const char introspectionXML[] = + "<node>" + " <interface name='org.webkit.gtk.WebExtensionTest'>" + " <method name='GetTitle'>" + " <arg type='t' name='pageID' direction='in'/>" + " <arg type='s' name='title' direction='out'/>" + " </method>" + " <method name='AbortProcess'>" + " </method>" + " <method name='RunJavaScriptInIsolatedWorld'>" + " <arg type='t' name='pageID' direction='in'/>" + " <arg type='s' name='script' direction='in'/>" + " </method>" + " <method name='GetProcessIdentifier'>" + " <arg type='u' name='identifier' direction='out'/>" + " </method>" + " <method name='RemoveAVPluginsFromGSTRegistry'>" + " </method>" + " <signal name='DocumentLoaded'/>" + " <signal name='URIChanged'>" + " <arg type='s' name='uri' direction='out'/>" + " </signal>" + " </interface>" + "</node>"; + + +typedef enum { + DocumentLoadedSignal, + URIChangedSignal, +} DelayedSignalType; + +struct DelayedSignal { + DelayedSignal(DelayedSignalType type) + : type(type) + { + } + + DelayedSignal(DelayedSignalType type, const char* uri) + : type(type) + , uri(uri) + { + } + + DelayedSignalType type; + CString uri; +}; + +Deque<DelayedSignal> delayedSignalsQueue; + +static void emitDocumentLoaded(GDBusConnection* connection) +{ + bool ok = g_dbus_connection_emit_signal( + connection, + 0, + "/org/webkit/gtk/WebExtensionTest", + "org.webkit.gtk.WebExtensionTest", + "DocumentLoaded", + 0, + 0); + g_assert(ok); +} + +static void documentLoadedCallback(WebKitWebPage* webPage, WebKitWebExtension* extension) +{ + // FIXME: Too much code just to send a message, we need convenient custom API for this. + WebKitDOMDocument* document = webkit_web_page_get_dom_document(webPage); + GRefPtr<WebKitDOMDOMWindow> window = adoptGRef(webkit_dom_document_get_default_view(document)); + if (WebKitDOMWebKitNamespace* webkit = webkit_dom_dom_window_get_webkit_namespace(window.get())) { + WebKitDOMUserMessageHandlersNamespace* messageHandlers = webkit_dom_webkit_namespace_get_message_handlers(webkit); + if (WebKitDOMUserMessageHandler* handler = webkit_dom_user_message_handlers_namespace_get_handler(messageHandlers, "dom")) + webkit_dom_user_message_handler_post_message(handler, "DocumentLoaded", nullptr); + } + + webkit_dom_dom_window_webkit_message_handlers_post_message(window.get(), "dom-convenience", "DocumentLoaded"); + + gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection"); + if (data) + emitDocumentLoaded(G_DBUS_CONNECTION(data)); + else + delayedSignalsQueue.append(DelayedSignal(DocumentLoadedSignal)); +} + +static void emitURIChanged(GDBusConnection* connection, const char* uri) +{ + bool ok = g_dbus_connection_emit_signal( + connection, + 0, + "/org/webkit/gtk/WebExtensionTest", + "org.webkit.gtk.WebExtensionTest", + "URIChanged", + g_variant_new("(s)", uri), + 0); + g_assert(ok); +} + +static void uriChangedCallback(WebKitWebPage* webPage, GParamSpec* pspec, WebKitWebExtension* extension) +{ + gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection"); + if (data) + emitURIChanged(G_DBUS_CONNECTION(data), webkit_web_page_get_uri(webPage)); + else + delayedSignalsQueue.append(DelayedSignal(URIChangedSignal, webkit_web_page_get_uri(webPage))); +} + +static gboolean sendRequestCallback(WebKitWebPage*, WebKitURIRequest* request, WebKitURIResponse* redirectResponse, gpointer) +{ + gboolean returnValue = FALSE; + const char* requestURI = webkit_uri_request_get_uri(request); + g_assert(requestURI); + + if (const char* suffix = g_strrstr(requestURI, "/remove-this/javascript.js")) { + GUniquePtr<char> prefix(g_strndup(requestURI, strlen(requestURI) - strlen(suffix))); + GUniquePtr<char> newURI(g_strdup_printf("%s/javascript.js", prefix.get())); + webkit_uri_request_set_uri(request, newURI.get()); + } else if (const char* suffix = g_strrstr(requestURI, "/remove-this/javascript-after-redirection.js")) { + // Redirected from /redirected.js, redirectResponse should be nullptr. + g_assert(WEBKIT_IS_URI_RESPONSE(redirectResponse)); + g_assert(g_str_has_suffix(webkit_uri_response_get_uri(redirectResponse), "/redirected.js")); + + GUniquePtr<char> prefix(g_strndup(requestURI, strlen(requestURI) - strlen(suffix))); + GUniquePtr<char> newURI(g_strdup_printf("%s/javascript-after-redirection.js", prefix.get())); + webkit_uri_request_set_uri(request, newURI.get()); + } else if (g_str_has_suffix(requestURI, "/redirected.js")) { + // Original request, redirectResponse should be nullptr. + g_assert(!redirectResponse); + } else if (g_str_has_suffix(requestURI, "/add-do-not-track-header")) { + SoupMessageHeaders* headers = webkit_uri_request_get_http_headers(request); + g_assert(headers); + soup_message_headers_append(headers, "DNT", "1"); + } else if (g_str_has_suffix(requestURI, "/http-get-method")) { + g_assert_cmpstr(webkit_uri_request_get_http_method(request), ==, "GET"); + g_assert(webkit_uri_request_get_http_method(request) == SOUP_METHOD_GET); + } else if (g_str_has_suffix(requestURI, "/http-post-method")) { + g_assert_cmpstr(webkit_uri_request_get_http_method(request), ==, "POST"); + g_assert(webkit_uri_request_get_http_method(request) == SOUP_METHOD_POST); + returnValue = TRUE; + } else if (g_str_has_suffix(requestURI, "/cancel-this.js")) + returnValue = TRUE; + + return returnValue; +} + +static GVariant* serializeContextMenu(WebKitContextMenu* menu) +{ + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); + GList* items = webkit_context_menu_get_items(menu); + for (GList* it = items; it; it = g_list_next(it)) + g_variant_builder_add(&builder, "u", webkit_context_menu_item_get_stock_action(WEBKIT_CONTEXT_MENU_ITEM(it->data))); + return g_variant_builder_end(&builder); +} + +static GVariant* serializeNode(WebKitDOMNode* node) +{ + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add(&builder, "{sv}", "Name", g_variant_new_take_string(webkit_dom_node_get_node_name(node))); + g_variant_builder_add(&builder, "{sv}", "Type", g_variant_new_uint32(webkit_dom_node_get_node_type(node))); + g_variant_builder_add(&builder, "{sv}", "Contents", g_variant_new_take_string(webkit_dom_node_get_text_content(node))); + WebKitDOMNode* parent = webkit_dom_node_get_parent_node(node); + g_variant_builder_add(&builder, "{sv}", "Parent", parent ? g_variant_new_take_string(webkit_dom_node_get_node_name(parent)) : g_variant_new_string("ROOT")); + return g_variant_builder_end(&builder); +} + +static gboolean contextMenuCallback(WebKitWebPage* page, WebKitContextMenu* menu, WebKitWebHitTestResult* hitTestResult, gpointer) +{ + const char* pageURI = webkit_web_page_get_uri(page); + if (!g_strcmp0(pageURI, "ContextMenuTestDefault")) { + webkit_context_menu_set_user_data(menu, serializeContextMenu(menu)); + return FALSE; + } + + if (!g_strcmp0(pageURI, "ContextMenuTestCustom")) { + // Remove Back and Forward, and add Inspector action. + webkit_context_menu_remove(menu, webkit_context_menu_first(menu)); + webkit_context_menu_remove(menu, webkit_context_menu_first(menu)); + webkit_context_menu_append(menu, webkit_context_menu_item_new_separator()); + webkit_context_menu_append(menu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT)); + webkit_context_menu_set_user_data(menu, serializeContextMenu(menu)); + return TRUE; + } + + if (!g_strcmp0(pageURI, "ContextMenuTestClear")) { + webkit_context_menu_remove_all(menu); + return TRUE; + } + + if (!g_strcmp0(pageURI, "ContextMenuTestNode")) { + WebKitDOMNode* node = webkit_web_hit_test_result_get_node(hitTestResult); + g_assert(WEBKIT_DOM_IS_NODE(node)); + webkit_context_menu_set_user_data(menu, serializeNode(node)); + return TRUE; + } + + return FALSE; +} + +static void consoleMessageSentCallback(WebKitWebPage* webPage, WebKitConsoleMessage* consoleMessage) +{ + g_assert(consoleMessage); + GRefPtr<GVariant> variant = g_variant_new("(uusus)", webkit_console_message_get_source(consoleMessage), + webkit_console_message_get_level(consoleMessage), webkit_console_message_get_text(consoleMessage), + webkit_console_message_get_line(consoleMessage), webkit_console_message_get_source_id(consoleMessage)); + GUniquePtr<char> messageString(g_variant_print(variant.get(), FALSE)); + GRefPtr<WebKitDOMDOMWindow> window = adoptGRef(webkit_dom_document_get_default_view(webkit_web_page_get_dom_document(webPage))); + g_assert(WEBKIT_DOM_IS_DOM_WINDOW(window.get())); + webkit_dom_dom_window_webkit_message_handlers_post_message(window.get(), "console", messageString.get()); +} + +static void pageCreatedCallback(WebKitWebExtension* extension, WebKitWebPage* webPage, gpointer) +{ + g_signal_connect(webPage, "document-loaded", G_CALLBACK(documentLoadedCallback), extension); + g_signal_connect(webPage, "notify::uri", G_CALLBACK(uriChangedCallback), extension); + g_signal_connect(webPage, "send-request", G_CALLBACK(sendRequestCallback), nullptr); + g_signal_connect(webPage, "context-menu", G_CALLBACK(contextMenuCallback), nullptr); + g_signal_connect(webPage, "console-message-sent", G_CALLBACK(consoleMessageSentCallback), nullptr); +} + +static JSValueRef echoCallback(JSContextRef jsContext, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) +{ + if (argumentCount <= 0) + return JSValueMakeUndefined(jsContext); + + JSRetainPtr<JSStringRef> string(Adopt, JSValueToStringCopy(jsContext, arguments[0], 0)); + return JSValueMakeString(jsContext, string.get()); +} + +static void windowObjectCleared(WebKitScriptWorld* world, WebKitWebPage* page, WebKitFrame* frame, gpointer) +{ + JSGlobalContextRef jsContext = webkit_frame_get_javascript_context_for_script_world(frame, world); + g_assert(jsContext); + JSObjectRef globalObject = JSContextGetGlobalObject(jsContext); + g_assert(globalObject); + + JSRetainPtr<JSStringRef> functionName(Adopt, JSStringCreateWithUTF8CString("echo")); + JSObjectRef function = JSObjectMakeFunctionWithCallback(jsContext, functionName.get(), echoCallback); + JSObjectSetProperty(jsContext, globalObject, functionName.get(), function, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); +} + +static WebKitWebPage* getWebPage(WebKitWebExtension* extension, uint64_t pageID, GDBusMethodInvocation* invocation) +{ + WebKitWebPage* page = webkit_web_extension_get_page(extension, pageID); + if (!page) { + g_dbus_method_invocation_return_error( + invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "Invalid page ID: %" G_GUINT64_FORMAT, pageID); + return 0; + } + + g_assert_cmpuint(webkit_web_page_get_id(page), ==, pageID); + return page; +} + +static void methodCallCallback(GDBusConnection* connection, const char* sender, const char* objectPath, const char* interfaceName, const char* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData) +{ + if (g_strcmp0(interfaceName, "org.webkit.gtk.WebExtensionTest")) + return; + + if (!g_strcmp0(methodName, "GetTitle")) { + uint64_t pageID; + g_variant_get(parameters, "(t)", &pageID); + WebKitWebPage* page = getWebPage(WEBKIT_WEB_EXTENSION(userData), pageID, invocation); + if (!page) + return; + + WebKitDOMDocument* document = webkit_web_page_get_dom_document(page); + GUniquePtr<char> title(webkit_dom_document_get_title(document)); + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", title.get())); + } else if (!g_strcmp0(methodName, "RunJavaScriptInIsolatedWorld")) { + uint64_t pageID; + const char* script; + g_variant_get(parameters, "(t&s)", &pageID, &script); + WebKitWebPage* page = getWebPage(WEBKIT_WEB_EXTENSION(userData), pageID, invocation); + if (!page) + return; + + GRefPtr<WebKitScriptWorld> world = adoptGRef(webkit_script_world_new()); + g_assert(webkit_script_world_get_default() != world.get()); + WebKitFrame* frame = webkit_web_page_get_main_frame(page); + JSGlobalContextRef jsContext = webkit_frame_get_javascript_context_for_script_world(frame, world.get()); + JSRetainPtr<JSStringRef> jsScript(Adopt, JSStringCreateWithUTF8CString(script)); + JSEvaluateScript(jsContext, jsScript.get(), 0, 0, 0, 0); + g_dbus_method_invocation_return_value(invocation, 0); + } else if (!g_strcmp0(methodName, "AbortProcess")) { + abort(); + } else if (!g_strcmp0(methodName, "GetProcessIdentifier")) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(u)", static_cast<guint32>(getCurrentProcessID()))); + } else if (!g_strcmp0(methodName, "RemoveAVPluginsFromGSTRegistry")) { + gst_init(nullptr, nullptr); + static const char* avPlugins[] = { "libav", "omx", "vaapi", nullptr }; + GstRegistry* registry = gst_registry_get(); + for (unsigned i = 0; avPlugins[i]; ++i) { + if (GstPlugin* plugin = gst_registry_find_plugin(registry, avPlugins[i])) { + gst_registry_remove_plugin(registry, plugin); + gst_object_unref(plugin); + } + } + g_dbus_method_invocation_return_value(invocation, nullptr); + } +} + +static const GDBusInterfaceVTable interfaceVirtualTable = { + methodCallCallback, 0, 0, { 0, } +}; + +static void busAcquiredCallback(GDBusConnection* connection, const char* name, gpointer userData) +{ + static GDBusNodeInfo* introspectionData = 0; + if (!introspectionData) + introspectionData = g_dbus_node_info_new_for_xml(introspectionXML, 0); + + GUniqueOutPtr<GError> error; + unsigned registrationID = g_dbus_connection_register_object( + connection, + "/org/webkit/gtk/WebExtensionTest", + introspectionData->interfaces[0], + &interfaceVirtualTable, + g_object_ref(userData), + static_cast<GDestroyNotify>(g_object_unref), + &error.outPtr()); + if (!registrationID) + g_warning("Failed to register object: %s\n", error->message); + + g_object_set_data(G_OBJECT(userData), "dbus-connection", connection); + while (delayedSignalsQueue.size()) { + DelayedSignal delayedSignal = delayedSignalsQueue.takeFirst(); + switch (delayedSignal.type) { + case DocumentLoadedSignal: + emitDocumentLoaded(connection); + break; + case URIChangedSignal: + emitURIChanged(connection, delayedSignal.uri.data()); + break; + } + } +} + +static void registerGResource(void) +{ + GUniquePtr<char> resourcesPath(g_build_filename(WEBKIT_EXEC_PATH, "TestWebKitAPI", "WebKit2Gtk", "resources", "webkit2gtk-tests-resources.gresource", nullptr)); + GResource* resource = g_resource_load(resourcesPath.get(), nullptr); + g_assert(resource); + + g_resources_register(resource); + g_resource_unref(resource); +} + +extern "C" void webkit_web_extension_initialize_with_user_data(WebKitWebExtension* extension, GVariant* userData) +{ + g_signal_connect(extension, "page-created", G_CALLBACK(pageCreatedCallback), extension); + g_signal_connect(webkit_script_world_get_default(), "window-object-cleared", G_CALLBACK(windowObjectCleared), 0); + + registerGResource(); + + g_assert(userData); + g_assert(g_variant_is_of_type(userData, G_VARIANT_TYPE_UINT32)); + GUniquePtr<char> busName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", g_variant_get_uint32(userData))); + g_bus_own_name( + G_BUS_TYPE_SESSION, + busName.get(), + G_BUS_NAME_OWNER_FLAGS_NONE, + busAcquiredCallback, + 0, 0, + g_object_ref(extension), + static_cast<GDestroyNotify>(g_object_unref)); +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebProcessTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebProcessTest.cpp new file mode 100644 index 000000000..bc058693d --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebProcessTest.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebProcessTest.h" + +#include <JavaScriptCore/JSRetainPtr.h> +#include <gio/gio.h> +#include <wtf/HashSet.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/glib/GUniquePtr.h> + +static HashSet<GObject*> s_watchedObjects; + +typedef HashMap<String, std::function<std::unique_ptr<WebProcessTest> ()>> TestsMap; +static TestsMap& testsMap() +{ + static NeverDestroyed<TestsMap> s_testsMap; + return s_testsMap; +} + +void WebProcessTest::add(const String& testName, std::function<std::unique_ptr<WebProcessTest> ()> closure) +{ + testsMap().add(testName, WTFMove(closure)); +} + +void WebProcessTest::assertObjectIsDeletedWhenTestFinishes(GObject* object) +{ + s_watchedObjects.add(object); + g_object_weak_ref(object, [](gpointer, GObject* finalizedObject) { + s_watchedObjects.remove(finalizedObject); + }, nullptr); +} + +std::unique_ptr<WebProcessTest> WebProcessTest::create(const String& testName) +{ + g_assert(testsMap().contains(testName)); + return testsMap().get(testName)(); +} + +static JSValueRef runTest(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + JSRetainPtr<JSStringRef> stringValue(Adopt, JSValueToStringCopy(context, arguments[0], nullptr)); + g_assert(stringValue); + size_t testPathLength = JSStringGetMaximumUTF8CStringSize(stringValue.get()); + GUniquePtr<char> testPath(static_cast<char*>(g_malloc(testPathLength))); + JSStringGetUTF8CString(stringValue.get(), testPath.get(), testPathLength); + + WebKitWebPage* webPage = WEBKIT_WEB_PAGE(JSObjectGetPrivate(thisObject)); + g_assert(WEBKIT_IS_WEB_PAGE(webPage)); + // Test /WebKitDOMNode/dom-cache is an exception, because it's called 3 times, so + // the WebPage is destroyed after the third time. + if (g_str_equal(testPath.get(), "WebKitDOMNode/dom-cache")) { + static unsigned domCacheTestRunCount = 0; + if (++domCacheTestRunCount == 3) + WebProcessTest::assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webPage)); + } else + WebProcessTest::assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webPage)); + + std::unique_ptr<WebProcessTest> test = WebProcessTest::create(String::fromUTF8(testPath.get())); + return JSValueMakeBoolean(context, test->runTest(g_strrstr(testPath.get(), "/") + 1, webPage)); +} + +static const JSStaticFunction webProcessTestRunnerStaticFunctions[] = +{ + { "runTest", runTest, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { nullptr, nullptr, 0 } +}; + +static void webProcessTestRunnerFinalize(JSObjectRef object) +{ + g_object_unref(JSObjectGetPrivate(object)); + + if (s_watchedObjects.isEmpty()) + return; + + g_print("Leaked objects in WebProcess:"); + for (const auto object : s_watchedObjects) + g_print(" %s(%p)", g_type_name_from_instance(reinterpret_cast<GTypeInstance*>(object)), object); + g_print("\n"); + + g_assert(s_watchedObjects.isEmpty()); +} + +static void windowObjectClearedCallback(WebKitScriptWorld* world, WebKitWebPage* webPage, WebKitFrame* frame, WebKitWebExtension* extension) +{ + JSGlobalContextRef context = webkit_frame_get_javascript_context_for_script_world(frame, world); + JSObjectRef globalObject = JSContextGetGlobalObject(context); + + JSClassDefinition classDefinition = kJSClassDefinitionEmpty; + classDefinition.className = "WebProcessTestRunner"; + classDefinition.staticFunctions = webProcessTestRunnerStaticFunctions; + classDefinition.finalize = webProcessTestRunnerFinalize; + + JSClassRef jsClass = JSClassCreate(&classDefinition); + JSObjectRef classObject = JSObjectMake(context, jsClass, g_object_ref(webPage)); + JSRetainPtr<JSStringRef> propertyString(Adopt, JSStringCreateWithUTF8CString("WebProcessTestRunner")); + JSObjectSetProperty(context, globalObject, propertyString.get(), classObject, kJSPropertyAttributeNone, nullptr); + JSClassRelease(jsClass); +} + +extern "C" void webkit_web_extension_initialize(WebKitWebExtension* extension) +{ + g_signal_connect(webkit_script_world_get_default(), "window-object-cleared", G_CALLBACK(windowObjectClearedCallback), extension); +} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebProcessTest.h b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebProcessTest.h new file mode 100644 index 000000000..3715eb91e --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebProcessTest.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <webkit2/webkit-web-extension.h> +#include <wtf/HashMap.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/text/StringHash.h> +#include <wtf/text/WTFString.h> + +class WebProcessTest { +public: + virtual ~WebProcessTest() { } + virtual bool runTest(const char* testName, WebKitWebPage*) = 0; + + static void assertObjectIsDeletedWhenTestFinishes(GObject*); + + static void add(const String& testName, std::function<std::unique_ptr<WebProcessTest> ()>); + static std::unique_ptr<WebProcessTest> create(const String& testName); +}; + +#define REGISTER_TEST(ClassName, TestName) \ + WebProcessTest::add(String::fromUTF8(TestName), ClassName::create) + diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/blank.ico b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/blank.ico Binary files differnew file mode 100644 index 000000000..ea848b991 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/blank.ico diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/boring.html b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/boring.html new file mode 100644 index 000000000..c0eeb49ee --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/boring.html @@ -0,0 +1 @@ +<p>This is a boring HTML file.</p> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/link-title.js b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/link-title.js new file mode 100644 index 000000000..2c824da38 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/link-title.js @@ -0,0 +1 @@ +window.document.getElementById('WebKitLink').title; diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/test-cert.pem b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/test-cert.pem new file mode 100644 index 000000000..b34301f25 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/test-cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB9jCCAV+gAwIBAgIJALeuXBo+vwz9MA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV +BAMMCTEyNy4wLjAuMTAeFw0xMjA3MTIxMjQ4MjRaFw0yMjA3MTAxMjQ4MjRaMBQx +EjAQBgNVBAMMCTEyNy4wLjAuMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +0TUzOQxHBIKDD2mkuq+tU92mQvDZg73B0G+Nhr2T2G6MbcLqIwjg1QYtBZWJ83tZ +xMMEfiweHLF85Z9ohavAgxJlKG7YmvZO79KkFpmjV2W5CVRm0eYMPnzmxNCoaYqo +DLl0zsH6KZOLPKu/fX4eDX9XpAP1f83hWB1UFBmHKN8CAwEAAaNQME4wHQYDVR0O +BBYEFDHv5ZQ1BdmhzTsDUEoY55EXyUdKMB8GA1UdIwQYMBaAFDHv5ZQ1BdmhzTsD +UEoY55EXyUdKMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAh3qMBx7v +jSodMf3OyTqTLE7deLnmnCeBVpgzxRZEoizcGqYcjiqO27i5N5Z6KVQsnITnLiyC +mUtuR5KnF69uTKUw4m/ugZe5whjig5Mq2l410KVK6EeG4tdLlfXR+wi4U5K4KjP6 +p4nchQUXLa2zcbJn+VBexJn6/9wdhr+DUGY= +-----END CERTIFICATE----- diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/test-key.pem b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/test-key.pem new file mode 100644 index 000000000..9036222ce --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/test-key.pem @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANE1MzkMRwSCgw9p +pLqvrVPdpkLw2YO9wdBvjYa9k9hujG3C6iMI4NUGLQWVifN7WcTDBH4sHhyxfOWf +aIWrwIMSZShu2Jr2Tu/SpBaZo1dluQlUZtHmDD585sTQqGmKqAy5dM7B+imTizyr +v31+Hg1/V6QD9X/N4VgdVBQZhyjfAgMBAAECgYB2QwOUsRsIMprRwJ9tJNfvO7G7 +z5i1/zOrlxPC4jHMPBnIBlICwgcOhLI4oOLdr5H8R12n0VqoT7DRwP396iwlJipF +iO1heDMn/8z8LPGwkCK/+ck04rMDksxWIdMwYKBXt9ahnJ/xRLzQ1/3AJiAGnoe5 +/QLXQweofd4mmfsjKQJBAO2CwT7uMP6nMjXgtVMJq5QP8UbeCS1sEOPJJbHuDxJB +/HePQHBjq4kzG6CL4oO7T+5fDv4g+fIIHzuXerZ0imsCQQDhfmiTIc9OucEIfg6/ +ms0JiKSmWc+qoiOCtrILuQvFoNwJRciQANqeJs6wpaDvevSUvBLGfG/7b3HvaE5X +iqBdAkBEQIvp2qcHtuJN60oQF7pPrRknxUyb2e8sljQX4pJAK+gyL19ULMAxiBdL +Vod8VYqNtJFpY+6Pp9fZ1xjzb6ALAkEA4JzrDAw0lQXA+3WduUw4ixOadr2ldyG0 +36KebcDwsfZO18m0Q4UmPz0Gy7zgN0wxzuochaw0W6+iPUiYKOlEXQJBAMWQrPlu +rrinoZS2f8doJ9BNNUa+RNpMug6UXc55qoUJlyiXEh+tu4AaMOtxuGIyC0sAcuw6 +XdAPVPXKd7Mne70= +-----END PRIVATE KEY----- diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/webkit2gtk-tests.gresource.xml b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/webkit2gtk-tests.gresource.xml new file mode 100644 index 000000000..87bc50158 --- /dev/null +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/webkit2gtk-tests.gresource.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<gresources> + <gresource prefix="/org/webkit/webkit2gtk/tests/"> + <file alias="boring.html">Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/boring.html</file> + <file alias="link-title.js">Tools/TestWebKitAPI/Tests/WebKit2Gtk/resources/link-title.js</file> + </gresource> +</gresources> diff --git a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsInvalidScheme.mm b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsInvalidScheme.mm deleted file mode 100644 index bf932cd43..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsInvalidScheme.mm +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformUtilities.h" -#import "PlatformWebView.h" -#import "TestBrowsingContextLoadDelegate.h" -#import <WebKit2/WebKit2.h> -#import <wtf/RetainPtr.h> - -static bool testFinished = false; - -namespace TestWebKitAPI { - -TEST(WebKit2CustomProtocolsTest, RegisterNilScheme) -{ - [WKBrowsingContextController registerSchemeForCustomProtocol:nil]; - [WKBrowsingContextController unregisterSchemeForCustomProtocol:nil]; -} - -TEST(WebKit2CustomProtocolsTest, LoadInvalidScheme) -{ - [WKBrowsingContextController registerSchemeForCustomProtocol:@"custom"]; - WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("CustomProtocolInvalidSchemeTest")); - PlatformWebView webView(context.get()); - - webView.platformView().browsingContextController.loadDelegate = [[TestBrowsingContextLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) { - testFinished = true; - }]; - [webView.platformView().browsingContextController loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"ht'tp://www.webkit.org"]]]; - - Util::run(&testFinished); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsInvalidScheme_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsInvalidScheme_Bundle.cpp index ee72f87e7..287f32ff5 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsInvalidScheme_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsInvalidScheme_Bundle.cpp @@ -25,8 +25,10 @@ #include "config.h" +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" -#include <WebKit2/WKBundlePage.h> +#include <WebKit/WKBundlePage.h> namespace TestWebKitAPI { @@ -45,15 +47,20 @@ public: } private: - virtual void didCreatePage(WKBundleRef, WKBundlePageRef bundlePage) OVERRIDE + virtual void didCreatePage(WKBundleRef, WKBundlePageRef bundlePage) override { - WKBundlePagePolicyClient policyClient; + WKBundlePagePolicyClientV0 policyClient; memset(&policyClient, 0, sizeof(policyClient)); + + policyClient.base.version = 0; policyClient.decidePolicyForNavigationAction = decidePolicyForNavigationAction; - WKBundlePageSetPolicyClient(bundlePage, &policyClient); + + WKBundlePageSetPolicyClient(bundlePage, &policyClient.base); } }; static InjectedBundleTest::Register<CustomProtocolInvalidSchemeTest> registrar("CustomProtocolInvalidSchemeTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsTest.mm b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsTest.mm deleted file mode 100644 index 7eb2d364e..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/CustomProtocolsTest.mm +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 "TestBrowsingContextLoadDelegate.h" -#import "TestProtocol.h" -#import <WebKit2/WebKit2.h> - -static bool testFinished = false; - -namespace TestWebKitAPI { - -TEST(WebKit2CustomProtocolsTest, MainResource) -{ - [NSURLProtocol registerClass:[TestProtocol class]]; - [WKBrowsingContextController registerSchemeForCustomProtocol:[TestProtocol scheme]]; - - WKProcessGroup *processGroup = [[WKProcessGroup alloc] init]; - WKBrowsingContextGroup *browsingContextGroup = [[WKBrowsingContextGroup alloc] initWithIdentifier:@"TestIdentifier"]; - WKView *wkView = [[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) processGroup:processGroup browsingContextGroup:browsingContextGroup]; - wkView.browsingContextController.loadDelegate = [[TestBrowsingContextLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) { - testFinished = true; - }]; - [wkView.browsingContextController loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@://test", [TestProtocol scheme]]]]]; - - Util::run(&testFinished); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing.mm b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing.mm deleted file mode 100644 index 0e86aaa27..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing.mm +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformWebView.h" -#import "TestBrowsingContextLoadDelegate.h" -#import "TestProtocol.h" -#import <WebKit2/WebKit2.h> -#import <WebKit2/WKViewPrivate.h> - -static bool testFinished = false; - -namespace TestWebKitAPI { - -TEST(WebKit2, PreventImageLoadWithAutoResizingTest) -{ - [NSURLProtocol registerClass:[TestProtocol class]]; - [WKBrowsingContextController registerSchemeForCustomProtocol:[TestProtocol scheme]]; - - WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("DenyWillSendRequestTest")); - PlatformWebView webView(context.get()); - - webView.platformView().minimumSizeForAutoLayout = NSMakeSize(400, 300); - webView.platformView().browsingContextController.loadDelegate = [[TestBrowsingContextLoadDelegate alloc] initWithBlockToRunOnLoad:^(WKBrowsingContextController *sender) { - testFinished = true; - }]; - [webView.platformView().browsingContextController loadHTMLString:@"<html><body style='background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFZJREFUeF59z4EJADEIQ1F36k7u5E7ZKXeUQPACJ3wK7UNokVxVk9kHnQH7bY9hbDyDhNXgjpRLqFlo4M2GgfyJHhjq8V4agfrgPQX3JtJQGbofmCHgA/nAKks+JAjFAAAAAElFTkSuQmCC);'></body></html>" baseURL:[NSURL URLWithString:@"about:blank"]]; - - Util::run(&testFinished); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing_Bundle.cpp b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing_Bundle.cpp index 9f73d7541..dde94407a 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing_Bundle.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/PreventImageLoadWithAutoResizing_Bundle.cpp @@ -24,11 +24,14 @@ */ #include "config.h" + +#if WK_HAVE_C_SPI + #include "InjectedBundleTest.h" #include "PlatformUtilities.h" #include "Test.h" -#include <WebKit2/WKBundlePage.h> +#include <WebKit/WKBundlePage.h> #include <wtf/Assertions.h> @@ -48,13 +51,13 @@ public: virtual void didCreatePage(WKBundleRef bundle, WKBundlePageRef page) { - WKBundlePageResourceLoadClient resourceLoadClient; + WKBundlePageResourceLoadClientV0 resourceLoadClient; memset(&resourceLoadClient, 0, sizeof(resourceLoadClient)); - resourceLoadClient.version = 0; + resourceLoadClient.base.version = 0; resourceLoadClient.willSendRequestForFrame = willSendRequestForFrame; - WKBundlePageSetResourceLoadClient(page, &resourceLoadClient); + WKBundlePageSetResourceLoadClient(page, &resourceLoadClient.base); } }; @@ -62,3 +65,5 @@ public: static InjectedBundleTest::Register<DenyWillSendRequestTest> registrar("DenyWillSendRequestTest"); } // namespace TestWebKitAPI + +#endif diff --git a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/UserContentTest.mm b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/UserContentTest.mm deleted file mode 100644 index 025896373..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/UserContentTest.mm +++ /dev/null @@ -1,230 +0,0 @@ -/* - * 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 "TestBrowsingContextLoadDelegate.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"; - -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 = [[TestBrowsingContextLoadDelegate 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 = [[TestBrowsingContextLoadDelegate 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 = [[TestBrowsingContextLoadDelegate 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 = [[TestBrowsingContextLoadDelegate 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 = [[TestBrowsingContextLoadDelegate 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 = [[TestBrowsingContextLoadDelegate 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); -} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKBrowsingContextGroupTest.mm b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKBrowsingContextGroupTest.mm deleted file mode 100644 index fbd87bdf4..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKBrowsingContextGroupTest.mm +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - */ - -#import "config.h" -#import "Test.h" - -#import <WebKit2/WKBrowsingContextGroup.h> - -TEST(WKBrowsingContextGroupTest, GetSetJavaScriptEnabled) -{ - WKBrowsingContextGroup *browsingContextGroup = [[WKBrowsingContextGroup alloc] initWithIdentifier:@"TestIdentifier"]; - - ASSERT_TRUE(browsingContextGroup.allowsJavaScript); - - browsingContextGroup.allowsJavaScript = NO; - - ASSERT_FALSE(browsingContextGroup.allowsJavaScript); - - [browsingContextGroup release]; -} - -TEST(WKBrowsingContextGroupTest, GetSetPluginsEnabled) -{ - WKBrowsingContextGroup *browsingContextGroup = [[WKBrowsingContextGroup alloc] initWithIdentifier:@"TestIdentifier"]; - - ASSERT_TRUE(browsingContextGroup.allowsPlugIns); - - browsingContextGroup.allowsPlugIns = NO; - - ASSERT_FALSE(browsingContextGroup.allowsPlugIns); - - [browsingContextGroup release]; -} diff --git a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKBrowsingContextLoadDelegateTest.mm b/Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKBrowsingContextLoadDelegateTest.mm deleted file mode 100644 index 6cadf0b14..000000000 --- a/Tools/TestWebKitAPI/Tests/WebKit2ObjC/WKBrowsingContextLoadDelegateTest.mm +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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. - */ - -#import "config.h" -#import "Test.h" - -#import <WebKit2/WKBrowsingContextController.h> -#import <WebKit2/WKBrowsingContextGroup.h> -#import <WebKit2/WKBrowsingContextLoadDelegate.h> -#import <WebKit2/WKProcessGroup.h> -#import <WebKit2/WKRetainPtr.h> -#import <WebKit2/WKView.h> - -#import "PlatformUtilities.h" - -namespace { - -class WKBrowsingContextLoadDelegateTest : public ::testing::Test { -public: - WKProcessGroup *processGroup; - WKBrowsingContextGroup *browsingContextGroup; - WKView *view; - - WKBrowsingContextLoadDelegateTest() - : processGroup(nil) - , browsingContextGroup(nil) - , view(nil) - { - } - - virtual void SetUp() - { - processGroup = [[WKProcessGroup alloc] init]; - browsingContextGroup = [[WKBrowsingContextGroup alloc] initWithIdentifier:@"TestIdentifier"]; - view = [[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) processGroup:processGroup browsingContextGroup:browsingContextGroup]; - } - - virtual void TearDown() - { - [view release]; - [browsingContextGroup release]; - [processGroup release]; - } -}; - -} // namespace - -@interface SimpleLoadDelegate : NSObject <WKBrowsingContextLoadDelegate> -{ - bool* _simpleLoadDone; -} - -- (id)initWithFlag:(bool*)flag; - -@end - -@implementation SimpleLoadDelegate - -- (id)initWithFlag:(bool*)flag -{ - self = [super init]; - if (!self) - return nil; - - _simpleLoadDone = flag; - return self; -} - -- (void)browsingContextControllerDidFinishLoad:(WKBrowsingContextController *)sender -{ - *_simpleLoadDone = true; -} - -@end - -TEST_F(WKBrowsingContextLoadDelegateTest, Empty) -{ - // Just make sure the setup/tear down works. -} - -TEST_F(WKBrowsingContextLoadDelegateTest, SimpleLoad) -{ - bool simpleLoadDone = false; - - // Add the load delegate. - SimpleLoadDelegate *loadDelegate = [[SimpleLoadDelegate alloc] initWithFlag:&simpleLoadDone]; - view.browsingContextController.loadDelegate = loadDelegate; - - // Load the file. - NSURL *nsURL = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]; - [view.browsingContextController loadFileURL:nsURL restrictToFilesWithin:nil]; - - // Wait for the load to finish. - TestWebKitAPI::Util::run(&simpleLoadDone); - - // Tear down the delegate. - view.browsingContextController.loadDelegate = nil; - [loadDelegate release]; -} - -TEST_F(WKBrowsingContextLoadDelegateTest, SimpleLoadOfHTMLString) -{ - bool simpleLoadDone = false; - - // Add the load delegate. - SimpleLoadDelegate *loadDelegate = [[SimpleLoadDelegate alloc] initWithFlag:&simpleLoadDone]; - view.browsingContextController.loadDelegate = loadDelegate; - - // Load the HTML string. - [view.browsingContextController loadHTMLString:@"<html><body>Simple HTML String</body></html>" baseURL:[NSURL URLWithString:@"about:blank"]]; - - // Wait for the load to finish. - TestWebKitAPI::Util::run(&simpleLoadDone); - - // Tear down the delegate. - view.browsingContextController.loadDelegate = nil; - [loadDelegate release]; -} - -TEST_F(WKBrowsingContextLoadDelegateTest, SimpleLoadOfHTMLString_NilBaseURL) -{ - bool simpleLoadDone = false; - - // Add the load delegate. - SimpleLoadDelegate *loadDelegate = [[SimpleLoadDelegate alloc] initWithFlag:&simpleLoadDone]; - view.browsingContextController.loadDelegate = loadDelegate; - - // Load the HTML string, pass nil as the baseURL. - [view.browsingContextController loadHTMLString:@"<html><body>Simple HTML String</body></html>" baseURL:nil]; - - // Wait for the load to finish. - TestWebKitAPI::Util::run(&simpleLoadDone); - - // Tear down the delegate. - view.browsingContextController.loadDelegate = nil; - [loadDelegate release]; -} - -TEST_F(WKBrowsingContextLoadDelegateTest, SimpleLoadOfHTMLString_NilHTMLStringAndBaseURL) -{ - bool simpleLoadDone = false; - - // Add the load delegate. - SimpleLoadDelegate *loadDelegate = [[SimpleLoadDelegate alloc] initWithFlag:&simpleLoadDone]; - view.browsingContextController.loadDelegate = loadDelegate; - - // Load the HTML string (as nil). - [view.browsingContextController loadHTMLString:nil baseURL:nil]; - - // Wait for the load to finish. - TestWebKitAPI::Util::run(&simpleLoadDone); - - // Tear down the delegate. - view.browsingContextController.loadDelegate = nil; - [loadDelegate release]; -} - -@interface SimpleLoadFailDelegate : NSObject <WKBrowsingContextLoadDelegate> -{ - bool* _simpleLoadFailDone; -} - -- (id)initWithFlag:(bool*)flag; - -@end - -@implementation SimpleLoadFailDelegate - -- (id)initWithFlag:(bool*)flag -{ - self = [super init]; - if (!self) - return nil; - - _simpleLoadFailDone = flag; - return self; -} - -- (void)browsingContextControllerDidFailProvisionalLoad:(WKBrowsingContextController *)sender withError:(NSError *)error -{ - EXPECT_EQ(-1100, error.code); - EXPECT_WK_STREQ(NSURLErrorDomain, error.domain); - - *_simpleLoadFailDone = true; -} - -@end - -TEST_F(WKBrowsingContextLoadDelegateTest, SimpleLoadFail) -{ - bool simpleLoadFailDone = false; - - // Add the load delegate. - SimpleLoadFailDelegate *loadDelegate = [[SimpleLoadFailDelegate alloc] initWithFlag:&simpleLoadFailDone]; - view.browsingContextController.loadDelegate = loadDelegate; - - // Load a non-existent file. - NSURL *nsURL = [NSURL URLWithString:@"file:///does-not-exist.html"]; - [view.browsingContextController loadFileURL:nsURL restrictToFilesWithin:nil]; - - // Wait for the load to fail. - TestWebKitAPI::Util::run(&simpleLoadFailDone); - - // Tear down the delegate. - view.browsingContextController.loadDelegate = nil; - [loadDelegate release]; -} diff --git a/Tools/TestWebKitAPI/Tests/gtk/InputMethodFilter.cpp b/Tools/TestWebKitAPI/Tests/gtk/InputMethodFilter.cpp deleted file mode 100644 index bfcc17dcc..000000000 --- a/Tools/TestWebKitAPI/Tests/gtk/InputMethodFilter.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * 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 "GtkInputMethodFilter.h" -#include "WTFStringUtilities.h" -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <wtf/gobject/GOwnPtr.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/text/CString.h> - -using namespace WebCore; - -namespace TestWebKitAPI { - -class TestInputMethodFilter : public GtkInputMethodFilter { -public: - TestInputMethodFilter() - : m_testWindow(gtk_window_new(GTK_WINDOW_POPUP)) - { - gtk_widget_show(m_testWindow.get()); - setWidget(m_testWindow.get()); - - // Focus in is necessary to activate the default input method in the multicontext. - notifyFocusedIn(); - } - - Vector<String>& events() { return m_events; } - - void sendKeyEventToFilter(unsigned int gdkKeyValue, GdkEventType type, unsigned int modifiers = 0) - { - GdkEvent* event = gdk_event_new(type); - event->key.keyval = gdkKeyValue; - event->key.state = modifiers; - event->key.window = gtk_widget_get_window(m_testWindow.get()); - event->key.time = GDK_CURRENT_TIME; - g_object_ref(event->key.window); - -#ifndef GTK_API_VERSION_2 - gdk_event_set_device(event, gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gdk_display_get_default()))); -#endif - - GOwnPtr<GdkKeymapKey> keys; - gint nKeys; - if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeyValue, &keys.outPtr(), &nKeys)) - event->key.hardware_keycode = keys.get()[0].keycode; - - filterKeyEvent(&event->key); - gdk_event_free(event); - } - - void sendPressAndReleaseKeyEventPairToFilter(unsigned int gdkKeyValue, unsigned int modifiers = 0) - { - sendKeyEventToFilter(gdkKeyValue, GDK_KEY_PRESS, modifiers); - sendKeyEventToFilter(gdkKeyValue, GDK_KEY_RELEASE, modifiers); - } - -protected: - virtual bool sendSimpleKeyEvent(GdkEventKey* event, WTF::String eventString, EventFakedForComposition faked) - { - const char* eventType = event->type == GDK_KEY_RELEASE ? "release" : "press"; - const char* fakedString = faked == EventFaked ? " (faked)" : ""; - if (!eventString.isNull()) - m_events.append(String::format("sendSimpleKeyEvent type=%s keycode=%x text='%s'%s", eventType, event->keyval, eventString.utf8().data(), fakedString)); - else - m_events.append(String::format("sendSimpleKeyEvent type=%s keycode=%x%s", eventType, event->keyval, fakedString)); - - return true; - } - - virtual bool sendKeyEventWithCompositionResults(GdkEventKey* event, ResultsToSend resultsToSend, EventFakedForComposition faked) - { - const char* eventType = event->type == GDK_KEY_RELEASE ? "release" : "press"; - const char* fakedString = faked == EventFaked ? " (faked)" : ""; - m_events.append(String::format("sendKeyEventWithCompositionResults type=%s keycode=%u%s", eventType, event->keyval, fakedString)); - - if (resultsToSend & Composition && !m_confirmedComposition.isNull()) - confirmCompositionText(m_confirmedComposition); - if (resultsToSend & Preedit && !m_preedit.isNull()) - setPreedit(m_preedit, m_cursorOffset); - - return true; - } - - virtual bool canEdit() - { - return true; - } - - virtual void confirmCompositionText(String text) - { - m_events.append(String::format("confirmComposition '%s'", text.utf8().data())); - } - - virtual void confirmCurrentComposition() - { - m_events.append(String("confirmCurrentcomposition")); - } - - virtual void cancelCurrentComposition() - { - m_events.append(String("cancelCurrentComposition")); - } - - virtual void setPreedit(String preedit, int cursorOffset) - { - m_events.append(String::format("setPreedit text='%s' cursorOffset=%i", preedit.utf8().data(), cursorOffset)); - } - -private: - GRefPtr<GtkWidget> m_testWindow; - Vector<String> m_events; -}; - -TEST(GTK, GtkInputMethodFilterSimple) -{ - TestInputMethodFilter inputMethodFilter; - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_g); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_t); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_k); - - const Vector<String>& events = inputMethodFilter.events(); - - ASSERT_EQ(6, events.size()); - ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=67 text='g'"), events[0]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=67"), events[1]); - ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=74 text='t'"), events[2]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=74"), events[3]); - ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=6b text='k'"), events[4]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=6b"), events[5]); -} - -TEST(GTK, GtkInputMethodFilterUnicodeSequence) -{ - TestInputMethodFilter inputMethodFilter; - - // This is simple unicode hex entry of the characters, u, 0, 0, f, 4 pressed with - // the shift and controls keys held down. In reality, these values are not typical - // of an actual hex entry, because they'd be transformed by the shift modifier according - // to the keyboard layout. For instance, on a US keyboard a 0 with the shift key pressed - // is a right parenthesis. Using these values prevents having to work out what the - // transformed characters are based on the current keyboard layout. - inputMethodFilter.sendKeyEventToFilter(GDK_KEY_Control_L, GDK_KEY_PRESS); - inputMethodFilter.sendKeyEventToFilter(GDK_KEY_Shift_L, GDK_KEY_PRESS, GDK_CONTROL_MASK); - - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_U, GDK_SHIFT_MASK | GDK_CONTROL_MASK); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_0, GDK_SHIFT_MASK | GDK_CONTROL_MASK); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_0, GDK_SHIFT_MASK | GDK_CONTROL_MASK); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_F, GDK_SHIFT_MASK | GDK_CONTROL_MASK); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_4, GDK_SHIFT_MASK | GDK_CONTROL_MASK); - - inputMethodFilter.sendKeyEventToFilter(GDK_KEY_Shift_L, GDK_KEY_RELEASE, GDK_CONTROL_MASK | GDK_SHIFT_MASK); - inputMethodFilter.sendKeyEventToFilter(GDK_KEY_Control_L, GDK_KEY_RELEASE, GDK_CONTROL_MASK); - - const Vector<String>& events = inputMethodFilter.events(); - ASSERT_EQ(21, events.size()); - ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=ffe3"), events[0]); - ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=ffe1"), events[1]); - ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=85"), events[2]); - ASSERT_EQ(String("setPreedit text='u' cursorOffset=1"), events[3]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=55"), events[4]); - ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=48"), events[5]); - ASSERT_EQ(String("setPreedit text='u0' cursorOffset=2"), events[6]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=30"), events[7]); - ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=48"), events[8]); - ASSERT_EQ(String("setPreedit text='u00' cursorOffset=3"), events[9]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=30"), events[10]); - ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=70"), events[11]); - ASSERT_EQ(String("setPreedit text='u00F' cursorOffset=4"), events[12]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=46"), events[13]); - ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=52"), events[14]); - ASSERT_EQ(String("setPreedit text='u00F4' cursorOffset=5"), events[15]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=34"), events[16]); - ASSERT_EQ(String("confirmComposition 'ô'"), events[17]); - ASSERT_EQ(String("setPreedit text='' cursorOffset=0"), events[18]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffe1"), events[19]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffe3"), events[20]); -} - -TEST(GTK, GtkInputMethodFilterComposeKey) -{ - TestInputMethodFilter inputMethodFilter; - - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_Multi_key); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_apostrophe); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_o); - - const Vector<String>& events = inputMethodFilter.events(); - ASSERT_EQ(5, events.size()); - ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=39"), events[0]); - ASSERT_EQ(String("setPreedit text='' cursorOffset=0"), events[1]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=27"), events[2]); - ASSERT_EQ(String("sendSimpleKeyEvent type=press keycode=6f text='ó'"), events[3]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=6f"), events[4]); -} - -typedef void (*GetPreeditStringCallback) (GtkIMContext*, gchar**, PangoAttrList**, int*); -static void temporaryGetPreeditStringOverride(GtkIMContext*, char** string, PangoAttrList** attrs, int* cursorPosition) -{ - *string = g_strdup("preedit of doom, bringer of cheese"); - *cursorPosition = 3; -} - -TEST(GTK, GtkInputMethodFilterContextEventsWithoutKeyEvents) -{ - TestInputMethodFilter inputMethodFilter; - - // This is a bit of a hack to avoid mocking out the entire InputMethodContext, by - // simply replacing the get_preedit_string virtual method for the length of this test. - GtkIMContext* context = inputMethodFilter.context(); - GtkIMContextClass* contextClass = GTK_IM_CONTEXT_GET_CLASS(context); - GetPreeditStringCallback previousCallback = contextClass->get_preedit_string; - contextClass->get_preedit_string = temporaryGetPreeditStringOverride; - - g_signal_emit_by_name(context, "preedit-changed"); - g_signal_emit_by_name(context, "commit", "commit text"); - - contextClass->get_preedit_string = previousCallback; - - const Vector<String>& events = inputMethodFilter.events(); - ASSERT_EQ(6, events.size()); - ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=16777215 (faked)"), events[0]); - ASSERT_EQ(String("setPreedit text='preedit of doom, bringer of cheese' cursorOffset=3"), events[1]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffffff (faked)"), events[2]); - ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=16777215 (faked)"), events[3]); - ASSERT_EQ(String("confirmComposition 'commit text'"), events[4]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=ffffff (faked)"), events[5]); -} - -static bool gSawContextReset = false; -typedef void (*ResetCallback) (GtkIMContext*); -static void temporaryResetOverride(GtkIMContext*) -{ - gSawContextReset = true; -} - -static void verifyCanceledComposition(const Vector<String>& events) -{ - ASSERT_EQ(3, events.size()); - ASSERT_EQ(String("sendKeyEventWithCompositionResults type=press keycode=39"), events[0]); - ASSERT_EQ(String("setPreedit text='' cursorOffset=0"), events[1]); - ASSERT_EQ(String("sendSimpleKeyEvent type=release keycode=27"), events[2]); - ASSERT(gSawContextReset); -} - -TEST(GTK, GtkInputMethodFilterContextFocusOutDuringOngoingComposition) -{ - TestInputMethodFilter inputMethodFilter; - - // See comment above about this technique. - GtkIMContext* context = inputMethodFilter.context(); - GtkIMContextClass* contextClass = GTK_IM_CONTEXT_GET_CLASS(context); - ResetCallback previousCallback = contextClass->reset; - contextClass->reset = temporaryResetOverride; - - gSawContextReset = false; - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_Multi_key); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_apostrophe); - inputMethodFilter.notifyFocusedOut(); - - verifyCanceledComposition(inputMethodFilter.events()); - - contextClass->reset = previousCallback; -} - -TEST(GTK, GtkInputMethodFilterContextMouseClickDuringOngoingComposition) -{ - TestInputMethodFilter inputMethodFilter; - - // See comment above about this technique. - GtkIMContext* context = inputMethodFilter.context(); - GtkIMContextClass* contextClass = GTK_IM_CONTEXT_GET_CLASS(context); - ResetCallback previousCallback = contextClass->reset; - contextClass->reset = temporaryResetOverride; - - gSawContextReset = false; - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_Multi_key); - inputMethodFilter.sendPressAndReleaseKeyEventPairToFilter(GDK_KEY_apostrophe); - inputMethodFilter.notifyMouseButtonPress(); - - verifyCanceledComposition(inputMethodFilter.events()); - - contextClass->reset = previousCallback; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/0.png b/Tools/TestWebKitAPI/Tests/mac/0.png Binary files differdeleted file mode 100644 index 649d1adf5..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/0.png +++ /dev/null diff --git a/Tools/TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm b/Tools/TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm deleted file mode 100644 index dec788804..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/AcceptsFirstMouse.mm +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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. - */ - -#include "config.h" -#include "WebKitAgnosticTest.h" - -#include <wtf/RetainPtr.h> - -@interface NSApplication (TestWebKitAPINSApplicationDetails) -- (void)_setCurrentEvent:(NSEvent *)event; -@end - -namespace TestWebKitAPI { - -class AcceptsFirstMouse : public WebKitAgnosticTest { -public: - template <typename View> void runTest(View); - - // WebKitAgnosticTest - virtual NSURL *url() const { return [[NSBundle mainBundle] URLForResource:@"acceptsFirstMouse" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]; } - virtual void didLoadURL(WebView *webView) { runTest(webView); } - virtual void didLoadURL(WKView *wkView) { runTest(wkView); } -}; - -template <typename View> -void AcceptsFirstMouse::runTest(View view) -{ - RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:view.frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]); - [[window.get() contentView] addSubview:view]; - - CGFloat viewHeight = view.bounds.size.height; - - NSPoint pointInsideSelection = NSMakePoint(50, viewHeight - 50); - NSEvent *mouseEventInsideSelection = [NSEvent mouseEventWithType:NSLeftMouseDown location:pointInsideSelection modifierFlags:0 timestamp:0 windowNumber:[window.get() windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]; - EXPECT_TRUE([[view hitTest:pointInsideSelection] acceptsFirstMouse:mouseEventInsideSelection]); - - NSPoint pointOutsideSelection = NSMakePoint(50, viewHeight - 150); - NSEvent *mouseEventOutsideSelection = [NSEvent mouseEventWithType:NSLeftMouseDown location:pointOutsideSelection modifierFlags:0 timestamp:0 windowNumber:[window.get() windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]; - EXPECT_FALSE([[view hitTest:pointInsideSelection] acceptsFirstMouse:mouseEventOutsideSelection]); -} - -TEST_F(AcceptsFirstMouse, WebKit) -{ - // Ensure that [NSApp currentEvent] is not a previously-simulated spacebar key press, since this - // causes the scrollBy() in the test to perform a smooth scroll. - [NSApp _setCurrentEvent:nil]; - runWebKit1Test(); -} - -TEST_F(AcceptsFirstMouse, WebKit2) -{ - runWebKit2Test(); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/AttributedString.mm b/Tools/TestWebKitAPI/Tests/mac/AttributedString.mm deleted file mode 100644 index 6386cad5f..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/AttributedString.mm +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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. - */ - -#include "config.h" -#include "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <wtf/RetainPtr.h> - - -@interface AttributedStringTest : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation AttributedStringTest - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} -@end - -namespace TestWebKitAPI { - -static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void*) -{ - didFinishLoad = true; -} - -TEST(WebKit1, AttributedStringTest) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<AttributedStringTest> testController = adoptNS([AttributedStringTest new]); - - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"attributedStringCustomFont" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - didFinishLoad = false; - - NSAttributedString *attrString = [(NSView <NSTextInput> *)[[[webView.get() mainFrame] frameView] documentView] attributedSubstringFromRange:NSMakeRange(0, 5)]; - - EXPECT_WK_STREQ("Lorem", [attrString string]); -} - -TEST(WebKit2, AttributedStringTest) -{ - WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); - PlatformWebView webView(context.get()); - - WKPageLoaderClient loaderClient; - memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - WKPageSetPageLoaderClient(webView.page(), &loaderClient); - - WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("attributedStringCustomFont", "html")).get()); - - Util::run(&didFinishLoad); - didFinishLoad = false; - - NSRange range = NSMakeRange(0, 5); - NSRange actualRange; - NSAttributedString *attrString = [webView.platformView() attributedSubstringForProposedRange:range actualRange:&actualRange]; - - EXPECT_WK_STREQ("Lorem", [attrString string]); -} - - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/BackForwardList.mm b/Tools/TestWebKitAPI/Tests/mac/BackForwardList.mm deleted file mode 100644 index 82ddb3830..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/BackForwardList.mm +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - */ - -#include "config.h" -#include "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <wtf/RetainPtr.h> - -#include <WebKit/WebBackForwardList.h> - -@interface BackForwardListTest : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation BackForwardListTest - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame -{ - [frame loadAlternateHTMLString:@"<html></html>" baseURL:[NSURL URLWithString:@"about:blank"] forUnreachableURL:[[error userInfo] valueForKey:NSURLErrorFailingURLErrorKey]]; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, ReloadBackForward) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<BackForwardListTest> testController = adoptNS([BackForwardListTest new]); - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://does-not-exist.example"]]]; - Util::run(&didFinishLoad); - didFinishLoad = false; - - [[webView.get() mainFrame] reload]; - Util::run(&didFinishLoad); - didFinishLoad = false; - - WebBackForwardList *bfList = [webView.get() backForwardList]; - EXPECT_EQ(0, [bfList backListCount]); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/CancelLoadFromResourceLoadDelegate.html b/Tools/TestWebKitAPI/Tests/mac/CancelLoadFromResourceLoadDelegate.html deleted file mode 100644 index efa4d1e37..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/CancelLoadFromResourceLoadDelegate.html +++ /dev/null @@ -1,8 +0,0 @@ -<script> - function cancelLoadAndJumpToBlank() { - window.stop(); - window.location = "about:blank"; - } -</script> -<img src="Ahem.ttf"> -<script src="about:blank"></script>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/Tests/mac/CancelLoadFromResourceLoadDelegate.mm b/Tools/TestWebKitAPI/Tests/mac/CancelLoadFromResourceLoadDelegate.mm deleted file mode 100644 index 9a19f936c..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/CancelLoadFromResourceLoadDelegate.mm +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#import <wtf/RetainPtr.h> - -@interface CancelLoadFromResourceLoadDelegate : NSObject { - size_t resourceCount; -} - -@end - -@implementation CancelLoadFromResourceLoadDelegate - -- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource -{ - // Break the load once we have loaded the <script> and <img>. - ++resourceCount; - if (resourceCount > 2) - [sender stringByEvaluatingJavaScriptFromString:@"cancelLoadAndJumpToBlank()"]; -} -@end - - -static bool didFinishLoad = false; - -@interface CancelLoadFromResourceLoadDelegateFrameLoadDelegate : NSObject -@end - -@implementation CancelLoadFromResourceLoadDelegateFrameLoadDelegate -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - if ([[sender mainFrameURL] isEqualToString:@"about:blank"]) - didFinishLoad = true; -} -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, CancelLoadFromResourceLoadDelegate) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - - RetainPtr<CancelLoadFromResourceLoadDelegate> resourceLoadDelegate = adoptNS([[CancelLoadFromResourceLoadDelegate alloc] init]); - webView.get().resourceLoadDelegate = resourceLoadDelegate.get(); - RetainPtr<CancelLoadFromResourceLoadDelegateFrameLoadDelegate> frameLoadDelegate = adoptNS([[CancelLoadFromResourceLoadDelegateFrameLoadDelegate alloc] init]); - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"CancelLoadFromResourceLoadDelegate" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - - [pool drain]; - // If we finished without crashing, the test passed. -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/CloseNewWindowInNavigationPolicyDelegate.mm b/Tools/TestWebKitAPI/Tests/mac/CloseNewWindowInNavigationPolicyDelegate.mm deleted file mode 100644 index 367378609..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/CloseNewWindowInNavigationPolicyDelegate.mm +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformUtilities.h" -#import <wtf/RetainPtr.h> - -static bool testFinished = false; - -@interface TestDelegate : NSObject - -+ (TestDelegate *)shared; - -@end - -@implementation TestDelegate - -+ (TestDelegate *)shared -{ - static TestDelegate *sharedTestDelegate = [[TestDelegate alloc] init]; - return sharedTestDelegate; -} - -- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener -{ - if (!request) { - [listener use]; - return; - } - - [webView close]; - [listener ignore]; - testFinished = true; -} - -- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request -{ - WebView *webView = [[WebView alloc] init]; - webView.policyDelegate = [TestDelegate shared]; - [[webView mainFrame] loadRequest:request]; - return webView; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, CloseNewWindowInNavigationPolicyDelegate) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - RetainPtr<WebView> webView = adoptNS([[WebView alloc] init]); - webView.get().preferences.javaScriptCanOpenWindowsAutomatically = YES; - webView.get().UIDelegate = [TestDelegate shared]; - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"OpenNewWindow" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&testFinished); - - [pool drain]; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/ContextMenuCanCopyURL.html b/Tools/TestWebKitAPI/Tests/mac/ContextMenuCanCopyURL.html deleted file mode 100644 index 3147603ce..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/ContextMenuCanCopyURL.html +++ /dev/null @@ -1,4 +0,0 @@ -<head> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -</head> -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<a href='http://www.webkit.org/'>Click me</a>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<a href='http://xn--ls8h.la/'>http://💩.la</a>.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/Tests/mac/ContextMenuCanCopyURL.mm b/Tools/TestWebKitAPI/Tests/mac/ContextMenuCanCopyURL.mm deleted file mode 100644 index f79535f64..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/ContextMenuCanCopyURL.mm +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#import "PlatformWebView.h" -#import "WTFStringUtilities.h" - -#import <WebKit/WebViewPrivate.h> -#import <WebKit/WebURLsWithTitles.h> -#import <WebKit/DOM.h> -#import <Carbon/Carbon.h> -#import <wtf/RetainPtr.h> - - -@interface ContextMenuCanCopyURLDelegate : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation ContextMenuCanCopyURLDelegate - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -@end - -namespace TestWebKitAPI { - -static void contextMenuCopyLink(WebView* webView, int itemIndex) -{ - [[[[webView mainFrame] frameView] documentView] layout]; - - DOMDocument *document = [[webView mainFrame] DOMDocument]; - DOMElement *documentElement = [document documentElement]; - DOMHTMLAnchorElement *anchor = (DOMHTMLAnchorElement *)[[documentElement querySelectorAll:@"a"] item:itemIndex]; - - NSWindow *window = [webView window]; - NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown - location:NSMakePoint(anchor.offsetLeft + anchor.offsetWidth / 2, window.frame.size.height - (anchor.offsetTop + anchor.offsetHeight / 2)) - modifierFlags:0 - timestamp:GetCurrentEventTime() - windowNumber:[window windowNumber] - context:[NSGraphicsContext currentContext] - eventNumber:0 - clickCount:0 - pressure:0.0]; - - NSView *subView = [webView hitTest:[event locationInWindow]]; - if (!subView) - return; - - NSMenu* menu = [subView menuForEvent:event]; - for (int i = 0; i < [menu numberOfItems]; ++i) { - NSMenuItem* menuItem = [menu itemAtIndex:i]; - if ([menuItem tag] != WebMenuItemTagCopyLinkToClipboard) - continue; - - [menu performActionForItemAtIndex:i]; - } -} - - -TEST(WebKit1, ContextMenuCanCopyURL) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0,0,800,600) frameName:nil groupName:nil]); - RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:NSMakeRect(100, 100, 800, 600) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]); - RetainPtr<ContextMenuCanCopyURLDelegate> delegate = adoptNS([[ContextMenuCanCopyURLDelegate alloc] init]); - - [window.get().contentView addSubview:webView.get()]; - webView.get().frameLoadDelegate = delegate.get(); - - [webView.get().mainFrame loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"ContextMenuCanCopyURL" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - - contextMenuCopyLink(webView.get(), 0); - - NSURL *url = [NSURL URLFromPasteboard:[NSPasteboard generalPasteboard]]; - EXPECT_EQ(String("http://www.webkit.org/"), String([url absoluteString])); - - contextMenuCopyLink(webView.get(), 1); - - NSArray * urls = [WebURLsWithTitles URLsFromPasteboard: [NSPasteboard generalPasteboard]]; - NSArray * titles = [WebURLsWithTitles titlesFromPasteboard: [NSPasteboard generalPasteboard]]; - EXPECT_WK_STREQ(@"http://xn--ls8h.la/", [[urls objectAtIndex:0] absoluteString]); - EXPECT_WK_STREQ(@"http://💩.la", [titles objectAtIndex:0]); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/DOMHTMLTableCellCellAbove.mm b/Tools/TestWebKitAPI/Tests/mac/DOMHTMLTableCellCellAbove.mm deleted file mode 100644 index 2c8ca3986..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/DOMHTMLTableCellCellAbove.mm +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <wtf/RetainPtr.h> - -#import <WebKit/DOMPrivate.h> -#import <WebKit/WebViewPrivate.h> - -@interface HTMLTableCellElementCellAboveTest : NSObject -@end - -static bool didFinishLoad; - -@implementation HTMLTableCellElementCellAboveTest - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} -@end - -namespace TestWebKitAPI { - -static void expectCellAboveCell(DOMDocument *document, NSString *cellID, NSString *cellAboveID) -{ - DOMHTMLTableCellElement *cell = (DOMHTMLTableCellElement *)[document getElementById:cellID]; - DOMHTMLTableCellElement *cellAbove = [cell _cellAbove]; - - EXPECT_WK_STREQ(cellAboveID, [cellAbove getAttribute:@"id"]); -} - -TEST(WebKit1, HTMLTableCellElementCellAbove) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<HTMLTableCellElementCellAboveTest> testController = adoptNS([HTMLTableCellElementCellAboveTest new]); - - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] - URLForResource:@"DOMHTMLTableCellElementCellAbove" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - didFinishLoad = false; - - DOMDocument *document = webView.get().mainFrameDocument; - - expectCellAboveCell(document, @"cell-4-2", @"cell-3-2"); - expectCellAboveCell(document, @"cell-3-1", @"cell-2-1"); - expectCellAboveCell(document, @"cell-2-1", @"cell-1-1"); - expectCellAboveCell(document, @"cell-1-2", @"cell-h-2"); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/DOMHTMLTableCellElementCellAbove.html b/Tools/TestWebKitAPI/Tests/mac/DOMHTMLTableCellElementCellAbove.html deleted file mode 100644 index 79135fd27..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/DOMHTMLTableCellElementCellAbove.html +++ /dev/null @@ -1,30 +0,0 @@ -<!DOCTYPE html> -<body> - <table> - <tbody> - <tr> - <td id="cell-1-1">1-1</td> - <td id="cell-1-2">1-2</td> - </tr> - <tr> - <td id="cell-2-1">2-1</td> - <td id="cell-2-2">2-2</td> - </tr> - </tbody> - <thead> - <tr> - <th id="cell-h-1">h-1</th> - <th id="cell-h-2">h-2</th> - </tr> - </thead> - <tbody> - <tr> - <td id="cell-3-1">3-1</td> - <td id="cell-3-2">3-2</td> - </tr> - <tr> - <td id="cell-4-1">4-1</td> - <td id="cell-4-2">4-2</td> - </tr> - </tbody> -</body> diff --git a/Tools/TestWebKitAPI/Tests/mac/DOMNodeFromJSObject.mm b/Tools/TestWebKitAPI/Tests/mac/DOMNodeFromJSObject.mm deleted file mode 100644 index 7bd23ea98..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/DOMNodeFromJSObject.mm +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2013 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 <JavaScriptCore/JSRetainPtr.h> -#import <WebKit/DOMPrivate.h> -#import <WebKit/WebFramePrivate.h> -#import <WebKit/WebScriptWorld.h> -#import <objc/runtime.h> - -namespace TestWebKitAPI { - -TEST(WebKit1, DOMNodeFromJSObject) -{ - WebView *webView = [[WebView alloc] initWithFrame:NSZeroRect frameName:nil groupName:nil]; - - [webView stringByEvaluatingJavaScriptFromString:@"document.body.mainWorldProperty = true"]; - - WebScriptWorld *isolatedWorld = [WebScriptWorld world]; - JSGlobalContextRef context = [[webView mainFrame] _globalContextForScriptWorld:isolatedWorld]; - - JSRetainPtr<JSStringRef> script(Adopt, JSStringCreateWithUTF8CString("document.body")); - - JSValueRef value = JSEvaluateScript(context, script.get(), 0, 0, 0, 0); - JSObjectRef jsBody = JSValueToObject(context, value, 0); - - id objcBody = [DOMNode _nodeFromJSWrapper:jsBody]; - - EXPECT_STREQ("DOMHTMLBodyElement", class_getName([objcBody class])); - EXPECT_EQ([[[webView mainFrame] DOMDocument] body], objcBody); - - // Verify that the Objective-C wrapper is for the main world JS wrapper. - EXPECT_TRUE([[objcBody valueForKey:@"mainWorldProperty"] boolValue]); - - [webView release]; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/DOMRangeOfString.html b/Tools/TestWebKitAPI/Tests/mac/DOMRangeOfString.html deleted file mode 100644 index 539cc0a53..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/DOMRangeOfString.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE html> -<html> -<body> - There is only a single needle in this stack of hay. - <iframe src="data:text/html, - There are no feathers in here. - "></iframe> -</body> -</html> diff --git a/Tools/TestWebKitAPI/Tests/mac/DOMRangeOfString.mm b/Tools/TestWebKitAPI/Tests/mac/DOMRangeOfString.mm deleted file mode 100644 index a4485178d..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/DOMRangeOfString.mm +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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. - */ - -#import "config.h" -#import "PlatformUtilities.h" -#import <WebKit/WebViewPrivate.h> -#import <WebKit/DOM.h> -#import <wtf/RetainPtr.h> - -@interface DOMRangeOfStringFrameLoadDelegate : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation DOMRangeOfStringFrameLoadDelegate - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, DOMRangeOfString) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSZeroRect frameName:nil groupName:nil]); - RetainPtr<DOMRangeOfStringFrameLoadDelegate> frameLoadDelegate = adoptNS([DOMRangeOfStringFrameLoadDelegate new]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"DOMRangeOfString" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - - DOMRange *resultRange = [webView.get() DOMRangeOfString:@"needles" relativeTo:nil options:0]; - EXPECT_EQ(nil, resultRange); - - DOMRange *needleRange = [webView.get() DOMRangeOfString:@"needle" relativeTo:nil options:0]; - EXPECT_EQ(28, needleRange.startOffset); - - resultRange = [webView.get() DOMRangeOfString:@"stack" relativeTo:needleRange options:0]; - EXPECT_EQ(43, resultRange.startOffset); - - resultRange = [webView.get() DOMRangeOfString:@"stack" relativeTo:needleRange options:WebFindOptionsBackwards]; - EXPECT_EQ(nil, resultRange); - - resultRange = [webView.get() DOMRangeOfString:@"n" relativeTo:needleRange options:0]; - EXPECT_EQ(36, resultRange.startOffset); - - resultRange = [webView.get() DOMRangeOfString:@"n" relativeTo:needleRange options:WebFindOptionsStartInSelection]; - EXPECT_EQ(28, resultRange.startOffset); - - RetainPtr<WebView> otherWebView = adoptNS([[WebView alloc] initWithFrame:NSZeroRect frameName:nil groupName:nil]); - DOMRange *foreignRange = [[[otherWebView.get() mainFrame] DOMDocument] createRange]; - resultRange = [webView.get() DOMRangeOfString:@"needle" relativeTo:foreignRange options:0]; - EXPECT_EQ(nil, resultRange); - - resultRange = [webView.get() DOMRangeOfString:@"here" relativeTo:needleRange options:0]; - EXPECT_EQ(1, resultRange.startOffset); - - resultRange = [webView.get() DOMRangeOfString:@"here" relativeTo:resultRange options:0]; - EXPECT_EQ(25, resultRange.startOffset); - - resultRange = [webView.get() DOMRangeOfString:@"here" relativeTo:resultRange options:WebFindOptionsWrapAround]; - EXPECT_EQ(6, resultRange.startOffset); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/DeviceScaleFactorInDashboardRegions.mm b/Tools/TestWebKitAPI/Tests/mac/DeviceScaleFactorInDashboardRegions.mm deleted file mode 100644 index 68ecbf819..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/DeviceScaleFactorInDashboardRegions.mm +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#import "SyntheticBackingScaleFactorWindow.h" -#import "Test.h" -#import <WebKit/WebDashboardRegion.h> -#import <wtf/RetainPtr.h> - -static bool gotDashboardRegions; -static NSDictionary *regions; - -@interface DeviceScaleFactorInDashboardRegionsUIDelegate : NSObject { -} -@end - -@implementation DeviceScaleFactorInDashboardRegionsUIDelegate - -- (void)webView:(WebView *)webView dashboardRegionsChanged:(NSDictionary *)newRegions -{ - gotDashboardRegions = true; - regions = [newRegions retain]; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, DeviceScaleFactorInDashboardRegions) -{ - NSRect viewFrame = NSMakeRect(0, 0, 800, 600); - RetainPtr<SyntheticBackingScaleFactorWindow> window = adoptNS([[SyntheticBackingScaleFactorWindow alloc] initWithContentRect:viewFrame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]); - [window.get() setReleasedWhenClosed:NO]; - [window.get() setBackingScaleFactor:2]; - - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:viewFrame frameName:nil groupName:nil]); - RetainPtr<DeviceScaleFactorInDashboardRegionsUIDelegate> uiDelegate = adoptNS([DeviceScaleFactorInDashboardRegionsUIDelegate new]); - webView.get().UIDelegate = uiDelegate.get(); - [window.get().contentView addSubview:webView.get()]; - - [webView.get().mainFrame loadHTMLString:@"<div style='position: absolute; top: 10px; left: 10px; width: 50px; height: 50px; -webkit-dashboard-region: dashboard-region(control rectangle);'></div>" baseURL:[NSURL URLWithString:@"about:blank"]]; - - Util::run(&gotDashboardRegions); - - NSRect controlRegionRect = [[[regions objectForKey:@"control"] objectAtIndex:0] dashboardRegionRect]; - - EXPECT_EQ(10, controlRegionRect.origin.x); - EXPECT_EQ(10, controlRegionRect.origin.y); - EXPECT_EQ(50, controlRegionRect.size.width); - EXPECT_EQ(50, controlRegionRect.size.height); - - [regions release]; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/DeviceScaleFactorOnBack.mm b/Tools/TestWebKitAPI/Tests/mac/DeviceScaleFactorOnBack.mm deleted file mode 100644 index 8c454282a..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/DeviceScaleFactorOnBack.mm +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 "WebKitAgnosticTest.h" - -#include "JavaScriptTest.h" -#include "PlatformUtilities.h" -#include "SyntheticBackingScaleFactorWindow.h" -#include <WebKit2/WKViewPrivate.h> -#include <wtf/RetainPtr.h> - -namespace TestWebKitAPI { - -class DeviceScaleFactorOnBack : public WebKitAgnosticTest { -public: - RetainPtr<SyntheticBackingScaleFactorWindow> createWindow(); - - template <typename View> void runTest(View); - - // WebKitAgnosticTest - virtual NSURL *url() const { return [[NSBundle mainBundle] URLForResource:@"devicePixelRatio" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]; } - virtual void didLoadURL(WebView *webView) { runTest(webView); } - virtual void didLoadURL(WKView *wkView) { runTest(wkView); } - virtual void initializeView(WebView *); - virtual void initializeView(WKView *); -}; - -RetainPtr<SyntheticBackingScaleFactorWindow> DeviceScaleFactorOnBack::createWindow() -{ - RetainPtr<SyntheticBackingScaleFactorWindow> window = adoptNS([[SyntheticBackingScaleFactorWindow alloc] initWithContentRect:viewFrame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]); - [window.get() setReleasedWhenClosed:NO]; - return window; -} - -void DeviceScaleFactorOnBack::initializeView(WebView *view) -{ - // The default cache model has a capacity of 0, so it is necessary to switch to a cache - // model that actuall caches things. - [[view preferences] setCacheModel:WebCacheModelDocumentBrowser]; -} - -void DeviceScaleFactorOnBack::initializeView(WKView *view) -{ - // The default cache model has a capacity of 0, so it is necessary to switch to a cache - // model that actuall caches things. - WKContextSetCacheModel(WKPageGetContext([view pageRef]), kWKCacheModelDocumentBrowser); -} - -template <typename View> -void DeviceScaleFactorOnBack::runTest(View view) -{ - EXPECT_JS_EQ(view, "window.devicePixelRatio", "1"); - EXPECT_JS_EQ(view, "devicePixelRatioFromStyle()", "1"); - - // Navigate to new URL - loadURL(view, [NSURL URLWithString:@"about:blank"]); - waitForLoadToFinish(); - - // Change the scale factor - RetainPtr<SyntheticBackingScaleFactorWindow> window1 = createWindow(); - [window1.get() setBackingScaleFactor:3]; - - [[window1.get() contentView] addSubview:view]; - - // Navigate back to the first page - goBack(view); - waitForLoadToFinish(); - - // Ensure that the cached page has updated its scale factor - EXPECT_JS_EQ(view, "window.devicePixelRatio", "3"); - EXPECT_JS_EQ(view, "devicePixelRatioFromStyle()", "3"); - - [view removeFromSuperview]; -} - -TEST_F(DeviceScaleFactorOnBack, WebKit) -{ - runWebKit1Test(); -} - -TEST_F(DeviceScaleFactorOnBack, WebKit2) -{ - runWebKit2Test(); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/DynamicDeviceScaleFactor.mm b/Tools/TestWebKitAPI/Tests/mac/DynamicDeviceScaleFactor.mm deleted file mode 100644 index 61a1efed7..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/DynamicDeviceScaleFactor.mm +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 "WebKitAgnosticTest.h" - -#include "JavaScriptTest.h" -#include "PlatformUtilities.h" -#include "SyntheticBackingScaleFactorWindow.h" -#include <wtf/RetainPtr.h> - -namespace TestWebKitAPI { - -class DynamicDeviceScaleFactor : public WebKitAgnosticTest { -public: - RetainPtr<SyntheticBackingScaleFactorWindow> createWindow(); - - template <typename View> void runTest(View); - - // WebKitAgnosticTest - virtual NSURL *url() const { return [[NSBundle mainBundle] URLForResource:@"devicePixelRatio" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]; } - virtual void didLoadURL(WebView *webView) { runTest(webView); } - virtual void didLoadURL(WKView *wkView) { runTest(wkView); } -}; - -RetainPtr<SyntheticBackingScaleFactorWindow> DynamicDeviceScaleFactor::createWindow() -{ - RetainPtr<SyntheticBackingScaleFactorWindow> window = adoptNS([[SyntheticBackingScaleFactorWindow alloc] initWithContentRect:viewFrame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]); - [window.get() setReleasedWhenClosed:NO]; - return window; -} - -template <typename View> -void DynamicDeviceScaleFactor::runTest(View view) -{ - EXPECT_JS_EQ(view, "window.devicePixelRatio", "1"); - EXPECT_JS_EQ(view, "devicePixelRatioFromStyle()", "1"); - - RetainPtr<SyntheticBackingScaleFactorWindow> window1 = createWindow(); - [window1.get() setBackingScaleFactor:3]; - - [[window1.get() contentView] addSubview:view]; - EXPECT_JS_EQ(view, "window.devicePixelRatio", "3"); - EXPECT_JS_EQ(view, "devicePixelRatioFromStyle()", "3"); - - RetainPtr<SyntheticBackingScaleFactorWindow> window2 = createWindow(); - [window2.get() setBackingScaleFactor:4]; - - [[window2.get() contentView] addSubview:view]; - EXPECT_JS_EQ(view, "window.devicePixelRatio", "4"); - EXPECT_JS_EQ(view, "devicePixelRatioFromStyle()", "4"); - - [view removeFromSuperview]; - EXPECT_JS_EQ(view, "window.devicePixelRatio", "1"); - EXPECT_JS_EQ(view, "devicePixelRatioFromStyle()", "1"); -} - -TEST_F(DynamicDeviceScaleFactor, WebKit) -{ - runWebKit1Test(); -} - -TEST_F(DynamicDeviceScaleFactor, WebKit2) -{ - runWebKit2Test(); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/ElementAtPointInWebFrame.mm b/Tools/TestWebKitAPI/Tests/mac/ElementAtPointInWebFrame.mm deleted file mode 100644 index 10fc581f4..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/ElementAtPointInWebFrame.mm +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#import <WebKit/WebFramePrivate.h> -#import <wtf/RetainPtr.h> - -@interface ElementAtPointFrameLoadDelegate : NSObject -@end - -static bool didFinishLoad; - -@implementation ElementAtPointFrameLoadDelegate - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, ElementAtPoint) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<ElementAtPointFrameLoadDelegate> frameLoadDelegate = adoptNS([[ElementAtPointFrameLoadDelegate alloc] init]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - WebFrame *mainFrame = webView.get().mainFrame; - - [mainFrame loadHTMLString:@"<style> div { position:absolute; width:60px; height:100px; } </style> <div name='first'></div> <div name='second' style='left:60px; top:100px;'></div>" - baseURL:[NSURL URLWithString:@"about:blank"]]; - - Util::run(&didFinishLoad); - - NSDictionary *elementDictionary = [mainFrame elementAtPoint:NSMakePoint(30, 50)]; - DOMElement *domElement = [elementDictionary objectForKey:WebElementDOMNodeKey]; - EXPECT_WK_STREQ(@"first", [domElement getAttribute:@"name"]); - - elementDictionary = [mainFrame elementAtPoint:NSMakePoint(90, 150)]; - domElement = [elementDictionary objectForKey:WebElementDOMNodeKey]; - EXPECT_WK_STREQ(@"second", [domElement getAttribute:@"name"]); - - elementDictionary = [mainFrame elementAtPoint:NSMakePoint(30, 150)]; - domElement = [elementDictionary objectForKey:WebElementDOMNodeKey]; - EXPECT_WK_STREQ(@"BODY", [domElement tagName]); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/HTMLCollectionNamedItem.html b/Tools/TestWebKitAPI/Tests/mac/HTMLCollectionNamedItem.html deleted file mode 100644 index c0205b63e..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/HTMLCollectionNamedItem.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE html> -<html> -<body> -<input type="text" id="idForTwoTextFields" value="firstItem"> -<input type="text" id="idForTwoTextFields" value="secondItem"> -<img name="nameForTwoImages" title="thirdItem"> -<img name="nameForTwoImages" title="fourthItem"> -</body> -</html> diff --git a/Tools/TestWebKitAPI/Tests/mac/HTMLCollectionNamedItem.mm b/Tools/TestWebKitAPI/Tests/mac/HTMLCollectionNamedItem.mm deleted file mode 100644 index 62cb79751..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/HTMLCollectionNamedItem.mm +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * 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: - * 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 "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <wtf/RetainPtr.h> - -#import <WebKit/DOM.h> -#import <WebKit/WebViewPrivate.h> - -@interface HTMLCollectionNamedItemTest : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation HTMLCollectionNamedItemTest - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, HTMLCollectionNamedItemTest) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<HTMLCollectionNamedItemTest> testController = adoptNS([HTMLCollectionNamedItemTest new]); - - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] - URLForResource:@"HTMLCollectionNamedItem" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - didFinishLoad = false; - - DOMDocument *document = webView.get().mainFrameDocument; - RetainPtr<DOMHTMLCollection> collection = [[document body] children]; - - EXPECT_EQ([collection.get() length], (unsigned)4); - EXPECT_WK_STREQ([[collection.get() item:0] value], @"firstItem"); - EXPECT_WK_STREQ([[collection.get() item:1] value], @"secondItem"); - EXPECT_WK_STREQ([[collection.get() namedItem:@"idForTwoTextFields"] value], @"firstItem"); - EXPECT_WK_STREQ([[collection.get() item:1] value], @"secondItem"); - EXPECT_WK_STREQ([[collection.get() item:0] value], @"firstItem"); - - EXPECT_WK_STREQ([(DOMHTMLElement*)[collection.get() item:2] title], @"thirdItem"); - EXPECT_WK_STREQ([(DOMHTMLElement*)[collection.get() item:3] title], @"fourthItem"); - EXPECT_WK_STREQ([(DOMHTMLElement*)[collection.get() namedItem:@"nameForTwoImages"] title], @"thirdItem"); - EXPECT_WK_STREQ([(DOMHTMLElement*)[collection.get() item:3] title], @"fourthItem"); - EXPECT_WK_STREQ([(DOMHTMLElement*)[collection.get() item:2] title], @"thirdItem"); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/HTMLFormCollectionNamedItem.html b/Tools/TestWebKitAPI/Tests/mac/HTMLFormCollectionNamedItem.html deleted file mode 100644 index 8439f2c27..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/HTMLFormCollectionNamedItem.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE html> -<html> -<body> -<form> - <input type="text" name="nameForTwoTextFields" value="firstItem"> - <input type="text" name="nameForTwoTextFields" value="secondItem"> -</form> -</body> -</html> diff --git a/Tools/TestWebKitAPI/Tests/mac/HTMLFormCollectionNamedItem.mm b/Tools/TestWebKitAPI/Tests/mac/HTMLFormCollectionNamedItem.mm deleted file mode 100644 index a716ab92f..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/HTMLFormCollectionNamedItem.mm +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * 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: - * 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 "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <wtf/RetainPtr.h> - -#import <WebKit/DOM.h> -#import <WebKit/WebViewPrivate.h> - -@interface HTMLFormCollectionNamedItemTest : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation HTMLFormCollectionNamedItemTest - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, HTMLFormCollectionNamedItemTest) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<HTMLFormCollectionNamedItemTest> testController = adoptNS([HTMLFormCollectionNamedItemTest new]); - - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] - URLForResource:@"HTMLFormCollectionNamedItem" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - didFinishLoad = false; - - DOMDocument *document = webView.get().mainFrameDocument; - DOMHTMLFormElement *form = (DOMHTMLFormElement *)[document querySelector:@"form"]; - RetainPtr<DOMHTMLCollection> collection = [form elements]; - - EXPECT_EQ([collection.get() length], (unsigned)2); - EXPECT_WK_STREQ([[collection.get() item:0] value], @"firstItem"); - EXPECT_WK_STREQ([[collection.get() item:1] value], @"secondItem"); - EXPECT_WK_STREQ([[collection.get() namedItem:@"nameForTwoTextFields"] value], @"firstItem"); - EXPECT_WK_STREQ([[collection.get() item:1] value], @"secondItem"); - EXPECT_WK_STREQ([[collection.get() item:0] value], @"firstItem"); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/InspectorBar.mm b/Tools/TestWebKitAPI/Tests/mac/InspectorBar.mm deleted file mode 100644 index 5f2205be8..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/InspectorBar.mm +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2011, 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 "PlatformUtilities.h" -#import <wtf/RetainPtr.h> - -@interface InspectorBarController : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation InspectorBarController - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -- (NSDictionary *)convertAttributes:(NSDictionary *)dictionary -{ - NSMutableDictionary *newDictionary = [dictionary mutableCopy]; - [newDictionary removeObjectForKey:NSForegroundColorAttributeName]; - return [newDictionary autorelease]; -} -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, InspectorBarTest) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<InspectorBarController> inspectorBarController = adoptNS([InspectorBarController new]); - - webView.get().frameLoadDelegate = inspectorBarController.get(); - [webView.get().mainFrame loadHTMLString:@"<body contenteditable style=\"color: green\"><u>Lorem ipsum sit amet</u></body>" baseURL:[NSURL URLWithString:@"about:blank"]]; - - Util::run(&didFinishLoad); - - DOMDocument *document = webView.get().mainFrameDocument; - [[document body] focus]; - - EXPECT_TRUE([webView.get() respondsToSelector:@selector(typingAttributes)]); - NSDictionary *attributes = [(id)webView.get() typingAttributes]; - [(id)[[[webView.get() mainFrame] frameView] documentView] doCommandBySelector:@selector(bold:)]; - EXPECT_FALSE([attributes isEqual:[(id)webView.get() typingAttributes]]); - - [webView.get() selectAll:nil]; - NSAttributedString *attrString = [(NSView <NSTextInput> *)[[[webView.get() mainFrame] frameView] documentView] attributedSubstringFromRange:NSMakeRange(0, 5)]; - attributes = [attrString attributesAtIndex:0 effectiveRange:0]; - - EXPECT_TRUE([[attributes objectForKey:NSUnderlineStyleAttributeName] intValue] != 0); - - [webView.get() changeAttributes:inspectorBarController.get()]; - - DOMNode *currentNode = [document body]; - while ([[currentNode firstChild] nodeType] != DOM_TEXT_NODE) - currentNode = [currentNode firstChild]; - - DOMCSSStyleDeclaration *style = [document getComputedStyle:(DOMElement *)currentNode pseudoElement:nil]; - EXPECT_WK_STREQ(@"rgb(0, 0, 0)", [style color]); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/JSContextBackForwardCache1.html b/Tools/TestWebKitAPI/Tests/mac/JSContextBackForwardCache1.html deleted file mode 100644 index f736a7890..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/JSContextBackForwardCache1.html +++ /dev/null @@ -1,10 +0,0 @@ -<body> - <div id="test-div"></div> - <script> - var testDiv = document.getElementById("test-div"); - if (!testDiv.myCustomProperty) - insertMyCustomProperty(testDiv); - else - checkForMyCustomProperty(testDiv); - </script> -</body> diff --git a/Tools/TestWebKitAPI/Tests/mac/JSContextBackForwardCache2.html b/Tools/TestWebKitAPI/Tests/mac/JSContextBackForwardCache2.html deleted file mode 100644 index 1d26d21b4..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/JSContextBackForwardCache2.html +++ /dev/null @@ -1,10 +0,0 @@ -<body> - <div id="test-div"></div> - <script> - var testDiv = document.getElementById("test-div"); - if (testDiv.myCustomProperty) - myConsole.log("ERROR: found myCustomProperty."); - else - didCompleteTestSuccessfully(); - </script> -</body> diff --git a/Tools/TestWebKitAPI/Tests/mac/JSWrapperForNodeInWebFrame.mm b/Tools/TestWebKitAPI/Tests/mac/JSWrapperForNodeInWebFrame.mm deleted file mode 100644 index 5c41aaab5..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/JSWrapperForNodeInWebFrame.mm +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#import <WebKit/WebFramePrivate.h> -#import <WebKit/WebScriptWorld.h> -#import <JavaScriptCore/JSContextRef.h> -#import <JavaScriptCore/JSRetainPtr.h> -#import <JavaScriptCore/JSStringRef.h> -#import <JavaScriptCore/JSValueRef.h> -#import <wtf/RetainPtr.h> - -@interface JSWrapperForNodeFrameLoadDelegate : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation JSWrapperForNodeFrameLoadDelegate - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, JSWrapperForNode) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<JSWrapperForNodeFrameLoadDelegate> frameLoadDelegate = adoptNS([[JSWrapperForNodeFrameLoadDelegate alloc] init]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - WebFrame *mainFrame = webView.get().mainFrame; - [mainFrame loadHTMLString:@"<div id=\"target\"</div>" baseURL:[NSURL URLWithString:@"about:blank"]]; - Util::run(&didFinishLoad); - DOMDocument *document = webView.get().mainFrameDocument; - DOMNode *target = [document getElementById:@"target"]; // This script object is in standard world. - - // In an isolated script world, add a new property to the target node. - NSString *isolatedScriptString = @"var target = document.getElementById(\"target\"); target.isolatedProperty = true;"; - WebScriptWorld *isolatedWorld = [WebScriptWorld world]; - JSGlobalContextRef isolatedCtx = [mainFrame _globalContextForScriptWorld:isolatedWorld]; - [mainFrame _stringByEvaluatingJavaScriptFromString:isolatedScriptString withGlobalObject:JSContextGetGlobalObject(isolatedCtx) inScriptWorld:isolatedWorld]; - JSValueRef isolatedNodeJSValue = [mainFrame jsWrapperForNode:target inScriptWorld:isolatedWorld]; - ASSERT_TRUE(JSValueIsObject(isolatedCtx, isolatedNodeJSValue)); - JSObjectRef isolatedNodeJSObject = JSValueToObject(isolatedCtx, isolatedNodeJSValue, 0); - - // In the standard script world, add a different property to the target node - NSString *normalScriptString = @"var target = document.getElementById(\"target\"); target.normalProperty = true;"; - WebScriptWorld *normalWorld = [WebScriptWorld standardWorld]; - JSGlobalContextRef normalCtx = [mainFrame _globalContextForScriptWorld:normalWorld]; - [mainFrame _stringByEvaluatingJavaScriptFromString:normalScriptString withGlobalObject:JSContextGetGlobalObject(normalCtx) inScriptWorld:normalWorld]; - JSValueRef normalNodeJSValue = [mainFrame jsWrapperForNode:target inScriptWorld:normalWorld]; - ASSERT_TRUE(JSValueIsObject(normalCtx, normalNodeJSValue)); - JSObjectRef normalNodeJSObject = JSValueToObject(normalCtx, normalNodeJSValue, 0); - - JSRetainPtr<JSStringRef> isolatedPropertyJSString = JSStringCreateWithUTF8CString("isolatedProperty"); - // Test for successful retrieval of the first property in the isolated script world - EXPECT_TRUE(JSValueIsBoolean(isolatedCtx, JSObjectGetProperty(isolatedCtx, isolatedNodeJSObject, isolatedPropertyJSString.get(), 0))); - // Test for failed retrieval of the first property in the standard script world - EXPECT_TRUE(JSValueIsUndefined(normalCtx, JSObjectGetProperty(normalCtx, normalNodeJSObject, isolatedPropertyJSString.get(), 0))); - - JSRetainPtr<JSStringRef> normalPropertyJSString = JSStringCreateWithUTF8CString("normalProperty"); - // Test for successful retrieval of the second property in the standard script world - EXPECT_TRUE(JSValueIsBoolean(normalCtx, JSObjectGetProperty(normalCtx, normalNodeJSObject, normalPropertyJSString.get(), 0))); - // Test for failed retrieval of the second property in the isolated script world - EXPECT_TRUE(JSValueIsUndefined(isolatedCtx, JSObjectGetProperty(isolatedCtx, isolatedNodeJSObject, normalPropertyJSString.get(), 0))); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.html b/Tools/TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.html deleted file mode 100644 index 033c79130..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.html +++ /dev/null @@ -1,14 +0,0 @@ -<script> - -function loaded() -{ - var request = new XMLHttpRequest(); - request.open('GET', 'http://www.iana.org/domains/example/', true); - request.send(null); -} - -</script> - -<body onload="loaded();"> -We will do some XHR'ing now! -</body> diff --git a/Tools/TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.mm b/Tools/TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.mm deleted file mode 100644 index e2ecdeac4..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/MemoryCacheDisableWithinResourceLoadDelegate.mm +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#import <WebKit/WebCache.h> -#import <wtf/RetainPtr.h> - -@interface MemoryCacheDisableTestResourceLoadDelegate : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation MemoryCacheDisableTestResourceLoadDelegate - -- (id)webView:(WebView *)sender identifierForInitialRequest:(NSURLRequest *)request fromDataSource:(WebDataSource *)dataSource -{ - [WebCache setDisabled:YES]; - [WebCache setDisabled:NO]; - - return self; -} - -- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource -{ - [WebCache setDisabled:YES]; - [WebCache setDisabled:NO]; - - return request; -} - -- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource -{ - [WebCache setDisabled:YES]; - [WebCache setDisabled:NO]; - - didFinishLoad = YES; -} - -- (void)webView:(WebView *)sender resource:(id)identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource -{ - [WebCache setDisabled:YES]; - [WebCache setDisabled:NO]; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, MemoryCacheDisableWithinResourceLoadDelegate) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - - RetainPtr<MemoryCacheDisableTestResourceLoadDelegate> resourceLoadDelegate = adoptNS([[MemoryCacheDisableTestResourceLoadDelegate alloc] init]); - webView.get().resourceLoadDelegate = resourceLoadDelegate.get(); - - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"MemoryCacheDisableWithinResourceLoadDelegate" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - - [pool drain]; - // If we finished without crashing, the test passed. -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/MemoryCachePruneWithinResourceLoadDelegate.html b/Tools/TestWebKitAPI/Tests/mac/MemoryCachePruneWithinResourceLoadDelegate.html deleted file mode 100644 index 7f4fd33b9..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/MemoryCachePruneWithinResourceLoadDelegate.html +++ /dev/null @@ -1,14 +0,0 @@ -<script> - -function loaded() -{ - var request = new XMLHttpRequest(); - request.open('GET', 'http://www.iana.org/domains/example/', true); - request.send(null); -} - -</script> - -<body onload="loaded();"> -We will do some XHR'ing now! -</body>
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/Tests/mac/MemoryCachePruneWithinResourceLoadDelegate.mm b/Tools/TestWebKitAPI/Tests/mac/MemoryCachePruneWithinResourceLoadDelegate.mm deleted file mode 100644 index 212820e0a..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/MemoryCachePruneWithinResourceLoadDelegate.mm +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#import <wtf/RetainPtr.h> - -@interface MemoryCachePruneTestResourceLoadDelegate : NSObject { -@public - NSWindow *_window; -} -@end - -static bool didFinishLoad; - -@implementation MemoryCachePruneTestResourceLoadDelegate - -- (id)webView:(WebView *)sender identifierForInitialRequest:(NSURLRequest *)request fromDataSource:(WebDataSource *)dataSource -{ - // We only care about an http request, which is our test XHR - if ([[[request URL] scheme] isEqualToString:@"http"]) - return self; - - return nil; -} - -- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource -{ - if (identifier == nil) - return request; - - [_window close]; - return request; -} - -- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource -{ - if (identifier == nil) - return; - - didFinishLoad = true; -} - -- (void)webView:(WebView *)sender resource:(id)identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource -{ - if (identifier == nil) - return; - - didFinishLoad = true; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, DISABLED_MemoryCachePruneWithinResourceLoadDelegate) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - RetainPtr<WebView> webView1 = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<WebView> webView2 = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - - NSWindow* window = [[NSWindow alloc] initWithContentRect:webView2.get().frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]; - [window.contentView addSubview:webView2.get()]; - - RetainPtr<MemoryCachePruneTestResourceLoadDelegate> resourceLoadDelegate = adoptNS([[MemoryCachePruneTestResourceLoadDelegate alloc] init]); - resourceLoadDelegate.get()->_window = window; - webView1.get().resourceLoadDelegate = resourceLoadDelegate.get(); - - [[webView1.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"MemoryCachePruneWithinResourceLoadDelegate" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - - [pool drain]; - // If we finished without crashing, the test passed. -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/OpenNewWindow.html b/Tools/TestWebKitAPI/Tests/mac/OpenNewWindow.html deleted file mode 100644 index 975f6d98d..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/OpenNewWindow.html +++ /dev/null @@ -1,7 +0,0 @@ -<a href="#" onclick="openWindow()"></a> -<script> - function openWindow() { - window.open("window-to-ignore.html", "newWindow"); - } - document.getElementsByTagName("a")[0].click(); -</script> diff --git a/Tools/TestWebKitAPI/Tests/mac/PageVisibilityStateWithWindowChanges.html b/Tools/TestWebKitAPI/Tests/mac/PageVisibilityStateWithWindowChanges.html deleted file mode 100644 index bded58089..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/PageVisibilityStateWithWindowChanges.html +++ /dev/null @@ -1,6 +0,0 @@ -<script> -document.addEventListener("visibilitychange", function(event) { - // Send a signal to the test controller via alert. - alert('visibilitychange'); -}); -</script> diff --git a/Tools/TestWebKitAPI/Tests/mac/PageVisibilityStateWithWindowChanges.mm b/Tools/TestWebKitAPI/Tests/mac/PageVisibilityStateWithWindowChanges.mm deleted file mode 100644 index 9a614ab7a..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/PageVisibilityStateWithWindowChanges.mm +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2013 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 "JavaScriptTest.h" -#import "Test.h" -#import "WebKitAgnosticTest.h" -#import <WebKit/WebView.h> -#import <WebKit2/WKViewPrivate.h> -#import <wtf/RetainPtr.h> - -static bool didGetPageSignalToContinue; - -// WebKit1 WebUIDelegate - -@interface PageVisibilityStateDelegate : NSObject -@end - -@implementation PageVisibilityStateDelegate - -- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame -{ - didGetPageSignalToContinue = true; -} - -@end - -// WebKit2 WKPageUIClient - -static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo) -{ - didGetPageSignalToContinue = true; -} - -// WebKitAgnosticTest - -namespace TestWebKitAPI { - -class PageVisibilityStateWithWindowChanges : public WebKitAgnosticTest { -public: - template <typename View> void runTest(View); - - // WebKitAgnosticTest - virtual NSURL *url() const OVERRIDE { return [[NSBundle mainBundle] URLForResource:@"PageVisibilityStateWithWindowChanges" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]; } - virtual void didLoadURL(WebView *webView) OVERRIDE { runTest(webView); } - virtual void didLoadURL(WKView *wkView) OVERRIDE { runTest(wkView); } - - // Setup and teardown the UIDelegate which gets alert() signals from the page. - virtual void initializeView(WebView *) OVERRIDE; - virtual void initializeView(WKView *) OVERRIDE; - virtual void teardownView(WebView *) OVERRIDE; - virtual void teardownView(WKView *) OVERRIDE; -}; - -void PageVisibilityStateWithWindowChanges::initializeView(WebView *webView) -{ - // Released in teardownView. - webView.UIDelegate = [[PageVisibilityStateDelegate alloc] init]; -} - -void PageVisibilityStateWithWindowChanges::teardownView(WebView *webView) -{ - id uiDelegate = webView.UIDelegate; - webView.UIDelegate = nil; - [uiDelegate release]; -} - -void PageVisibilityStateWithWindowChanges::initializeView(WKView *wkView) -{ - WKPageUIClient uiClient; - memset(&uiClient, 0, sizeof(uiClient)); - uiClient.version = 0; - uiClient.clientInfo = 0; - uiClient.runJavaScriptAlert = runJavaScriptAlert; - WKPageSetPageUIClient(wkView.pageRef, &uiClient); -} - -void PageVisibilityStateWithWindowChanges::teardownView(WKView *wkView) -{ - // We do not need to teardown the WKPageUIClient. -} - -template <typename View> -void PageVisibilityStateWithWindowChanges::runTest(View view) -{ - // This WebView does not have a window and superview. PageVisibility should be "hidden". - EXPECT_NULL([view window]); - EXPECT_NULL([view superview]); - EXPECT_JS_EQ(view, "document.visibilityState", "hidden"); - - // Add it to a non-visible window. PageVisibility should still be "hidden". - RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:view.frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]); - [window.get().contentView addSubview:view]; - EXPECT_NOT_NULL([view window]); - EXPECT_NOT_NULL([view superview]); - EXPECT_FALSE([window.get() isVisible]); - EXPECT_JS_EQ(view, "document.visibilityState", "hidden"); - - // Make the window visible. PageVisibility should become "visible". - didGetPageSignalToContinue = false; - [window.get() makeKeyAndOrderFront:nil]; - EXPECT_TRUE([window.get() isVisible]); - Util::run(&didGetPageSignalToContinue); - EXPECT_JS_EQ(view, "document.visibilityState", "visible"); - - // Minimize the window. PageVisibility should become "hidden". - didGetPageSignalToContinue = false; - [window.get() miniaturize:nil]; - Util::run(&didGetPageSignalToContinue); - EXPECT_JS_EQ(view, "document.visibilityState", "hidden"); - - // Deminimize the window. PageVisibility should become "visible". - didGetPageSignalToContinue = false; - [window.get() deminiaturize:nil]; - Util::run(&didGetPageSignalToContinue); - EXPECT_JS_EQ(view, "document.visibilityState", "visible"); - - // Remove the WebView from its superview. PageVisibility should become "hidden". - didGetPageSignalToContinue = false; - [view removeFromSuperview]; - EXPECT_NULL([view window]); - EXPECT_NULL([view superview]); - EXPECT_TRUE([window.get() isVisible]); - Util::run(&didGetPageSignalToContinue); - EXPECT_JS_EQ(view, "document.visibilityState", "hidden"); -} - -TEST_F(PageVisibilityStateWithWindowChanges, WebKit) -{ - runWebKit1Test(); -} - -TEST_F(PageVisibilityStateWithWindowChanges, WebKit2) -{ - runWebKit1Test(); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm b/Tools/TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm deleted file mode 100644 index bc3a11db3..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/RenderedImageFromDOMRange.mm +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - */ - -#import "config.h" -#import "PlatformUtilities.h" -#import <WebKit/WebDocumentPrivate.h> -#import <WebKit/DOMPrivate.h> -#import <wtf/RetainPtr.h> - -@interface RenderedImageFromDOMRangeFrameLoadDelegate : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation RenderedImageFromDOMRangeFrameLoadDelegate - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, RenderedImageFromDOMRange) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<RenderedImageFromDOMRangeFrameLoadDelegate> frameLoadDelegate = adoptNS([RenderedImageFromDOMRangeFrameLoadDelegate new]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - [webView.get().mainFrame loadHTMLString:@"<div style=\"width: 100px;\">Lorem <span id=\"target\">ipsum dolor</span> sit amet</div>" baseURL:[NSURL URLWithString:@"about:blank"]]; - - Util::run(&didFinishLoad); - - DOMDocument *document = webView.get().mainFrameDocument; - DOMRange *range = [document createRange]; - DOMNode *target = [document getElementById:@"target"]; - [range selectNode:target]; - NSImage *actualImage = [range renderedImageForcingBlackText:YES]; - - [webView.get() setSelectedDOMRange:range affinity:NSSelectionAffinityDownstream]; - id <WebDocumentView> documentView = webView.get().mainFrame.frameView.documentView; - NSImage *expectedImage = [(id <WebDocumentSelection>)documentView selectionImageForcingBlackText:YES]; - EXPECT_TRUE([actualImage.TIFFRepresentation isEqual:expectedImage.TIFFRepresentation]); - - [target.parentElement.style setProperty:@"-webkit-user-select" value:@"none" priority:nil]; - NSImage *actualImageWithUserSelectNone = [range renderedImageForcingBlackText:YES]; - EXPECT_TRUE([actualImageWithUserSelectNone.TIFFRepresentation isEqual:expectedImage.TIFFRepresentation]); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/SetAndUpdateCacheModel.mm b/Tools/TestWebKitAPI/Tests/mac/SetAndUpdateCacheModel.mm deleted file mode 100644 index 003755235..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/SetAndUpdateCacheModel.mm +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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. - */ - -#include "config.h" -#include <wtf/RetainPtr.h> - -#import <WebKit/WebView.h> -#import <WebKit/WebPreferences.h> - -@interface WebView (WebViewOtherInternal) -+ (WebCacheModel)_cacheModel; -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, SetAndUpdateCacheModelInitialModel) -{ - EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); - - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - - EXPECT_EQ((int)WebCacheModelDocumentBrowser, (int)[WebView _cacheModel]); -} - -TEST(WebKit1, SetAndUpdateCacheModelStandardPreferenceChange) -{ - EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); - - WebPreferences *standardPreferences = [WebPreferences standardPreferences]; - EXPECT_EQ((int)WebCacheModelDocumentBrowser, (int)[WebView _cacheModel]); - - [standardPreferences setCacheModel:WebCacheModelPrimaryWebBrowser]; - EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); - - [standardPreferences setCacheModel:WebCacheModelDocumentViewer]; - EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); -} - -TEST(WebKit1, SetAndUpdateCacheModelPreferencesChangeMix) -{ - // On change, the cache model always take the highest value of any preference bound to a WebView. - EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); - - WebPreferences *standardPreferences = [WebPreferences standardPreferences]; - RetainPtr<WebPreferences> customPreferences = adoptNS([[WebPreferences alloc] initWithIdentifier:@"SetAndUpdateCacheModelPreferencesChangeMix"]); - - // 1) The customPreferences is not set on a view. - EXPECT_EQ((int)WebCacheModelDocumentBrowser, (int)[WebView _cacheModel]); - - [standardPreferences setCacheModel:WebCacheModelPrimaryWebBrowser]; - EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); - - [standardPreferences setCacheModel:WebCacheModelDocumentViewer]; - EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); - [customPreferences.get() setCacheModel:WebCacheModelPrimaryWebBrowser]; - EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); - - - // 2) The cache model should follow the highest value of cache model between the two preferences. - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - [webView.get() setPreferences:customPreferences.get()]; - EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); - - [customPreferences.get() setCacheModel:WebCacheModelDocumentBrowser]; - EXPECT_EQ((int)WebCacheModelDocumentBrowser, (int)[WebView _cacheModel]); - - [standardPreferences setCacheModel:WebCacheModelPrimaryWebBrowser]; - EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); - [customPreferences.get() setCacheModel:WebCacheModelDocumentViewer]; - EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); - - // 3) Resetting the view should fall back to standardPreferences. - [standardPreferences setCacheModel:WebCacheModelDocumentViewer]; - [customPreferences.get() setCacheModel:WebCacheModelPrimaryWebBrowser]; - EXPECT_EQ((int)WebCacheModelPrimaryWebBrowser, (int)[WebView _cacheModel]); - - webView.clear(); - EXPECT_EQ((int)WebCacheModelDocumentViewer, (int)[WebView _cacheModel]); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.html b/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.html deleted file mode 100644 index ad3714bb0..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.html +++ /dev/null @@ -1,8 +0,0 @@ -<!doctype html> -<html> - <body> - <p>This is a document to load so that the ObjC [document setDocumentURI:] - API can be tested.</p> - <a href="relativeURL.html" id="relative"></a> - </body> -</html> diff --git a/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.mm b/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.mm deleted file mode 100644 index 44ecc3e9b..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.mm +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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: - * 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 "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <wtf/RetainPtr.h> - -#import <WebKit/DOM.h> -#import <WebKit/WebViewPrivate.h> - -@interface SetDocumentURITest : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation SetDocumentURITest - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, SetDocumentURITestFile) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<SetDocumentURITest> testController = adoptNS([SetDocumentURITest new]); - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"SetDocumentURI" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - Util::run(&didFinishLoad); - didFinishLoad = false; - DOMDocument *document = webView.get().mainFrameDocument; - - [document setDocumentURI:@"file:///test"]; - // documentURI set correctly. - EXPECT_WK_STREQ(@"file:///test", [document documentURI]); - // baseURI follows along. - EXPECT_WK_STREQ(@"file:///test", [document baseURI]); -} - -TEST(WebKit1, SetDocumentURITestURL) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<SetDocumentURITest> testController = adoptNS([SetDocumentURITest new]); - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"SetDocumentURI" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - Util::run(&didFinishLoad); - didFinishLoad = false; - DOMDocument *document = webView.get().mainFrameDocument; - - [document setDocumentURI:@"http://example.com/"]; - // documentURI set correctly. - EXPECT_WK_STREQ(@"http://example.com/", [document documentURI]); - // baseURI follows along. - EXPECT_WK_STREQ(@"http://example.com/", [document baseURI]); - // Relative links too. - NSString *result = [webView.get() stringByEvaluatingJavaScriptFromString:@"document.getElementById('relative').href"]; - EXPECT_WK_STREQ(@"http://example.com/relativeURL.html", result); -} - -TEST(WebKit1, SetDocumentURITestString) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<SetDocumentURITest> testController = adoptNS([SetDocumentURITest new]); - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"SetDocumentURI" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - Util::run(&didFinishLoad); - didFinishLoad = false; - DOMDocument *document = webView.get().mainFrameDocument; - - [document setDocumentURI:@"A non-URL string."]; - // documentURI accepts random strings. - EXPECT_WK_STREQ(@"A non-URL string.", [document documentURI]); - // baseURI is empty for non-URL strings. - EXPECT_WK_STREQ(@"", [document baseURI]); -} - -TEST(WebKit1, SetDocumentURITestNull) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<SetDocumentURITest> testController = adoptNS([SetDocumentURITest new]); - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"SetDocumentURI" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - Util::run(&didFinishLoad); - didFinishLoad = false; - DOMDocument *document = webView.get().mainFrameDocument; - - [document setDocumentURI:nil]; - // documenturi is empty. - EXPECT_WK_STREQ(@"", [document documentURI]); - // baseURI is null as well. - EXPECT_WK_STREQ(@"", [document baseURI]); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/SimplifyMarkup.mm b/Tools/TestWebKitAPI/Tests/mac/SimplifyMarkup.mm deleted file mode 100644 index 9d443ad04..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/SimplifyMarkup.mm +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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. - */ - -#include "config.h" -#include "PlatformUtilities.h" -#include "PlatformWebView.h" -#include <wtf/RetainPtr.h> - -#import <WebKit/DOM.h> -#import <WebKit/WebViewPrivate.h> - -@interface SimplifyMarkupTest : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation SimplifyMarkupTest - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, SimplifyMarkupTest) -{ - RetainPtr<WebView> webView1 = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<WebView> webView2 = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<SimplifyMarkupTest> testController = adoptNS([SimplifyMarkupTest new]); - - webView1.get().frameLoadDelegate = testController.get(); - [[webView1.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"verboseMarkup" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - didFinishLoad = false; - - webView2.get().frameLoadDelegate = testController.get(); - [[webView2.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"verboseMarkup" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - didFinishLoad = false; - - DOMDocument *document1 = webView1.get().mainFrameDocument; - NSString* markupBefore = [[document1 body] innerHTML]; - DOMDocument *document2 = webView2.get().mainFrameDocument; - - // If start is after end, nothing is done - DOMNode *start = [document1 getElementById:@"test2"]; - DOMNode *end = [document1 getElementById:@"test1"]; - - [webView1.get() _simplifyMarkup:[document1 body] endNode:end]; - NSString* markupAfter = [[document1 body] innerHTML]; - - EXPECT_WK_STREQ(markupBefore, markupAfter); - EXPECT_EQ([markupBefore length], [markupAfter length]); - - // If the two nodes are not in the same webView, nothing is done. - start = [document1 getElementById:@"test1"]; - end = [document2 getElementById:@"test2"]; - [webView1.get() _simplifyMarkup:start endNode:end]; - markupAfter = [[document1 body] innerHTML]; - - EXPECT_WK_STREQ(markupBefore, markupAfter); - EXPECT_EQ([markupBefore length], [markupAfter length]); - - // If the two nodes are not in the same document, nothing is done. - DOMHTMLFrameElement* frame = (DOMHTMLFrameElement *)[document1 getElementById:@"test3"]; - end = [[frame contentDocument] firstChild]; - - [webView1.get() _simplifyMarkup:start endNode:end]; - markupAfter = [[document1 body] innerHTML]; - - EXPECT_WK_STREQ(markupBefore, markupAfter); - EXPECT_EQ([markupBefore length], [markupAfter length]); - - // If the nodes are in the same webView, same document and in the right order, - // we should have a simplified markup. - [webView1.get() _simplifyMarkup:[document1 body] endNode:nil]; - markupAfter = [[document1 body] innerHTML]; - // We only verify that the markup has changed and that it is less verbose - // then the original version. - // The accuracy of the operation is tested by the DRT tests already. - EXPECT_GT([markupBefore length], [markupAfter length]); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/StopLoadingFromDidReceiveResponse.html b/Tools/TestWebKitAPI/Tests/mac/StopLoadingFromDidReceiveResponse.html deleted file mode 100644 index 92af0012c..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/StopLoadingFromDidReceiveResponse.html +++ /dev/null @@ -1 +0,0 @@ -<script src="data:text/javascript,document.write('SUCCESS')"></script> diff --git a/Tools/TestWebKitAPI/Tests/mac/StopLoadingFromDidReceiveResponse.mm b/Tools/TestWebKitAPI/Tests/mac/StopLoadingFromDidReceiveResponse.mm deleted file mode 100644 index 8eb269df0..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/StopLoadingFromDidReceiveResponse.mm +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformUtilities.h" -#import <WebKit/WebCache.h> -#import <wtf/RetainPtr.h> - -@interface StopLoadingFromDidReceiveResponse : NSObject { -} -@end - -static bool didFinishLoad; - -@implementation StopLoadingFromDidReceiveResponse - -- (void)webView:(WebView *)sender resource:(id)identifier didReceiveResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)dataSource -{ - static BOOL mainResourceReceived; - if (!mainResourceReceived) { - mainResourceReceived = YES; - return; - } - - [sender stopLoading:identifier]; - - didFinishLoad = YES; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, StopLoadingFromDidReceiveResponse) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - - RetainPtr<StopLoadingFromDidReceiveResponse> resourceLoadDelegate = adoptNS([[StopLoadingFromDidReceiveResponse alloc] init]); - webView.get().resourceLoadDelegate = resourceLoadDelegate.get(); - - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"StopLoadingFromDidReceiveResponse" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - - [pool drain]; - // If we finished without crashing, the test passed. -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/StringByEvaluatingJavaScriptFromString.mm b/Tools/TestWebKitAPI/Tests/mac/StringByEvaluatingJavaScriptFromString.mm deleted file mode 100644 index 260a5a53e..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/StringByEvaluatingJavaScriptFromString.mm +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2007, 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. - */ - -#import "config.h" -#import "PlatformUtilities.h" -#import <wtf/RetainPtr.h> - -namespace TestWebKitAPI { - -TEST(WebKit1, StringByEvaluatingJavaScriptFromString) -{ - // maps expected result <= JavaScript expression - RetainPtr<NSDictionary> expressions = adoptNS([[NSDictionary alloc] initWithObjectsAndKeys: - @"0", @"0", - @"0", @"'0'", - @"", @"", - @"", @"''", - @"", @"new String()", - @"", @"new String('0')", - @"", @"throw 1", - @"", @"{ }", - @"", @"[ ]", - @"", @"//", - @"", @"a.b.c", - @"", @"(function() { throw 'error'; })()", - @"", @"null", - @"", @"undefined", - @"true", @"true", - @"false", @"false", - @"", @"alert('Should not be result')", - nil - ]); - - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSZeroRect frameName:@"" groupName:@""]); - - // Test a nil string - NSString *result = [webView.get() stringByEvaluatingJavaScriptFromString:nil]; - EXPECT_WK_STREQ(@"", result); - - for (id expression in expressions.get()) { - NSString *expectedResult = [expressions.get() objectForKey:expression]; - NSString *result = [webView.get() stringByEvaluatingJavaScriptFromString:expression]; - EXPECT_WK_STREQ(expectedResult, result); - } - - [webView.get() close]; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/SubresourceErrorCrash.mm b/Tools/TestWebKitAPI/Tests/mac/SubresourceErrorCrash.mm deleted file mode 100644 index 870a4896a..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/SubresourceErrorCrash.mm +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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" - -namespace TestWebKitAPI { - -TEST(WebKit1, SubresourceErrorCrash) -{ - WebView *webView = [[WebView alloc] initWithFrame:NSZeroRect frameName:@"" groupName:@""]; - [webView.mainFrame loadHTMLString:@"<link rel=stylesheet href='x-error:error'>" baseURL:nil]; - [webView release]; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/WebViewCanPasteURL.mm b/Tools/TestWebKitAPI/Tests/mac/WebViewCanPasteURL.mm deleted file mode 100644 index d4bc83bf9..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/WebViewCanPasteURL.mm +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#import "WTFStringUtilities.h" - -#import <WebKit/WebViewPrivate.h> -#import <WebKit/DOM.h> - -namespace TestWebKitAPI { - -TEST(WebKit1, WebViewCanPasteURL) -{ - WebView *webView = [[WebView alloc] initWithFrame:NSZeroRect frameName:nil groupName:nil]; - [webView setEditable:YES]; - - [[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSURLPboardType] owner:nil]; - [[NSURL URLWithString:@"http://www.webkit.org/"] writeToPasteboard:[NSPasteboard generalPasteboard]]; - [webView paste:nil]; - - DOMDocument *document = [[webView mainFrame] DOMDocument]; - DOMElement *documentElement = [document documentElement]; - DOMHTMLAnchorElement *anchor = (DOMHTMLAnchorElement *)[documentElement querySelector:@"a"]; - NSString *text = [anchor href]; - - EXPECT_EQ(String("http://www.webkit.org/"), String(text)); - - [webView release]; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/WebViewCanPasteZeroPng.mm b/Tools/TestWebKitAPI/Tests/mac/WebViewCanPasteZeroPng.mm deleted file mode 100644 index 5049fb3af..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/WebViewCanPasteZeroPng.mm +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 "PlatformUtilities.h" -#import "WTFStringUtilities.h" - -#import <WebKit/WebViewPrivate.h> -#import <WebKit/DOM.h> - -namespace TestWebKitAPI { - -TEST(WebKit1, WebViewCanPasteZeroPng) -{ - WebView *webView = [[WebView alloc] initWithFrame:NSZeroRect frameName:nil groupName:nil]; - [webView setEditable:YES]; - - //pasting a 0x0 image as pdf board type. Referring to <rdar://problem/11141920> - [[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSPDFPboardType] owner:nil]; - [[[NSBundle mainBundle] URLForResource:@"0" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"] writeToPasteboard:[NSPasteboard generalPasteboard]]; - [webView paste:nil]; - - [webView release]; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/WebViewDidCreateJavaScriptContext.mm b/Tools/TestWebKitAPI/Tests/mac/WebViewDidCreateJavaScriptContext.mm deleted file mode 100644 index 39504dda8..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/WebViewDidCreateJavaScriptContext.mm +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformUtilities.h" -#import <JavaScriptCore/JSExport.h> -#import <JavaScriptCore/JSContext.h> -#import <WebKit/WebFrameLoadDelegatePrivate.h> -#import <wtf/RetainPtr.h> - -#if JSC_OBJC_API_ENABLED - -@class MyConsole; - -static bool didFinishLoad = false; -static bool didCompleteTestSuccessfully = false; -static bool didCallWindowCallback = false; -static bool didFindMyCustomProperty = false; -static bool didInsertMyCustomProperty = true; - -@protocol MyConsole<JSExport> -- (void)log:(NSString *)s; -- (void)printHelloWorld; -- (int)add:(int)a to:(int)b; -@end - -@interface MyConsole : NSObject<MyConsole> -@end - -@implementation MyConsole -- (void)log:(NSString *)s -{ - NSLog(@"%@", s); -} - -- (void)printHelloWorld -{ - NSLog(@"Hello, World!"); -} - -- (int)add:(int)a to:(int)b -{ - return a + b; -} -@end - -@interface DidCreateJavaScriptContextFrameLoadDelegate : NSObject -@end - -@implementation DidCreateJavaScriptContextFrameLoadDelegate - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -- (void)webView:(WebView *)webView didCreateJavaScriptContext:(JSContext *)context forFrame:(WebFrame *)frame -{ - MyConsole *myConsole = [[MyConsole alloc] init]; - context[@"myConsole"] = myConsole; - context.exceptionHandler = nil; - [myConsole release]; - - context[@"windowCallback"] = ^(JSValue *thisObject){ - didCallWindowCallback = true; - }; - - context[@"didCompleteTestSuccessfully"] = ^{ - didCompleteTestSuccessfully = true; - }; - - context[@"callMeBack"] = ^(JSValue *functionValue) { - [functionValue callWithArguments:[NSArray array]]; - }; - - context[@"checkForMyCustomProperty"] = ^(JSValue *element) { - if ([element hasProperty:@"myCustomProperty"] && [[element valueForProperty:@"myCustomProperty"] toInt32] == 42) - didFindMyCustomProperty = true; - else - NSLog(@"ERROR: Did not find myCustomProperty."); - }; - - context[@"insertMyCustomProperty"] = ^(JSValue *element) { - JSValue *fortyTwo = [JSValue valueWithInt32:42 inContext:[JSContext currentContext]]; - [element setValue:fortyTwo forProperty:@"myCustomProperty"]; - didInsertMyCustomProperty = true; - }; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, DidCreateJavaScriptContextSanity1) -{ - didFinishLoad = false; - @autoreleasepool { - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - WebFrame *mainFrame = webView.get().mainFrame; - - NSString *bodyString = - @"<body> \ - <script> \ - myConsole.printHelloWorld(); \ - myConsole.log(\"Loaded custom stuff.\"); \ - myConsole.log(myConsole.addTo(40, 2)); \ - didCompleteTestSuccessfully(); \ - </script> \ - </body>"; - NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"]; - - [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL]; - Util::run(&didCompleteTestSuccessfully); - } -} - -TEST(WebKit1, DidCreateJavaScriptContextSanity2) -{ - didCallWindowCallback = false; - @autoreleasepool { - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - WebFrame *mainFrame = webView.get().mainFrame; - - NSString *bodyString = - @"<body> \ - <script> \ - setTimeout(windowCallback, 100); \ - </script> \ - </body>"; - NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"]; - - [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL]; - Util::run(&didCallWindowCallback); - } -} - -TEST(WebKit1, DidCreateJavaScriptContextCallJSFunctionFromObjCCallbackTest) -{ - @autoreleasepool { - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - WebFrame *mainFrame = webView.get().mainFrame; - - NSString *bodyString = - @"<body> \ - <script> \ - callMeBack(function() { \ - didCompleteTestSuccessfully(); \ - }); \ - </script> \ - </body>"; - NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"]; - - [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL]; - Util::run(&didCompleteTestSuccessfully); - } -} - -TEST(WebKit1, DidCreateJavaScriptContextAddCustomPropertiesFromJSTest) -{ - didFindMyCustomProperty = false; - @autoreleasepool { - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - WebFrame *mainFrame = webView.get().mainFrame; - - NSString *bodyString = - @"<body> \ - <div id=\"test-div\"></div> \ - <script> \ - var testDiv = document.getElementById(\"test-div\"); \ - testDiv.myCustomProperty = 42; \ - checkForMyCustomProperty(testDiv); \ - </script> \ - </body>"; - NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"]; - - [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL]; - Util::run(&didFindMyCustomProperty); - } -} - -TEST(WebKit1, DidCreateJavaScriptContextAddCustomPropertiesFromObjCTest) -{ - didFindMyCustomProperty = false; - @autoreleasepool { - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - WebFrame *mainFrame = webView.get().mainFrame; - - NSString *bodyString = - @"<body> \ - <div id=\"test-div\"></div> \ - <script> \ - var testDiv = document.getElementById(\"test-div\"); \ - insertMyCustomProperty(testDiv); \ - if (testDiv.myCustomProperty === 42) { \ - checkForMyCustomProperty(testDiv); \ - } \ - </script> \ - </body>"; - NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"]; - - [mainFrame loadHTMLString:bodyString baseURL:aboutBlankURL]; - Util::run(&didFindMyCustomProperty); - } -} - -TEST(WebKit1, DidCreateJavaScriptContextBackForwardCacheTest) -{ - didInsertMyCustomProperty = false; - didFindMyCustomProperty = false; - didCompleteTestSuccessfully = false; - @autoreleasepool { - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<DidCreateJavaScriptContextFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidCreateJavaScriptContextFrameLoadDelegate alloc] init]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - WebFrame *mainFrame = webView.get().mainFrame; - - NSURL *url1 = [[NSBundle mainBundle] URLForResource:@"JSContextBackForwardCache1" - withExtension:@"html" - subdirectory:@"TestWebKitAPI.resources"]; - [mainFrame loadRequest:[NSURLRequest requestWithURL:url1]]; - Util::run(&didInsertMyCustomProperty); - - NSURL *url2 = [[NSBundle mainBundle] URLForResource:@"JSContextBackForwardCache2" - withExtension:@"html" - subdirectory:@"TestWebKitAPI.resources"]; - [mainFrame loadRequest:[NSURLRequest requestWithURL:url2]]; - Util::run(&didCompleteTestSuccessfully); - - didCompleteTestSuccessfully = false; - [[mainFrame javaScriptContext] evaluateScript: - @"var testDiv = document.getElementById(\"test-div\"); \ - if (!testDiv.myCustomProperty) { \ - didCompleteTestSuccessfully(); \ - }"]; - EXPECT_TRUE(didCompleteTestSuccessfully); - - if ([webView.get() goBack]) { - [[mainFrame javaScriptContext] evaluateScript: - @"var testDiv = document.getElementById(\"test-div\"); \ - checkForMyCustomProperty(testDiv);"]; - EXPECT_TRUE(didFindMyCustomProperty); - } else - EXPECT_TRUE(false); - } -} - -} // namespace TestWebKitAPI - -#endif // ENABLE(JSC_OBJC_API) diff --git a/Tools/TestWebKitAPI/Tests/mac/WebViewDidRemoveFrameFromHierarchy.mm b/Tools/TestWebKitAPI/Tests/mac/WebViewDidRemoveFrameFromHierarchy.mm deleted file mode 100644 index fbe8af52a..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/WebViewDidRemoveFrameFromHierarchy.mm +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformUtilities.h" -#import <WebKit/WebFrameLoadDelegatePrivate.h> -#import <wtf/RetainPtr.h> - -@interface DidRemoveFrameFromHierarchyFrameLoadDelegate : NSObject -@end - -static bool didFinishLoad; -static bool didRemoveFrame; - -@implementation DidRemoveFrameFromHierarchyFrameLoadDelegate - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -- (void)webView:(WebView *)sender didRemoveFrameFromHierarchy:(WebFrame *)frame -{ - didRemoveFrame = true; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, DidRemoveFrameFromHierarchy) -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<DidRemoveFrameFromHierarchyFrameLoadDelegate> frameLoadDelegate = adoptNS([[DidRemoveFrameFromHierarchyFrameLoadDelegate alloc] init]); - - webView.get().frameLoadDelegate = frameLoadDelegate.get(); - WebFrame *mainFrame = webView.get().mainFrame; - - NSString *bodyWithIFrameString = @"<body><iframe id='iframe'></iframe></body>"; - NSURL *aboutBlankURL = [NSURL URLWithString:@"about:blank"]; - - [mainFrame loadHTMLString:bodyWithIFrameString baseURL:aboutBlankURL]; - Util::run(&didFinishLoad); - - EXPECT_FALSE(didRemoveFrame); - [webView.get() stringByEvaluatingJavaScriptFromString:@"document.body.removeChild(document.getElementById('iframe'))"]; - EXPECT_TRUE(didRemoveFrame); - - didFinishLoad = false; - didRemoveFrame = false; - - [mainFrame loadHTMLString:bodyWithIFrameString baseURL:aboutBlankURL]; - Util::run(&didFinishLoad); - - // The delegate method is not called when the frame is removed due to navigation in an ancestor frame. - EXPECT_FALSE(didRemoveFrame); - [mainFrame loadHTMLString:@"<body></body>" baseURL:aboutBlankURL]; - EXPECT_FALSE(didRemoveFrame); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/WillSendSubmitEvent.mm b/Tools/TestWebKitAPI/Tests/mac/WillSendSubmitEvent.mm deleted file mode 100644 index 1654f9ca8..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/WillSendSubmitEvent.mm +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2013 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 "PlatformUtilities.h" -#import "PlatformWebView.h" -#import "Test.h" - -#import <WebKit/WebFormDelegate.h> -#import <WebKit/WebViewPrivate.h> -#import <wtf/RetainPtr.h> - -static bool didFinishLoad; - -@interface FormDelegate : WebFormDelegate -@end - -@implementation FormDelegate - -- (void)willSendSubmitEventToForm:(DOMHTMLFormElement *)element inFrame:(WebFrame *)sourceFrame withValues:(NSDictionary *)values -{ - EXPECT_NOT_NULL(element); - EXPECT_NOT_NULL(sourceFrame); - - EXPECT_WK_STREQ([values objectForKey:@"textField"], @"text field"); - EXPECT_WK_STREQ([values objectForKey:@"passwordField"], @"password field"); - - // <input type="hidden"> fields are not sent. - EXPECT_NULL([values objectForKey:@"hiddenField"]); - - didFinishLoad = true; -} - -@end - -namespace TestWebKitAPI { - -TEST(WebKit1, WillSendSubmitEvent) -{ - @autoreleasepool { - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - - RetainPtr<FormDelegate> formDelegate = [[FormDelegate alloc] init]; - [webView _setFormDelegate:formDelegate.get()]; - - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"auto-submitting-form" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - Util::run(&didFinishLoad); - } -} - -} diff --git a/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.html b/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.html deleted file mode 100644 index db064fb05..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.html +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html> -<body> - We want to make sure the page sends its onload event even if it has media in a windowless WebView. - <audio src="invalid.mp3"></audio> - <script> - var didTriggerLoad = false; - window.addEventListener('load', function(event) { - didTriggerLoad = true; - }, false); - </script> -</body> -</html> diff --git a/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.mm b/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.mm deleted file mode 100644 index 9225783ab..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/WindowlessWebViewWithMedia.mm +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - */ - -#include "config.h" -#include "JavaScriptTest.h" -#include "PlatformUtilities.h" -#include <wtf/RetainPtr.h> - - -static bool didFinishLoad; - -@interface WindowlessWebViewWithMediaFrameLoadDelegate : NSObject -@end - -@implementation WindowlessWebViewWithMediaFrameLoadDelegate - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - didFinishLoad = true; -} - -@end - - -namespace TestWebKitAPI { - -static void spinLoop(NSTimeInterval timeout, BOOL (^block)()) -{ - if (timeout <= 0) - return; - - NSTimeInterval end = [[NSDate date] timeIntervalSinceReferenceDate] + timeout; - NSDate *endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:end]; - - while (!block()) { - [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate]; - if ([[NSDate date] timeIntervalSinceReferenceDate] > end) - break; - } -} - -TEST(WebKit1, WindowlessWebViewWithMedia) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]); - RetainPtr<WindowlessWebViewWithMediaFrameLoadDelegate> testController = adoptNS([WindowlessWebViewWithMediaFrameLoadDelegate new]); - webView.get().frameLoadDelegate = testController.get(); - [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"WindowlessWebViewWithMedia" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; - - EXPECT_EQ(nil, [webView.get() window]); - - Util::run(&didFinishLoad); - - spinLoop(0.25, ^{ - return [[webView.get() stringByEvaluatingJavaScriptFromString:@"window.didTriggerLoad"] isEqualToString:@"true"]; - }); - - EXPECT_JS_EQ(webView.get(), "window.didTriggerLoad", "true"); - - [pool drain]; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/Tests/mac/acceptsFirstMouse.html b/Tools/TestWebKitAPI/Tests/mac/acceptsFirstMouse.html deleted file mode 100644 index 3de413a5a..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/acceptsFirstMouse.html +++ /dev/null @@ -1,23 +0,0 @@ -<!DOCTYPE html> -<html style="height: 200%;"> -<head> - <style> - img.selectable { - width: 100px; - height: 100px; - display: block; - background-color: gray; - } - </style> -</head> -<body style="margin: 0;"> - <img class="selectable"> - <img class="selectable" id="target"> - <img class="selectable"> - <script> - var target = document.getElementById("target"); - getSelection().setBaseAndExtent(target, 0, target, 1); - scrollBy(0, 100); - </script> -</body> -</html> diff --git a/Tools/TestWebKitAPI/Tests/mac/attributedStringCustomFont.html b/Tools/TestWebKitAPI/Tests/mac/attributedStringCustomFont.html deleted file mode 100644 index 1e6b90a82..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/attributedStringCustomFont.html +++ /dev/null @@ -1,15 +0,0 @@ -<html> - <head> - <style> - @font-face { - font-family: customFont; - src: url(Ahem.ttf); - } - </style> - </head> - <body contenteditable style="font-family: customFont; font-size: 48px;">Lorem Ipsum - <script> - document.body.focus(); - </script> - </body> -</html> diff --git a/Tools/TestWebKitAPI/Tests/mac/devicePixelRatio.html b/Tools/TestWebKitAPI/Tests/mac/devicePixelRatio.html deleted file mode 100644 index f6acf8678..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/devicePixelRatio.html +++ /dev/null @@ -1,23 +0,0 @@ -<!DOCTYPE html> -<style> - #detector { width: 5px; } - @media (-webkit-device-pixel-ratio:1) { #detector { width: 10px; } } - @media (-webkit-device-pixel-ratio:3) { #detector { width: 30px; } } - @media (-webkit-device-pixel-ratio:4) { #detector { width: 40px; } } -</style> -<script> - function devicePixelRatioFromStyle() { - var width = getComputedStyle(document.getElementById("detector")).width; - switch (width) { - case "10px": - return 1; - case "30px": - return 3; - case "40px": - return 4; - default: - return "unknown width: " + width; - } - } -</script> -<div id="detector"></div> diff --git a/Tools/TestWebKitAPI/Tests/mac/verboseMarkup.html b/Tools/TestWebKitAPI/Tests/mac/verboseMarkup.html deleted file mode 100644 index c8a24487e..000000000 --- a/Tools/TestWebKitAPI/Tests/mac/verboseMarkup.html +++ /dev/null @@ -1,19 +0,0 @@ -<html> - <body contenteditable="true"> - <div>Hello</div> - <div id="test1"><b><i>Hello</i></b></div> - <div><b><i><span style="font-weight: normal"><b><i>Hello</i></b></span></i></b></div> - <div><div><div>Hello</div></div></div> - <div><b><div><i>Hello</i></div></b></div> - <div><div style="text-align: center;"><b>Hello</b></div></div> - <div id="test2"><b><i><span style="font-weight: normal"><b><i>hello</i></b></span></i></b></div><div><b><i><span style="font-weight: normal"><b><i>world</i></b></span></i></b></div> - <div><b><i><span style="font-weight: normal;"><b><i>hello1</i></b><b><i> hello2</i></b></span></i></b></div> - <div><i style="margin: 10px;"><b><i style="margin: 10px;">hello</i></b></i></div> - <div><b><i><span style="font-weight: normal"><b><i>Hello <!-- comment -->world</i></b></span></i></b></div> - <div><b><i><span style="font-weight: normal">plain text<b><i>bold italic text</i></b></span></i></b></div> - <iframe id="test3" src="data:text/html, - <div>This is another document.</div> - "> - </iframe> - </body> -</html> diff --git a/Tools/TestWebKitAPI/TestsController.cpp b/Tools/TestWebKitAPI/TestsController.cpp index 29dcc714e..913305d7b 100644 --- a/Tools/TestWebKitAPI/TestsController.cpp +++ b/Tools/TestWebKitAPI/TestsController.cpp @@ -30,9 +30,33 @@ namespace TestWebKitAPI { -TestsController& TestsController::shared() +class Printer : public ::testing::EmptyTestEventListener { + virtual void OnTestPartResult(const ::testing::TestPartResult& test_part_result) + { + if (!test_part_result.failed()) + return; + + std::stringstream stream; + stream << "\n" << test_part_result.file_name() << ":" << test_part_result.line_number() << "\n" << test_part_result.summary() << "\n\n"; + failures += stream.str(); + } + + virtual void OnTestEnd(const ::testing::TestInfo& test_info) + { + if (test_info.result()->Passed()) + std::cout << "**PASS** " << test_info.test_case_name() << "." << test_info.name() << "\n"; + else + std::cout << "**FAIL** " << test_info.test_case_name() << "." << test_info.name() << "\n" << failures; + + failures = std::string(); + } + + std::string failures; +}; + +TestsController& TestsController::singleton() { - static TestsController& shared = *new TestsController; + static NeverDestroyed<TestsController> shared; return shared; } @@ -48,6 +72,11 @@ TestsController::TestsController() bool TestsController::run(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); + + ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); + delete listeners.Release(listeners.default_result_printer()); + listeners.Append(new Printer); + return !RUN_ALL_TESTS(); } diff --git a/Tools/TestWebKitAPI/TestsController.h b/Tools/TestWebKitAPI/TestsController.h index c73e3ac4d..ea8496853 100644 --- a/Tools/TestWebKitAPI/TestsController.h +++ b/Tools/TestWebKitAPI/TestsController.h @@ -26,17 +26,21 @@ #ifndef TestsController_h #define TestsController_h +#include <wtf/NeverDestroyed.h> + namespace TestWebKitAPI { class TestsController { public: - static TestsController& shared(); + static TestsController& singleton(); bool run(int argc, char** argv); private: TestsController(); ~TestsController(); + + friend class WTF::NeverDestroyed<TestsController>; }; } // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/mac/TestProtocol.h b/Tools/TestWebKitAPI/WKWebViewConfigurationExtras.h index cf6734b88..782da85d4 100644 --- a/Tools/TestWebKitAPI/mac/TestProtocol.h +++ b/Tools/TestWebKitAPI/WKWebViewConfigurationExtras.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,12 +23,12 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef TestProtocol_h -#define TestProtocol_h +#import <WebKit/WKWebViewConfiguration.h> -@interface TestProtocol : NSURLProtocol { -} -+ (NSString *)scheme; +#if WK_API_ENABLED + +@interface WKWebViewConfiguration (TestWebKitAPIExtras) ++ (instancetype)testwebkitapi_configurationWithTestPlugInClassName:(NSString *)className; @end -#endif // TestProtocol_h +#endif // WK_API_ENABLED diff --git a/Tools/TestWebKitAPI/config.h b/Tools/TestWebKitAPI/config.h index 0fb19e1c3..ccee71073 100644 --- a/Tools/TestWebKitAPI/config.h +++ b/Tools/TestWebKitAPI/config.h @@ -23,16 +23,11 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H -#ifdef BUILDING_WITH_CMAKE +#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H && defined(BUILDING_WITH_CMAKE) #include "cmakeconfig.h" -#else -#include "autotoolsconfig.h" -#endif #endif -#include <wtf/Platform.h> -#include <wtf/ExportMacros.h> +#include <WebCore/PlatformExportMacros.h> #include <runtime/JSExportMacros.h> #if defined(__APPLE__) && __APPLE__ @@ -52,24 +47,24 @@ #endif #if PLATFORM(WIN_CAIRO) -#undef WTF_USE_CG -#define WTF_USE_CAIRO 1 -#define WTF_USE_CURL 1 +#undef USE_CG +#define USE_CAIRO 1 +#define USE_CURL 1 #ifndef _WINSOCKAPI_ #define _WINSOCKAPI_ // Prevent inclusion of winsock.h in windows.h #endif -#elif !OS(WINCE) -#define WTF_USE_CG 1 -#undef WTF_USE_CAIRO -#undef WTF_USE_CURL +#else +#define USE_CG 1 +#undef USE_CAIRO +#undef USE_CURL #endif #endif // PLATFORM(WIN) #include <stdint.h> -#if !PLATFORM(IOS) && !PLATFORM(WIN) && !(PLATFORM(GTK) && !defined(BUILDING_WEBKIT2__)) -#include <WebKit2/WebKit2_C.h> +#if !PLATFORM(IOS) && !PLATFORM(WIN) && !(PLATFORM(QT) && !defined(HAVE_WEBKIT2)) +#include <WebKit/WebKit2_C.h> #endif #ifdef __clang__ @@ -87,6 +82,13 @@ #pragma clang diagnostic pop #endif -#if PLATFORM(MAC) && defined(__OBJC__) +#if PLATFORM(COCOA) && defined(__OBJC__) +// FIXME: Get Cocoa tests working with CMake on Mac. +#if !defined(BUILDING_WITH_CMAKE) #import <WebKit/WebKit.h> #endif +#endif + +#if !PLATFORM(IOS) +#define WK_HAVE_C_SPI 1 +#endif diff --git a/Tools/TestWebKitAPI/efl/PlatformWebView.cpp b/Tools/TestWebKitAPI/efl/PlatformWebView.cpp deleted file mode 100644 index 5a3aa6b1e..000000000 --- a/Tools/TestWebKitAPI/efl/PlatformWebView.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics - * 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" -#include "ewk_view_private.h" -#include "PlatformWebView.h" - -#include "EWebKit2.h" -#include <WebKit2/WKAPICast.h> -#include <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKViewEfl.h> -#include <Ecore_Evas.h> - -extern bool useX11Window; - -using namespace WebKit; - -namespace TestWebKitAPI { - -static Ecore_Evas* initEcoreEvas() -{ - if (!ecore_evas_init()) - return 0; - - Ecore_Evas* ecoreEvas; -#if defined(WTF_USE_ACCELERATED_COMPOSITING) && defined(HAVE_ECORE_X) - ecoreEvas = ecore_evas_new("opengl_x11", 0, 0, 800, 600, 0); - // Graceful fallback to software rendering if evas_gl engine is not available. - if (!ecoreEvas) -#endif - ecoreEvas = ecore_evas_new(0, 0, 0, 800, 600, 0); - - ASSERT(ecoreEvas); - - ecore_evas_show(ecoreEvas); - - return ecoreEvas; -} - -static void onWebProcessCrashed(void*, Evas_Object*, void* eventInfo) -{ - bool* handled = static_cast<bool*>(eventInfo); - *handled = true; -} - -PlatformWebView::PlatformWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef) -{ - m_window = initEcoreEvas(); - - m_view = EWKViewCreate(contextRef, pageGroupRef, ecore_evas_get(m_window), /* smart */ 0); - - WKRetainPtr<WKStringRef> wkTheme = adoptWK(WKStringCreateWithUTF8CString(TEST_THEME_DIR "/default.edj")); - WKViewSetThemePath(EWKViewGetWKView(m_view), wkTheme.get()); - - evas_object_smart_callback_add(m_view, "webprocess,crashed", onWebProcessCrashed, 0); - resizeTo(600, 800); -} - -PlatformWebView::~PlatformWebView() -{ - evas_object_del(m_view); - - ecore_evas_free(m_window); - ecore_evas_shutdown(); -} - -void PlatformWebView::resizeTo(unsigned width, unsigned height) -{ - evas_object_resize(m_view, width, height); -} - -WKPageRef PlatformWebView::page() const -{ - return WKViewGetPage(EWKViewGetWKView(m_view)); -} - -void PlatformWebView::simulateSpacebarKeyPress() -{ - Evas* evas = evas_object_evas_get(m_view); - evas_object_focus_set(m_view, true); - evas_event_feed_key_down(evas, "space", "space", " ", 0, 0, 0); - evas_event_feed_key_up(evas, "space", "space", " ", 0, 1, 0); -} - -void PlatformWebView::simulateMouseMove(unsigned x, unsigned y) -{ - Evas* evas = evas_object_evas_get(m_view); - evas_object_show(m_view); - evas_event_feed_mouse_move(evas, x, y, 0, 0); -} - -void PlatformWebView::simulateRightClick(unsigned x, unsigned y) -{ - Evas* evas = evas_object_evas_get(m_view); - evas_object_show(m_view); - evas_event_feed_mouse_move(evas, x, y, 0, 0); - evas_event_feed_mouse_down(evas, 3, EVAS_BUTTON_NONE, 0, 0); - evas_event_feed_mouse_up(evas, 3, EVAS_BUTTON_NONE, 0, 0); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/efl/main.cpp b/Tools/TestWebKitAPI/efl/main.cpp deleted file mode 100644 index c69ec450c..000000000 --- a/Tools/TestWebKitAPI/efl/main.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics - * 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" -#include "TestsController.h" -#include <Ecore.h> -#include <Eina.h> -#include <getopt.h> -#include <wtf/Assertions.h> - -bool useX11Window = false; - -static bool checkForUseX11WindowArgument(int argc, char** argv) -{ - int hasUseX11Window = 0; - - static const option options[] = { - {"useX11Window", no_argument, &hasUseX11Window, 1}, - {0, 0, 0, 0} - }; - - while (getopt_long(argc, argv, "", options, 0) != -1) { } - - return hasUseX11Window; -} - -int main(int argc, char** argv) -{ - WTFInstallReportBacktraceOnCrashHook(); - - if (!eina_init()) - return EXIT_FAILURE; - - if (!ecore_init()) - return EXIT_FAILURE; - - useX11Window = checkForUseX11WindowArgument(argc, argv); - - int returnCode = TestWebKitAPI::TestsController::shared().run(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE; - - ecore_shutdown(); - eina_shutdown(); - - return returnCode; -} diff --git a/Tools/TestWebKitAPI/gtk/InjectedBundleControllerGtk.cpp b/Tools/TestWebKitAPI/gtk/InjectedBundleControllerGtk.cpp deleted file mode 100644 index 5d55002cc..000000000 --- a/Tools/TestWebKitAPI/gtk/InjectedBundleControllerGtk.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * 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 "InjectedBundleController.h" - -namespace TestWebKitAPI { - -void InjectedBundleController::platformInitialize() -{ -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/gtk/PlatformUtilitiesGtk.cpp b/Tools/TestWebKitAPI/gtk/PlatformUtilitiesGtk.cpp deleted file mode 100644 index 6fd05f5f3..000000000 --- a/Tools/TestWebKitAPI/gtk/PlatformUtilitiesGtk.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * 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 "PlatformUtilities.h" - -#include <gtk/gtk.h> -#include <wtf/gobject/GOwnPtr.h> -#include <wtf/gobject/GRefPtr.h> - -namespace TestWebKitAPI { -namespace Util { - -static gboolean checkTestFinished(gpointer userData) -{ - bool* done = static_cast<bool*>(userData); - - if (*done) - gtk_main_quit(); - - return !*done; -} - -void run(bool* done) -{ - g_idle_add(checkTestFinished, done); - gtk_main(); -} - -void sleep(double seconds) -{ - g_usleep(seconds * 1000000); -} - -static char* getFilenameFromEnvironmentVariableAsUTF8(const char* variableName) -{ - const char* value = g_getenv(variableName); - if (!value) { - g_printerr("%s environment variable not found\n", variableName); - exit(1); - } - gsize bytesWritten; - return g_filename_to_utf8(value, -1, 0, &bytesWritten, 0); -} - -WKStringRef createInjectedBundlePath() -{ - GOwnPtr<char> injectedBundlePath(getFilenameFromEnvironmentVariableAsUTF8("TEST_WEBKIT_API_WEBKIT2_INJECTED_BUNDLE_PATH")); - GOwnPtr<char> injectedBundleFilename(g_build_filename(injectedBundlePath.get(), "libTestWebKitAPIInjectedBundle.la", NULL)); - return WKStringCreateWithUTF8CString(injectedBundleFilename.get()); -} - -WKURLRef createURLForResource(const char* resource, const char* extension) -{ - GOwnPtr<char> testResourcesPath(getFilenameFromEnvironmentVariableAsUTF8("TEST_WEBKIT_API_WEBKIT2_RESOURCES_PATH")); - GOwnPtr<char> resourceBasename(g_strdup_printf("%s.%s", resource, extension)); - GOwnPtr<char> resourceFilename(g_build_filename(testResourcesPath.get(), resourceBasename.get(), NULL)); - GRefPtr<GFile> resourceFile = adoptGRef(g_file_new_for_path(resourceFilename.get())); - GOwnPtr<char> resourceURI(g_file_get_uri(resourceFile.get())); - return WKURLCreateWithUTF8CString(resourceURI.get()); -} - -WKURLRef URLForNonExistentResource() -{ - return WKURLCreateWithUTF8CString("file:///does-not-exist.html"); -} - -bool isKeyDown(WKNativeEventPtr event) -{ - return event->type == GDK_KEY_PRESS; -} - -} // namespace Util -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/gtk/PlatformWebViewGtk.cpp b/Tools/TestWebKitAPI/gtk/PlatformWebViewGtk.cpp deleted file mode 100644 index ba6fab048..000000000 --- a/Tools/TestWebKitAPI/gtk/PlatformWebViewGtk.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * 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 "PlatformWebView.h" - -#include <WebCore/GOwnPtrGtk.h> -#include <gtk/gtk.h> -#include <wtf/gobject/GOwnPtr.h> - -namespace TestWebKitAPI { - -PlatformWebView::PlatformWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef) -{ - m_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - m_view = WKViewCreate(contextRef, pageGroupRef); - gtk_container_add(GTK_CONTAINER(m_window), GTK_WIDGET(m_view)); - gtk_widget_show(GTK_WIDGET(m_view)); - gtk_widget_show(m_window); -} - -PlatformWebView::~PlatformWebView() -{ - gtk_widget_destroy(m_window); -} - -WKPageRef PlatformWebView::page() const -{ - return WKViewGetPage(m_view); -} - -void PlatformWebView::resizeTo(unsigned width, unsigned height) -{ - gtk_window_resize(GTK_WINDOW(m_window), width, height); -} - -static void doKeyStroke(GtkWidget* viewWidget, unsigned int keyVal) -{ - GOwnPtr<GdkEvent> event(gdk_event_new(GDK_KEY_PRESS)); - event->key.keyval = keyVal; - event->key.time = GDK_CURRENT_TIME; - event->key.state = 0; - event->key.window = gtk_widget_get_window(viewWidget); - g_object_ref(event->key.window); - gdk_event_set_device(event.get(), gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget)))); - - // When synthesizing an event, an invalid hardware_keycode value can cause it to be badly processed by GTK+. - GOwnPtr<GdkKeymapKey> keys; - int keysCount; - if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount)) - event->key.hardware_keycode = keys.get()[0].keycode; - - gtk_main_do_event(event.get()); - event->key.type = GDK_KEY_RELEASE; - gtk_main_do_event(event.get()); -} - -void PlatformWebView::simulateSpacebarKeyPress() -{ - GtkWidget* viewWidget = GTK_WIDGET(m_view); - if (!gtk_widget_get_realized(viewWidget)) - gtk_widget_show(m_window); - doKeyStroke(viewWidget, GDK_KEY_KP_Space); -} - -void PlatformWebView::simulateAltKeyPress() -{ - GtkWidget* viewWidget = GTK_WIDGET(m_view); - if (!gtk_widget_get_realized(viewWidget)) - gtk_widget_show(m_window); - doKeyStroke(viewWidget, GDK_KEY_Alt_L); -} - -static void doMouseButtonEvent(GtkWidget* viewWidget, GdkEventType eventType, int x, int y, unsigned int button) -{ - GOwnPtr<GdkEvent> event(gdk_event_new(eventType)); - event->button.x = x; - event->button.y = y; - event->button.button = button; - event->button.time = GDK_CURRENT_TIME; - event->button.axes = 0; - event->button.state = 0; - event->button.window = gtk_widget_get_window(viewWidget); - g_object_ref(event->button.window); - event->button.device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget))); - - int xRoot, yRoot; - gdk_window_get_root_coords(gtk_widget_get_window(viewWidget), x, y, &xRoot, &yRoot); - event->button.x_root = xRoot; - event->button.y_root = yRoot; - gtk_main_do_event(event.get()); -} - -void PlatformWebView::simulateRightClick(unsigned x, unsigned y) -{ - GtkWidget* viewWidget = GTK_WIDGET(m_view); - if (!gtk_widget_get_realized(viewWidget)) - gtk_widget_show(m_window); - doMouseButtonEvent(viewWidget, GDK_BUTTON_PRESS, x, y, 3); - doMouseButtonEvent(viewWidget, GDK_BUTTON_RELEASE, x, y, 3); -} - -void PlatformWebView::simulateMouseMove(unsigned x, unsigned y) -{ - GOwnPtr<GdkEvent> event(gdk_event_new(GDK_MOTION_NOTIFY)); - event->motion.x = x; - event->motion.y = y; - event->motion.time = GDK_CURRENT_TIME; - event->motion.state = 0; - event->motion.axes = 0; - - GtkWidget* viewWidget = GTK_WIDGET(m_view); - if (!gtk_widget_get_realized(viewWidget)) - gtk_widget_show(m_window); - event->motion.window = gtk_widget_get_window(viewWidget); - g_object_ref(event->motion.window); - event->motion.device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget))); - - int xRoot, yRoot; - gdk_window_get_root_coords(gtk_widget_get_window(viewWidget), x, y, &xRoot, &yRoot); - event->motion.x_root = xRoot; - event->motion.y_root = yRoot; - gtk_main_do_event(event.get()); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/gtk/main.cpp b/Tools/TestWebKitAPI/gtk/main.cpp deleted file mode 100644 index 1b7fef64f..000000000 --- a/Tools/TestWebKitAPI/gtk/main.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * 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 "TestsController.h" - -#include <gtk/gtk.h> - -int main(int argc, char** argv) -{ - gtk_init(&argc, &argv); - - return TestWebKitAPI::TestsController::shared().run(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/Tools/TestWebKitAPI/mac/InjectedBundleControllerMac.mm b/Tools/TestWebKitAPI/mac/InjectedBundleControllerMac.mm deleted file mode 100644 index 5d6712a57..000000000 --- a/Tools/TestWebKitAPI/mac/InjectedBundleControllerMac.mm +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - */ - -#import "config.h" -#import "InjectedBundleController.h" - -#import <Foundation/Foundation.h> - -namespace TestWebKitAPI { - -void InjectedBundleController::platformInitialize() -{ - // Set up user defaults. - NSMutableDictionary *argumentDomain = [[[NSUserDefaults standardUserDefaults] volatileDomainForName:NSArgumentDomain] mutableCopy]; - if (!argumentDomain) - argumentDomain = [[NSMutableDictionary alloc] init]; - - NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInteger:4], @"AppleAntiAliasingThreshold", - [NSNumber numberWithInteger:0], @"AppleFontSmoothing", -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 - [NSNumber numberWithBool:NO], @"NSScrollAnimationEnabled", -#else - [NSNumber numberWithBool:NO], @"AppleScrollAnimationEnabled", -#endif - [NSNumber numberWithBool:NO], @"NSOverlayScrollersEnabled", - @"Always", @"AppleShowScrollBars", - nil]; - - [argumentDomain addEntriesFromDictionary:dict]; - [[NSUserDefaults standardUserDefaults] setVolatileDomain:argumentDomain forName:NSArgumentDomain]; - - [argumentDomain release]; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/mac/InstanceMethodSwizzler.h b/Tools/TestWebKitAPI/mac/InstanceMethodSwizzler.h deleted file mode 100644 index fe31a8aa9..000000000 --- a/Tools/TestWebKitAPI/mac/InstanceMethodSwizzler.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ - -#ifndef InstanceMethodSwizzler_h -#define InstanceMethodSwizzler_h - -#include <objc/runtime.h> -#include <wtf/Noncopyable.h> - -namespace TestWebKitAPI { - -class InstanceMethodSwizzler { - WTF_MAKE_NONCOPYABLE(InstanceMethodSwizzler); -public: - InstanceMethodSwizzler(Class, SEL, IMP); - ~InstanceMethodSwizzler(); - - Method m_method; - IMP m_originalImplementation; -}; - -} // namespace TestWebKitAPI - -#endif // InstanceMethodSwizzler_h diff --git a/Tools/TestWebKitAPI/mac/InstanceMethodSwizzler.mm b/Tools/TestWebKitAPI/mac/InstanceMethodSwizzler.mm deleted file mode 100644 index 4c37da4b8..000000000 --- a/Tools/TestWebKitAPI/mac/InstanceMethodSwizzler.mm +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 "InstanceMethodSwizzler.h" - -namespace TestWebKitAPI { - -InstanceMethodSwizzler::InstanceMethodSwizzler(Class cls, SEL selector, IMP implementation) - : m_method(class_getInstanceMethod(cls, selector)) - , m_originalImplementation(method_setImplementation(m_method, implementation)) -{ -} - -InstanceMethodSwizzler::~InstanceMethodSwizzler() -{ - method_setImplementation(m_method, m_originalImplementation); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/mac/JavaScriptTestMac.mm b/Tools/TestWebKitAPI/mac/JavaScriptTestMac.mm deleted file mode 100644 index b2526679f..000000000 --- a/Tools/TestWebKitAPI/mac/JavaScriptTestMac.mm +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 "JavaScriptTest.h" - -#include <WebKit/WebView.h> -#include <WebKit2/WKViewPrivate.h> - -namespace TestWebKitAPI { - -::testing::AssertionResult runJSTest(const char*, const char*, const char*, WebView *webView, const char* script, const char* expectedResult) -{ - NSString *actualResult = [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithUTF8String:script]]; - return compareJSResult(script, [actualResult UTF8String], expectedResult); -} - -::testing::AssertionResult runJSTest(const char* viewExpr, const char* scriptExpr, const char* expectedResultExpr, WKView *view, const char* script, const char* expectedResult) -{ - return runJSTest(viewExpr, scriptExpr, expectedResultExpr, [view pageRef], script, expectedResult); -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/mac/PlatformUtilitiesMac.mm b/Tools/TestWebKitAPI/mac/PlatformUtilitiesMac.mm deleted file mode 100644 index 1e73adbb3..000000000 --- a/Tools/TestWebKitAPI/mac/PlatformUtilitiesMac.mm +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2010 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 "PlatformUtilities.h" - -#include <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKStringCF.h> -#include <WebKit2/WKURLCF.h> -#include <WebKit2/WKURLResponseNS.h> -#include <wtf/OwnArrayPtr.h> -#include <wtf/RetainPtr.h> - -namespace TestWebKitAPI { -namespace Util { - -void run(bool* done) -{ - while (!*done) - [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]; -} - -void sleep(double seconds) -{ - usleep(seconds * 1000000); -} - -WKStringRef createInjectedBundlePath() -{ - NSString *nsString = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"InjectedBundleTestWebKitAPI.bundle"]; - return WKStringCreateWithCFString((CFStringRef)nsString); -} - -WKURLRef createURLForResource(const char* resource, const char* extension) -{ - NSURL *nsURL = [[NSBundle mainBundle] URLForResource:[NSString stringWithUTF8String:resource] withExtension:[NSString stringWithUTF8String:extension] subdirectory:@"TestWebKitAPI.resources"]; - return WKURLCreateWithCFURL((CFURLRef)nsURL); -} - -WKURLRef URLForNonExistentResource() -{ - NSURL *nsURL = [NSURL URLWithString:@"file:///does-not-exist.html"]; - return WKURLCreateWithCFURL((CFURLRef)nsURL); -} - -WKRetainPtr<WKStringRef> MIMETypeForWKURLResponse(WKURLResponseRef wkResponse) -{ - RetainPtr<NSURLResponse> response = adoptNS(WKURLResponseCopyNSURLResponse(wkResponse)); - return adoptWK(WKStringCreateWithCFString((CFStringRef)[response.get() MIMEType])); -} - -bool isKeyDown(WKNativeEventPtr event) -{ - return [event type] == NSKeyDown; -} - -std::string toSTD(NSString *string) -{ - if (!string) - return std::string(); - - size_t bufferSize = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - OwnArrayPtr<char> buffer = adoptArrayPtr(new char[bufferSize]); - NSUInteger stringLength; - [string getBytes:buffer.get() maxLength:bufferSize usedLength:&stringLength encoding:NSUTF8StringEncoding options:0 range:NSMakeRange(0, [string length]) remainingRange:0]; - return std::string(buffer.get(), stringLength); -} - -} // namespace Util -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/mac/PlatformWebViewMac.mm b/Tools/TestWebKitAPI/mac/PlatformWebViewMac.mm deleted file mode 100644 index 1661074b2..000000000 --- a/Tools/TestWebKitAPI/mac/PlatformWebViewMac.mm +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2010 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 "PlatformWebView.h" - -#import <WebKit2/WKViewPrivate.h> -#import <Carbon/Carbon.h> - -@interface ActiveOffscreenWindow : NSWindow -@end - -@implementation ActiveOffscreenWindow -- (BOOL)isKeyWindow -{ - return YES; -} -@end - -namespace TestWebKitAPI { - -PlatformWebView::PlatformWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef) -{ - NSRect rect = NSMakeRect(0, 0, 800, 600); - m_view = [[WKView alloc] initWithFrame:rect contextRef:contextRef pageGroupRef:pageGroupRef]; - - NSRect windowRect = NSOffsetRect(rect, -10000, [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height - rect.size.height + 10000); - m_window = [[ActiveOffscreenWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]; - [m_window setColorSpace:[[NSScreen mainScreen] colorSpace]]; - [[m_window contentView] addSubview:m_view]; - [m_window orderBack:nil]; - [m_window setAutodisplay:NO]; - [m_window setReleasedWhenClosed:NO]; -} - -PlatformWebView::~PlatformWebView() -{ - [m_window close]; - [m_window release]; - [m_view release]; -} - -void PlatformWebView::resizeTo(unsigned width, unsigned height) -{ - [m_view setFrame:NSMakeRect(0, 0, width, height)]; -} - - -WKPageRef PlatformWebView::page() const -{ - return [m_view pageRef]; -} - -void PlatformWebView::focus() -{ - // Implement. -} - -void PlatformWebView::simulateSpacebarKeyPress() -{ - NSEvent *event = [NSEvent keyEventWithType:NSKeyDown - location:NSMakePoint(5, 5) - modifierFlags:0 - timestamp:GetCurrentEventTime() - windowNumber:[m_window windowNumber] - context:[NSGraphicsContext currentContext] - characters:@" " - charactersIgnoringModifiers:@" " - isARepeat:NO - keyCode:0x31]; - - [m_view keyDown:event]; - - event = [NSEvent keyEventWithType:NSKeyUp - location:NSMakePoint(5, 5) - modifierFlags:0 - timestamp:GetCurrentEventTime() - windowNumber:[m_window windowNumber] - context:[NSGraphicsContext currentContext] - characters:@" " - charactersIgnoringModifiers:@" " - isARepeat:NO - keyCode:0x31]; - - [m_view keyUp:event]; -} - -void PlatformWebView::simulateRightClick(unsigned x, unsigned y) -{ - NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown - location:NSMakePoint(x, y) - modifierFlags:0 - timestamp:GetCurrentEventTime() - windowNumber:[m_window windowNumber] - context:[NSGraphicsContext currentContext] - eventNumber:0 - clickCount:0 - pressure:0]; - - - [m_view rightMouseDown:event]; - - event = [NSEvent mouseEventWithType:NSRightMouseUp - location:NSMakePoint(x, y) - modifierFlags:0 - timestamp:GetCurrentEventTime() - windowNumber:[m_window windowNumber] - context:[NSGraphicsContext currentContext] - eventNumber:0 - clickCount:0 - pressure:0]; - - [m_view rightMouseUp:event]; - -} - -void PlatformWebView::simulateMouseMove(unsigned x, unsigned y) -{ - NSEvent *event = [NSEvent mouseEventWithType:NSMouseMoved - location:NSMakePoint(x, y) - modifierFlags:0 - timestamp:GetCurrentEventTime() - windowNumber:[m_window windowNumber] - context:[NSGraphicsContext currentContext] - eventNumber:0 - clickCount:0 - pressure:0]; - - [m_view mouseMoved:event]; - -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/mac/TestBrowsingContextLoadDelegate.h b/Tools/TestWebKitAPI/mac/TestBrowsingContextLoadDelegate.h deleted file mode 100644 index d8f8ffa95..000000000 --- a/Tools/TestWebKitAPI/mac/TestBrowsingContextLoadDelegate.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 <WebKit2/WebKit2.h> - -typedef void (^OnLoadBlock)(WKBrowsingContextController *); - -@interface TestBrowsingContextLoadDelegate : NSObject <WKBrowsingContextLoadDelegate> { -@private - OnLoadBlock _onLoadBlock; -} - -@property(nonatomic, copy) OnLoadBlock onLoadBlock; - -- (id)initWithBlockToRunOnLoad:(OnLoadBlock)block; - -@end diff --git a/Tools/TestWebKitAPI/mac/TestBrowsingContextLoadDelegate.mm b/Tools/TestWebKitAPI/mac/TestBrowsingContextLoadDelegate.mm deleted file mode 100644 index a6c8cef94..000000000 --- a/Tools/TestWebKitAPI/mac/TestBrowsingContextLoadDelegate.mm +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ - -#include "config.h" -#include "TestBrowsingContextLoadDelegate.h" - -@implementation TestBrowsingContextLoadDelegate - -@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
\ No newline at end of file diff --git a/Tools/TestWebKitAPI/mac/TestProtocol.mm b/Tools/TestWebKitAPI/mac/TestProtocol.mm deleted file mode 100644 index 367ea0489..000000000 --- a/Tools/TestWebKitAPI/mac/TestProtocol.mm +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2013 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 "TestProtocol.h" - -static NSString *testScheme = @"test"; - -@implementation TestProtocol - -+ (BOOL)canInitWithRequest:(NSURLRequest *)request -{ - return [[[request URL] scheme] caseInsensitiveCompare:testScheme] == NSOrderedSame; -} - -+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request -{ - return request; -} - -+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b -{ - return NO; -} - -+ (NSString *)scheme -{ - return testScheme; -} - -- (void)startLoading -{ - EXPECT_TRUE([[[[self request] URL] scheme] isEqualToString:testScheme]); - - NSData *data = [@"PASS" dataUsingEncoding:NSASCIIStringEncoding]; - NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[[self request] URL] MIMEType:@"text/html" expectedContentLength:[data length] textEncodingName:nil]; - [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - [[self client] URLProtocol:self didLoadData:data]; - [[self client] URLProtocolDidFinishLoading:self]; - [response release]; -} - -- (void)stopLoading -{ -} - -@end diff --git a/Tools/TestWebKitAPI/mac/WebKitAgnosticTest.h b/Tools/TestWebKitAPI/mac/WebKitAgnosticTest.h deleted file mode 100644 index c25c4b4cf..000000000 --- a/Tools/TestWebKitAPI/mac/WebKitAgnosticTest.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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. - */ - -#ifndef WebKitAgnosticTest_h -#define WebKitAgnosticTest_h - -#include "PlatformUtilities.h" - -namespace TestWebKitAPI { - -// This test fixture can be used to write test that work with both WebKit1 and WebKit2. Calling -// runWebKit1Test or runWebKit2Test will create a WebView or WKView (respectively), load the URL -// specified by url(), and then call didLoadURL. Your test's logic should go in didLoadURL. -class WebKitAgnosticTest : public ::testing::Test { -public: - WebKitAgnosticTest(); - - void runWebKit1Test(); - void runWebKit2Test(); - - void loadURL(WebView *, NSURL *); - void loadURL(WKView *, NSURL *); - - void goBack(WebView *); - void goBack(WKView *); - - void waitForLoadToFinish(); - - NSRect viewFrame; - -private: - virtual NSURL *url() const = 0; - virtual void didLoadURL(WebView *) = 0; - virtual void didLoadURL(WKView *) = 0; - - virtual void initializeView(WebView *) { } - virtual void initializeView(WKView *) { } - - virtual void teardownView(WebView *) { } - virtual void teardownView(WKView *) { } - - bool didFinishLoad; -}; - -} // namespace TestWebKitAPI - -#endif // WebKitAgnosticTest_h diff --git a/Tools/TestWebKitAPI/mac/WebKitAgnosticTest.mm b/Tools/TestWebKitAPI/mac/WebKitAgnosticTest.mm deleted file mode 100644 index 03552b3a8..000000000 --- a/Tools/TestWebKitAPI/mac/WebKitAgnosticTest.mm +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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 "WebKitAgnosticTest.h" - -#include <WebKit2/WKURLCF.h> -#include <WebKit2/WKViewPrivate.h> -#include <wtf/RetainPtr.h> - -@interface FrameLoadDelegate : NSObject { - bool* _didFinishLoad; -} - -- (id)initWithDidFinishLoadBoolean:(bool*)didFinishLoad; - -@end - -@implementation FrameLoadDelegate - -- (id)initWithDidFinishLoadBoolean:(bool*)didFinishLoad -{ - self = [super init]; - if (!self) - return nil; - - _didFinishLoad = didFinishLoad; - return self; -} - -- (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame *)webFrame -{ - *_didFinishLoad = true; -} - -@end - -namespace TestWebKitAPI { - -static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef, const void* context) -{ - *static_cast<bool*>(const_cast<void*>(context)) = true; -} - -static void setPageLoaderClient(WKPageRef page, bool* didFinishLoad) -{ - WKPageLoaderClient loaderClient; - memset(&loaderClient, 0, sizeof(loaderClient)); - loaderClient.version = 0; - loaderClient.clientInfo = didFinishLoad; - loaderClient.didFinishLoadForFrame = didFinishLoadForFrame; - - WKPageSetPageLoaderClient(page, &loaderClient); -} - -WebKitAgnosticTest::WebKitAgnosticTest() - : viewFrame(NSMakeRect(0, 0, 800, 600)) - , didFinishLoad(false) -{ -} - -void WebKitAgnosticTest::runWebKit1Test() -{ - RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:viewFrame]); - RetainPtr<FrameLoadDelegate> delegate = adoptNS([[FrameLoadDelegate alloc] initWithDidFinishLoadBoolean:&didFinishLoad]); - [webView.get() setFrameLoadDelegate:delegate.get()]; - initializeView(webView.get()); - - loadURL(webView.get(), url()); - waitForLoadToFinish(); - didLoadURL(webView.get()); - teardownView(webView.get()); -} - -void WebKitAgnosticTest::runWebKit2Test() -{ - WKRetainPtr<WKContextRef> context = adoptWK(WKContextCreate()); - WKRetainPtr<WKPageGroupRef> pageGroup = adoptWK(WKPageGroupCreateWithIdentifier(Util::toWK("WebKitAgnosticTest").get())); - RetainPtr<WKView> view = adoptNS([[WKView alloc] initWithFrame:viewFrame contextRef:context.get() pageGroupRef:pageGroup.get()]); - setPageLoaderClient([view.get() pageRef], &didFinishLoad); - initializeView(view.get()); - - loadURL(view.get(), url()); - waitForLoadToFinish(); - didLoadURL(view.get()); - teardownView(view.get()); -} - -void WebKitAgnosticTest::loadURL(WebView *webView, NSURL *url) -{ - EXPECT_FALSE(didFinishLoad); - [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:url]]; -} - -void WebKitAgnosticTest::loadURL(WKView *view, NSURL *url) -{ - EXPECT_FALSE(didFinishLoad); - WKPageLoadURL([view pageRef], adoptWK(WKURLCreateWithCFURL((CFURLRef)url)).get()); -} - -void WebKitAgnosticTest::goBack(WebView *webView) -{ - EXPECT_FALSE(didFinishLoad); - [webView goBack]; -} - -void WebKitAgnosticTest::goBack(WKView *view) -{ - EXPECT_FALSE(didFinishLoad); - WKPageGoBack([view pageRef]); -} - -void WebKitAgnosticTest::waitForLoadToFinish() -{ - Util::run(&didFinishLoad); - didFinishLoad = false; -} - -} // namespace TestWebKitAPI diff --git a/Tools/TestWebKitAPI/mac/mainMac.mm b/Tools/TestWebKitAPI/mac/mainMac.mm deleted file mode 100644 index 498eb480e..000000000 --- a/Tools/TestWebKitAPI/mac/mainMac.mm +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2010 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 "TestsController.h" - -int main(int argc, char** argv) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - [NSApplication sharedApplication]; - - bool passed = TestWebKitAPI::TestsController::shared().run(argc, argv); - - [pool drain]; - - return passed ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/Tools/TestWebKitAPI/qt/PlatformUtilitiesQt.cpp b/Tools/TestWebKitAPI/qt/PlatformUtilitiesQt.cpp index b210a4a1d..6b67622b7 100644 --- a/Tools/TestWebKitAPI/qt/PlatformUtilitiesQt.cpp +++ b/Tools/TestWebKitAPI/qt/PlatformUtilitiesQt.cpp @@ -21,9 +21,9 @@ #include "config.h" #include "PlatformUtilities.h" -#include <WebKit2/WKStringQt.h> -#include <WebKit2/WKNativeEvent.h> -#include <WebKit2/WKURLQt.h> +#include <WebKit/WKNativeEvent.h> +#include <WebKit/WKStringQt.h> +#include <WebKit/WKURLQt.h> #include <QCoreApplication> #include <QDir> diff --git a/Tools/TestWebKitAPI/qt/PlatformWebViewQt.cpp b/Tools/TestWebKitAPI/qt/PlatformWebViewQt.cpp index 17c786e8e..553462285 100644 --- a/Tools/TestWebKitAPI/qt/PlatformWebViewQt.cpp +++ b/Tools/TestWebKitAPI/qt/PlatformWebViewQt.cpp @@ -31,7 +31,7 @@ #include "qquickwebpage_p.h" #include "qquickwebview_p.h" -#include <WebKit2/WKRetainPtr.h> +#include <WebKit/WKRetainPtr.h> #include <QCoreApplication> #include <QEventLoop> diff --git a/Tools/TestWebKitAPI/qt/main.cpp b/Tools/TestWebKitAPI/qt/main.cpp index e33da3036..7b719ed0a 100644 --- a/Tools/TestWebKitAPI/qt/main.cpp +++ b/Tools/TestWebKitAPI/qt/main.cpp @@ -21,7 +21,9 @@ #include "config.h" #include "TestsController.h" +#if HAVE(WEBKIT2) #include "qquickwebview_p.h" +#endif #include <QGuiApplication> void addQtWebProcessToPath() @@ -53,7 +55,9 @@ int main(int argc, char** argv) useDesktopBehavior = false; } +#if HAVE(WEBKIT2) QQuickWebViewExperimental::setFlickableViewportEnabled(!useDesktopBehavior); +#endif // Has to be done before QApplication is constructed in case // QApplication itself produces debug output. @@ -66,5 +70,5 @@ int main(int argc, char** argv) QGuiApplication app(argc, argv); addQtWebProcessToPath(); - return TestWebKitAPI::TestsController::shared().run(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE; + return TestWebKitAPI::TestsController::singleton().run(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/Tools/TestWebKitAPI/win/HostWindow.cpp b/Tools/TestWebKitAPI/win/HostWindow.cpp deleted file mode 100644 index 74c947d9e..000000000 --- a/Tools/TestWebKitAPI/win/HostWindow.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2010 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 "HostWindow.h" - -namespace TestWebKitAPI { - -static LPCWSTR hostWindowClassName = L"HostWindow"; - -HostWindow::HostWindow() - : m_window(0) -{ -} - -bool HostWindow::initialize() -{ - registerWindowClass(); - m_window = ::CreateWindowExW(0, hostWindowClassName, L"TestWebKitAPI", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, ::GetModuleHandle(0), 0); - return m_window; -} - -HostWindow::~HostWindow() -{ - if (!::IsWindow(m_window)) - return; - ::DestroyWindow(m_window); -} - -RECT HostWindow::clientRect() const -{ - RECT rect = {0}; - if (!::GetClientRect(m_window, &rect)) { - RECT emptyRect = {0}; - return emptyRect; - } - return rect; -} - -void HostWindow::registerWindowClass() -{ - static bool initialized; - if (initialized) - return; - initialized = true; - - WNDCLASSEXW wndClass = {0}; - wndClass.cbSize = sizeof(wndClass); - wndClass.style = CS_HREDRAW | CS_VREDRAW; - wndClass.lpfnWndProc = wndProc; - wndClass.hCursor = LoadCursor(0, IDC_ARROW); - wndClass.hInstance = GetModuleHandle(0); - wndClass.lpszClassName = hostWindowClassName; - - ::RegisterClassExW(&wndClass); -} - -LRESULT HostWindow::wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - return ::DefWindowProcW(hWnd, uMsg, wParam, lParam); -} - -} // namespace WebKitAPITest diff --git a/Tools/TestWebKitAPI/win/HostWindow.h b/Tools/TestWebKitAPI/win/HostWindow.h deleted file mode 100644 index ddb53f10f..000000000 --- a/Tools/TestWebKitAPI/win/HostWindow.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#ifndef HostWindow_h -#define HostWindow_h - -#include <windows.h> -#include <wtf/Noncopyable.h> - -namespace TestWebKitAPI { - -class HostWindow { - WTF_MAKE_NONCOPYABLE(HostWindow); -public: - HostWindow(); - ~HostWindow(); - bool initialize(); - - RECT clientRect() const; - HWND window() const { return m_window; } - -private: - static void registerWindowClass(); - static LRESULT CALLBACK wndProc(HWND, UINT uMsg, WPARAM, LPARAM); - - HWND m_window; -}; - -} // namespace WebKitAPITest - -#endif // HostWindow_h diff --git a/Tools/TestWebKitAPI/win/main.cpp b/Tools/TestWebKitAPI/win/main.cpp deleted file mode 100644 index 265471bd0..000000000 --- a/Tools/TestWebKitAPI/win/main.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2010, 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 "TestsController.h" -#include <windows.h> - -#if defined _M_IX86 -#define PROCESSORARCHITECTURE "x86" -#elif defined _M_IA64 -#define PROCESSORARCHITECTURE "ia64" -#elif defined _M_X64 -#define PROCESSORARCHITECTURE "amd64" -#else -#define PROCESSORARCHITECTURE "*" -#endif - -#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='" PROCESSORARCHITECTURE "' publicKeyToken='6595b64144ccf1df' language='*'\"") -#if defined(_MSC_VER) && (_MSC_VER >= 1600) -#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.6195' processorArchitecture='" PROCESSORARCHITECTURE "' publicKeyToken='1fc8b3b9a1e18e3b' language='*'\"") -#endif - -int main(int argc, char** argv) -{ - // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for - // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the - // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>. - ::SetErrorMode(0); - - // Initialize COM, needed for WebKit1 tests. - // FIXME: Remove this line once <http://webkit.org/b/32867> is fixed. - ::OleInitialize(0); - - bool passed = TestWebKitAPI::TestsController::shared().run(argc, argv); - - return passed ? EXIT_SUCCESS : EXIT_FAILURE; -} |