summaryrefslogtreecommitdiffstats
path: root/WebKitTools
diff options
context:
space:
mode:
Diffstat (limited to 'WebKitTools')
-rw-r--r--WebKitTools/ChangeLog827
-rw-r--r--WebKitTools/DrawTest/AppDelegate.h37
-rw-r--r--WebKitTools/DrawTest/AppDelegate.m52
-rw-r--r--WebKitTools/DrawTest/DrawTest.xcodeproj/project.pbxproj387
-rw-r--r--WebKitTools/DrawTest/DrawTestDocument.h45
-rw-r--r--WebKitTools/DrawTest/DrawTestDocument.m151
-rw-r--r--WebKitTools/DrawTest/DrawTestInspectorController.h37
-rw-r--r--WebKitTools/DrawTest/DrawTestInspectorController.m48
-rw-r--r--WebKitTools/DrawTest/DrawTestToolbarController.h37
-rw-r--r--WebKitTools/DrawTest/DrawTestToolbarController.m354
-rw-r--r--WebKitTools/DrawTest/DrawTestView.h38
-rw-r--r--WebKitTools/DrawTest/DrawTestView.m43
-rw-r--r--WebKitTools/DrawTest/DrawTest_Prefix.pch37
-rw-r--r--WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/classes.nib34
-rw-r--r--WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/info.nib22
-rw-r--r--WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/keyedobjects.nibbin6746 -> 0 bytes
-rw-r--r--WebKitTools/DrawTest/English.lproj/InfoPlist.stringsbin262 -> 0 bytes
-rw-r--r--WebKitTools/DrawTest/English.lproj/Inspector.nib/classes.nib12
-rw-r--r--WebKitTools/DrawTest/English.lproj/Inspector.nib/info.nib16
-rw-r--r--WebKitTools/DrawTest/English.lproj/Inspector.nib/keyedobjects.nibbin9256 -> 0 bytes
-rw-r--r--WebKitTools/DrawTest/English.lproj/MainMenu.nib/classes.nib44
-rw-r--r--WebKitTools/DrawTest/English.lproj/MainMenu.nib/info.nib21
-rw-r--r--WebKitTools/DrawTest/English.lproj/MainMenu.nib/keyedobjects.nibbin17633 -> 0 bytes
-rw-r--r--WebKitTools/DrawTest/English.lproj/TestViewer.nib/classes.nib36
-rw-r--r--WebKitTools/DrawTest/English.lproj/TestViewer.nib/info.nib17
-rw-r--r--WebKitTools/DrawTest/English.lproj/TestViewer.nib/keyedobjects.nibbin11724 -> 0 bytes
-rw-r--r--WebKitTools/DrawTest/Info.plist49
-rw-r--r--WebKitTools/DrawTest/SVGTest.h48
-rw-r--r--WebKitTools/DrawTest/SVGTest.m113
-rw-r--r--WebKitTools/DrawTest/ScalingImageView.h33
-rw-r--r--WebKitTools/DrawTest/ScalingImageView.m57
-rw-r--r--WebKitTools/DrawTest/TestController.h72
-rw-r--r--WebKitTools/DrawTest/TestController.m270
-rw-r--r--WebKitTools/DrawTest/TestViewerSplitView.h31
-rw-r--r--WebKitTools/DrawTest/TestViewerSplitView.m77
-rw-r--r--WebKitTools/DrawTest/main.m29
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.cpp55
-rw-r--r--WebKitTools/DumpRenderTree/LayoutTestController.h2
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp20
-rw-r--r--WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp3
-rw-r--r--WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp16
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm2
-rw-r--r--WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm10
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp28
-rw-r--r--WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h4
-rw-r--r--WebKitTools/DumpRenderTree/qt/main.cpp10
-rw-r--r--WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp1
-rw-r--r--WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp23
-rw-r--r--WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp34
-rw-r--r--WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp11
-rw-r--r--WebKitTools/QtLauncher/QtLauncher.pro2
-rw-r--r--WebKitTools/QtLauncher/main.cpp210
-rw-r--r--WebKitTools/QtLauncher/mainwindow.cpp8
-rw-r--r--WebKitTools/QtLauncher/utils.cpp50
-rw-r--r--WebKitTools/QtLauncher/utils.h9
-rw-r--r--WebKitTools/QtLauncher/webview.cpp62
-rw-r--r--WebKitTools/QtLauncher/webview.h43
-rwxr-xr-xWebKitTools/Scripts/build-webkit11
-rwxr-xr-xWebKitTools/Scripts/check-for-global-initializers2
-rwxr-xr-xWebKitTools/Scripts/check-for-weak-vtables-and-externals (renamed from WebKitTools/Scripts/check-for-weak-vtables)35
-rwxr-xr-xWebKitTools/Scripts/rebaseline-chromium-webkit-tests2
-rwxr-xr-xWebKitTools/Scripts/run-chromium-webkit-tests3
-rwxr-xr-xWebKitTools/Scripts/run-drawtest47
-rwxr-xr-xWebKitTools/Scripts/run-iexploder-tests15
-rwxr-xr-xWebKitTools/Scripts/run-webkit-tests42
-rwxr-xr-xWebKitTools/Scripts/run-webkit-websocketserver1
-rwxr-xr-xWebKitTools/Scripts/test-webkitpy2
-rwxr-xr-xWebKitTools/Scripts/webkit-build-directory (renamed from WebKitTools/Scripts/build-drawtest)47
-rw-r--r--WebKitTools/Scripts/webkitdirs.pm248
-rw-r--r--WebKitTools/Scripts/webkitperl/features.pm104
-rw-r--r--WebKitTools/Scripts/webkitperl/httpd.pm169
-rw-r--r--WebKitTools/Scripts/webkitpy/bugzilla.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/upload.py45
-rw-r--r--WebKitTools/Scripts/webkitpy/commands/upload_unittest.py5
-rw-r--r--WebKitTools/Scripts/webkitpy/committers.py1
-rw-r--r--WebKitTools/Scripts/webkitpy/credentials.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/grammar.py8
-rw-r--r--WebKitTools/Scripts/webkitpy/grammar_unittest.py38
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/driver_test.py77
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py8
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py56
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py112
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py7
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py219
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py49
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py37
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/base.py645
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py260
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py327
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py293
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py293
-rwxr-xr-xWebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py97
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py11
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py439
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/path_utils.py395
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/test.py144
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py103
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py4
-rwxr-xr-xWebKitTools/Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py213
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py9
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py63
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py106
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py19
-rw-r--r--WebKitTools/Scripts/webkitpy/mock_bugzillatool.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/style/checker.py167
-rwxr-xr-xWebKitTools/Scripts/webkitpy/style/checker_unittest.py108
-rw-r--r--WebKitTools/Scripts/webkitpy/style/error_handlers.py6
-rw-r--r--WebKitTools/Scripts/webkitpy/style/error_handlers_unittest.py23
-rw-r--r--WebKitTools/Scripts/webkitpy/style/filter.py203
-rw-r--r--WebKitTools/Scripts/webkitpy/style/filter_unittest.py196
-rw-r--r--WebKitTools/Scripts/webkitpy/style/processors/cpp.py40
-rw-r--r--WebKitTools/Scripts/webkitpy/style/processors/cpp_unittest.py17
-rw-r--r--WebKitTools/Scripts/webkitpy/user.py9
-rw-r--r--WebKitTools/Scripts/webkitpy/user_unittest.py53
-rw-r--r--WebKitTools/pywebsocket/mod_pywebsocket/standalone.py30
-rw-r--r--WebKitTools/pywebsocket/setup.py2
-rw-r--r--WebKitTools/wx/build/settings.py6
117 files changed, 4819 insertions, 4538 deletions
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index ed2e4bf..ab4b32d 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,830 @@
+2010-02-12 Diego Gonzalez <diego.gonzalez@openbossa.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Qt DRT now dump the frame loader callbacks when LayoutTestController()
+ method is called.
+
+ LayoutTests:
+ http/tests/security/mixedContent/data-url-script-in-iframe.html
+ http/tests/security/mixedContent/empty-url-plugin-in-frame.html
+ http/tests/security/mixedContent/insecure-css-in-iframe.html
+ http/tests/security/mixedContent/insecure-iframe-in-iframe.html
+ http/tests/security/mixedContent/insecure-image-in-iframe.html
+ http/tests/security/mixedContent/insecure-plugin-in-iframe.html
+ http/tests/security/mixedContent/insecure-script-in-iframe.html
+ http/tests/security/mixedContent/redirect-http-to-https-script-in-iframe.html
+ http/tests/security/mixedContent/redirect-https-to-http-script-in-iframe.html
+
+ [Qt] Make possible Qt DRT dump frame load callbacks
+ https://bugs.webkit.org/show_bug.cgi?id=34702
+
+ * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+ (LayoutTestController::reset):
+ (LayoutTestController::dumpFrameLoadCallbacks):
+ * DumpRenderTree/qt/LayoutTestControllerQt.h:
+
+2010-02-12 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Antti Koivisto.
+
+ Make QtLauncher somewhat useable on S60.
+
+ Show the window fullscreen to make scrollbars appear, resize
+ the toolbar buttons to 16x16 to give more screen space to
+ web content and moved the location lineedit into a separate
+ line.
+
+ * QtLauncher/main.cpp:
+ (LauncherWindow::LauncherWindow):
+ * QtLauncher/mainwindow.cpp:
+ (MainWindow::buildUI):
+
+2010-02-12 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Support frameset flattening
+ https://bugs.webkit.org/show_bug.cgi?id=32717
+
+ Add FrameSet Flattening support to Mac DRT.
+
+ * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+ (LayoutTestController::setFrameSetFlatteningEnabled):
+ * DumpRenderTree/win/DumpRenderTree.cpp:
+ (resetDefaultsToConsistentValues):
+ * DumpRenderTree/win/LayoutTestControllerWin.cpp:
+ (LayoutTestController::setXSSAuditorEnabled):
+ * DumpRenderTree/wx/LayoutTestControllerWx.cpp:
+ (LayoutTestController::setFrameSetFlatteningEnabled):
+ * DumpRenderTree/LayoutTestController.cpp:
+ (setFrameSetFlatteningEnabledCallback):
+ (LayoutTestController::staticFunctions):
+ * DumpRenderTree/LayoutTestController.h:
+ * DumpRenderTree/mac/DumpRenderTree.mm:
+ (resetDefaultsToConsistentValues):
+ * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+ (LayoutTestController::setFrameSetFlatteningEnabled):
+
+2010-02-12 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Fix typos in driver_test.py
+
+ https://bugs.webkit.org/show_bug.cgi?id=34810
+
+ * Scripts/webkitpy/layout_tests/driver_test.py:
+
+2010-02-12 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Make it possible to toggle the use of QGraphicsView in QtLauncher at run-time
+ https://bugs.webkit.org/show_bug.cgi?id=34844
+
+ * QtLauncher/main.cpp:
+ (LauncherWindow::LauncherWindow):
+ (LauncherWindow::initializeView):
+ (LauncherWindow::setupUI):
+ * QtLauncher/webview.cpp:
+ (WebViewGraphicsBased::WebViewGraphicsBased):
+
+2010-02-11 Fumitoshi Ukai <ukai@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ WebSocket ignores HttpOnly cookies, but should use in Handshake.
+ https://bugs.webkit.org/show_bug.cgi?id=34289
+
+ Update pywebsocket to 0.4.8, which supports cgi directories.
+ run-webkit-tests and run-webkit-websocketserver will run
+ pywebsocket, specifying /websocket/test/cookies as cgi directory.
+
+ * Scripts/run-webkit-tests:
+ * Scripts/run-webkit-websocketserver:
+ * pywebsocket/mod_pywebsocket/standalone.py:
+ * pywebsocket/setup.py:
+
+2010-02-11 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Dan Bernstein.
+
+ [Mac] Duplicated setXSSAuditorEnabled preference at Mac DRT
+ https://bugs.webkit.org/show_bug.cgi?id=34798
+
+ Remove duplicated setXSSAuditorEnabled preference at Mac DRT
+
+ * DumpRenderTree/mac/DumpRenderTree.mm:
+ (resetDefaultsToConsistentValues):
+
+2010-02-11 Eric Seidel <eric@webkit.org>
+
+ No review, build fix only.
+
+ webkitdirs.pm has a crazy amount of duplicated feature detection code
+ https://bugs.webkit.org/show_bug.cgi?id=34869
+
+ * Scripts/build-webkit: Fix typo which broke bots.
+
+2010-02-11 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ webkitdirs.pm has a crazy amount of duplicated feature detection code
+ https://bugs.webkit.org/show_bug.cgi?id=34869
+
+ * Scripts/build-webkit: Use the new hotness.
+ * Scripts/run-webkit-tests: ditto
+ * Scripts/webkitdirs.pm: Remove a bunch of bad duplicate code.
+ * Scripts/webkitperl/features.pm: Added.
+ - Simplified the 10 methods in webkitdirs.pm into 2 exported methods in this new file.
+
+2010-02-11 Daniel Bates <dbates@rim.com>
+
+ Reviewed by Adam Barth.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34830
+
+ Makes method User.prompt static and adds the parameter repeat
+ to prompt the user up to repeat times.
+
+ * Scripts/test-webkitpy:
+ * Scripts/webkitpy/bugzilla.py: Substituted method User.prompt for method raw_input.
+ * Scripts/webkitpy/commands/upload.py: Ditto
+ * Scripts/webkitpy/credentials.py: Ditto
+ * Scripts/mock_bugzillatool.py: Updated prototype of MockUser.prompt to match User.prompt.
+ * Scripts/webkitpy/user.py: Made method prompt static and added parameter repeat.
+ * Scripts/webkitpy/user_unittest.py: Added.
+
+2010-02-10 Yuzo Fujishima <yuzo@google.com>
+
+ Reviewed by Darin Adler.
+
+ Allow underscored identifiers in CSSParser.cpp
+
+ Flex (http://flex.sourceforge.net/) uses identifiers named as yy_*.
+ WebCore/css/CSSParser.cpp needs to handle some such identifiers.
+ We should relax the style rule for the file to allow underscored identifiers.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34787
+
+ * Scripts/webkitpy/style/checker.py:
+
+2010-02-11 Eric Seidel <eric@webkit.org>
+
+ Rubber-stamped by Adam Barth.
+
+ Remove DrawTest, the application I used when bringing up SVG support on the Mac.
+ The code hasn't been touched (or used) in years. No sense in keeping it in trunk.
+
+ * Scripts/build-drawtest: Removed.
+ * Scripts/run-drawtest: Removed.
+ * DrawTest: Removed.
+
+2010-02-11 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Need a command to clear r+ on obsolete patches in the pending-commit queue.
+ https://bugs.webkit.org/show_bug.cgi?id=34863
+
+ Unfortunately our http://webkit.org/pending-commit bugzilla query is not
+ smart enough to ignore obsolete patches, so bugs show up there which are
+ still open, but do not have patches ready for landing on them.
+ This new command "clean-pending-commit" will remove r+ from obsolete patches
+ in the pending-commit list.
+
+ * Scripts/test-webkitpy: Add grammar_unittest
+ * Scripts/webkitpy/commands/upload.py: Add clean-pending-commit and make assign-to-committer ignore cq+'d patches.
+ * Scripts/webkitpy/grammar.py: Add join_with_separators
+ * Scripts/webkitpy/grammar_unittest.py: Added.
+
+2010-02-11 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ run-chromium-webkit-tests fails random pixel tests on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=34862
+
+ This is due to the fact that the Mac port has an
+ invalid path to the image diff tool. Currently it points
+ to image_diff even though ImageDiff would be correct. We
+ can't change it to the right path yet without causing the
+ script to hang. ImageDiff expects to be long-running and
+ be passed image data over stdin. image_diff (chromium's fork)
+ expects to be passed command line arguments.
+ This fix works around the random failures by disabling pixel
+ tests on mac and logging if the user was trying to run with pixel
+ tests enabled.
+
+ * Scripts/webkitpy/layout_tests/port/mac.py:
+
+2010-02-11 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Adam Roben.
+ Try to fix build breakage from r54665.
+
+ * Scripts/check-for-global-initializers:
+
+2010-02-11 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Make it possible to toggle accelerated compositing from the menu
+ at run-time.
+
+ * QtLauncher/main.cpp:
+ (LauncherWindow::toggleAcceleratedCompositing):
+ (LauncherWindow::setupUI):
+
+2010-02-08 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Restore ENABLE_RUBY flag so vendors can ship with Ruby disabled if they choose.
+ https://bugs.webkit.org/show_bug.cgi?id=34698
+
+ * Scripts/build-webkit:
+
+2010-02-10 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Fix various minor bugs keeping run-chromium-webkit-tests from actually
+ working on the linux and win ports of Chromium.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34739
+
+ * Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py:
+ * Scripts/webkitpy/layout_tests/port/__init__.py:
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ * Scripts/webkitpy/layout_tests/port/chromium.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_linux.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_win.py:
+ * Scripts/webkitpy/layout_tests/port/http_server.py:
+ * Scripts/webkitpy/layout_tests/port/websocket_server.py:
+
+2010-02-10 Eric Seidel <eric@webkit.org>
+
+ Reviewed by David Levin.
+
+ run-chromium-webkit-tests --platform=mac-leopard crashes when using a custom build directory
+ https://bugs.webkit.org/show_bug.cgi?id=34817
+
+ This doesn't fix the root cause of us not
+ correctly failing when support binaries are missing.
+ This only causes the DumpRenderTree binary not to be
+ missing in the custom build directory case.
+ Later patches will make us correctly fail fast when
+ support binaries (like DumpRenderTree or ImageDiff) are missing.
+
+ * Scripts/webkit-build-directory: Added.
+ - Need a way to re-use the perl logic for finding build directories in non-perl scripts.
+ * Scripts/webkitpy/layout_tests/port/base.py: Add a FIXME.
+ * Scripts/webkitpy/layout_tests/port/mac.py:
+ - Call webkit-build-directory to find the build directory instead of assuming "WebKitBuild"
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py: Add FIXMEs.
+
+2010-02-10 Kevin Watters <kevinwatters@gmail.com>
+
+ Reviewed by Kevin Ollivier.
+
+ [wx] Add Windows complex text support.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34759
+
+ * wx/build/settings.py:
+
+2010-02-10 Kevin Ollivier <kevino@theolliviers.com>
+
+ [wx] Build fix. Add stub for new LayoutTestController method.
+
+ * DumpRenderTree/wx/LayoutTestControllerWx.cpp:
+ (LayoutTestController::numberOfPages):
+
+2010-02-10 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviewed. Roll out r54626, because it broke GTK and Win build.
+ https://bugs.webkit.org/show_bug.cgi?id=32717
+
+ * DumpRenderTree/LayoutTestController.cpp:
+ (LayoutTestController::staticFunctions):
+ * DumpRenderTree/LayoutTestController.h:
+ * DumpRenderTree/mac/DumpRenderTree.mm:
+ (resetDefaultsToConsistentValues):
+ * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+
+2010-02-10 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Support frameset flattening
+ https://bugs.webkit.org/show_bug.cgi?id=32717
+
+ Add FrameSet Flattening support to Mac DRT.
+
+ * DumpRenderTree/LayoutTestController.cpp:
+ (setFrameSetFlatteningEnabledCallback):
+ (LayoutTestController::staticFunctions):
+ * DumpRenderTree/LayoutTestController.h:
+ * DumpRenderTree/mac/DumpRenderTree.mm:
+ (resetDefaultsToConsistentValues):
+ * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+ (LayoutTestController::setFrameSetFlatteningEnabled):
+
+2010-02-08 Jon Honeycutt <jhoneycutt@apple.com>
+
+ <rdar://problem/7436875> Crash in Flash when visiting
+ http://www.cctv.com/default.shtml (WER ID 819298200) [watson 2502260]
+
+ Reviewed by Darin Adler.
+
+ * DumpRenderTree/win/TestNetscapePlugin/main.cpp:
+ (executeScript):
+ Moved to an earlier point in the file.
+ (NPP_New):
+ If the plug-in has an onDestroy attribute, store its value.
+ (NPP_Destroy):
+ If the plug-in has code to run on destruction, run it and free it.
+
+2010-02-10 Diego Gonzalez <diego.gonzalez@openbossa.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Implement pageNumberForElementById() method in Qt DRT LayoutTestController,
+ to make Qt DRT able to get page number.
+
+ LayoutTests:
+ printing/page-break-always.html
+ printing/pageNumerForElementById.html
+ printing/css2.1/page-break-before-000.html
+ printing/css2.1/page-break-after-000.html
+ printing/css2.1/page-break-after-004.html
+ printing/css2.1/page-break-before-001.html
+ printing/css2.1/page-break-after-001.html
+ printing/css2.1/page-break-after-002.html
+ printing/css2.1/page-break-before-002.html
+ printing/css2.1/page-break-inside-000.html
+
+ [Qt] Make possible Qt DRT get a page number for element by ID
+ https://bugs.webkit.org/show_bug.cgi?id=34777
+
+ * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+ (LayoutTestController::pageNumberForElementById):
+ * DumpRenderTree/qt/LayoutTestControllerQt.h:
+
+2010-02-10 Andras Becsi <abecsi@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ Make run-iexploder-tests work on Linux.
+ https://bugs.webkit.org/show_bug.cgi?id=34748
+
+ Extract the platform dependant Apache configuration checking code in httpd.pm to a separate function
+ called getHTTPDConfigPathForTestDirectory and use run-launcher instead of run-safari if run on Linux.
+
+ * Scripts/run-iexploder-tests:
+ * Scripts/webkitperl/httpd.pm:
+
+2010-02-09 Csaba Osztrogonác <ossy@webkit.org>
+
+ [Qt] Unreviewed. Roll-out r54543, because layout tests crash in debug mode.
+ https://bugs.webkit.org/show_bug.cgi?id=34713
+
+ * DumpRenderTree/qt/DumpRenderTreeQt.cpp:
+ (WebCore::WebPage::WebPage):
+ * DumpRenderTree/qt/main.cpp:
+ (main):
+
+2010-02-09 Alejandro G. Castro <alex@igalia.com>
+
+ Unreviewed; added myself to committers
+
+ * Scripts/webkitpy/committers.py:
+
+2010-02-09 Yael Aharon <yael.aharon@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Webkit in Qt does not have window.showModalDialog
+ https://bugs.webkit.org/show_bug.cgi?id=25585
+
+ Set the modality flag when createWindow is called with window type WebWindowDialog.
+
+ * QtLauncher/main.cpp:
+ (WebPage::createWindow):
+
+2010-02-09 Andras Becsi <abecsi@webkit.org>
+
+ Unreviewed trivial warning fix.
+
+ * Scripts/build-webkit:
+
+2010-02-09 Gabor Rapcsanyi <rgabor@inf.u-szeged.hu>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Add possibility of passing parameters to build-webkit by environment variable,
+ because the buildbot slaves can't control the arguments.
+
+ * Scripts/build-webkit:
+
+2010-02-09 Chang Shu <Chang.Shu@nokia.com>
+
+ Reviewed by Laszlo Gombos.
+
+ [Qt] Enable appcache feature.
+ https://bugs.webkit.org/show_bug.cgi?id=34713
+
+
+ * DumpRenderTree/qt/DumpRenderTreeQt.cpp:
+ (WebCore::WebPage::WebPage):
+ * DumpRenderTree/qt/main.cpp:
+ (main):
+
+2010-02-09 Shinichiro Hamaji <hamaji@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Provide a way to get total number of pages to be printed
+ https://bugs.webkit.org/show_bug.cgi?id=34699
+
+ * DumpRenderTree/LayoutTestController.cpp:
+ (parsePageParameters):
+ (pageNumberForElementByIdCallback):
+ (numberOfPagesCallback):
+ (LayoutTestController::staticFunctions):
+ * DumpRenderTree/LayoutTestController.h:
+ * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+ (LayoutTestController::numberOfPages):
+ * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+ (LayoutTestController::numberOfPages):
+ * DumpRenderTree/win/LayoutTestControllerWin.cpp:
+ (LayoutTestController::numberOfPages):
+
+2010-02-08 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34727
+ Assertion crashes and freezes when plug-in property access results in an exception
+
+ * DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp:
+ (pluginGetProperty): Raise an exception when accessing a particular property.
+ (pluginSetProperty): Ditto.
+ (pluginInvoke): Added methods to get and set host object properties.
+
+2010-02-08 Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] Backport No'am Rosenthal's frame rate measurement
+
+ * QtLauncher/main.cpp:
+ (LauncherWindow::LauncherWindow):
+ (LauncherApplication::handleUserOptions):
+ * QtLauncher/webview.cpp:
+ (WebViewGraphicsBased::WebViewGraphicsBased):
+ (WebViewGraphicsBased::enableFrameRateMeasurement):
+ (WebViewGraphicsBased::updateFrameRate):
+ (WebViewGraphicsBased::paintEvent):
+ * QtLauncher/webview.h:
+
+2010-02-08 Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Reviewed by Tor Arne Vestbø.
+
+ [Qt] Make overridePreference complain when it does not
+ support the preference given.
+
+ * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+ (LayoutTestController::overridePreference):
+
+2010-02-08 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Set stdout/stderr to binary mode for DRT on Windows
+
+ This makes sure we don't end up with lots of CRLFs in the
+ DRT output, which breaks tons of results. Matches what
+ the Windows DRT does.
+
+ * DumpRenderTree/qt/main.cpp:
+
+2010-02-08 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Build fix for Qt on Windows.
+
+ Don't use noreturn directly since it's a gcc attribute.
+ Instead use the NO_RETURN macro from AlwaysInline.h
+
+ * QtLauncher/QtLauncher.pro:
+ * QtLauncher/utils.h:
+
+2010-02-05 Chris Jerdonek <cjerdonek@webkit.org>
+
+ Reviewed by Shinichiro Hamaji.
+
+ Suppressed check-webkit-style's underscore check in Qt's autotests.
+ Also made the path-specific filter check case-insensitive.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34574
+
+ * Scripts/webkitpy/style/checker.py:
+ - Added a list element to _PATH_RULES_SPECIFIER for
+ directories that should be excluded from the
+ "readability/naming" category (the category that relates to
+ underscores in identifiers, for example).
+
+ * Scripts/webkitpy/style/checker_unittest.py:
+ - Added an "end-to-end" test for "WebKit/qt/tests/".
+
+ * Scripts/webkitpy/style/filter.py:
+ - Altered FilterConfiguration's should_check() method to
+ check for path substring matches case-insensitively.
+
+ * Scripts/webkitpy/style/filter_unittest.py:
+ - Added a test to check case-insensitive path substring matching.
+
+ * Scripts/webkitpy/style/processors/cpp.py:
+ - Removed the hard-coded "WebKit/gtk/webkit/" path reference
+ since this is now taken care of by the _PATH_RULES_SPECIFIER
+ configuration variable.
+
+ * Scripts/webkitpy/style/processors/cpp_unittest.py:
+ - Removed the unit test for the GTK directory since this
+ is now taken care of by the checker._PATH_RULES_SPECIFIER
+ end-to-end tests.
+
+2010-02-08 Leith Bade <leith@leithalweapon.geek.nz>
+
+ Reviewed by Darin Adler.
+
+ Fixes: https://bugs.webkit.org/show_bug.cgi?id=34637
+ Corrects the newline inserted into WebKitOutputDir, and WebKitLibrariesDir Windows
+ environemnt variables when there is a space in the user's /home path.
+
+ * Scripts/webkitdirs.pm:
+ - Added missing quotes around $sourceDir in argument list of cygpath in determineWindowsSourceDir().
+
+2010-02-05 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34670
+ TestNetscapePlugin should work with Firefox
+
+ * DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp: (NPP_New): Default to Carbon if
+ browser doesn't tell what it supports.
+
+2010-02-05 Shinichiro Hamaji <hamaji@chromium.org>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [Gtk] Implement layoutTestController.pageNumberForElementById
+ https://bugs.webkit.org/show_bug.cgi?id=34572
+
+ * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+ (LayoutTestController::pageNumberForElementById):
+
+2010-02-03 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Add a simple test implementation and the WebKit Mac implementation
+ for the layout_tests/port package. Also add a simple test driver of
+ that interface.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34511
+
+ * Scripts/webkitpy/layout_tests/driver_test.py: Added.
+ * Scripts/webkitpy/layout_tests/port/__init__.py:
+ * Scripts/webkitpy/layout_tests/port/mac.py: Added.
+ * Scripts/webkitpy/layout_tests/port/test.py: Added.
+
+2010-02-03 Dirk Pranke <dpranke@chromium.org>
+
+ Reviewed by Eric Siedel.
+
+ Refactor the port package into an object-oriented style and merge
+ path_utils into it. We add a 'base' and a 'chromium' object to the
+ port package; this will allow us to easily add new ports (like
+ WebKit Mac).
+
+ https://bugs.webkit.org/show_bug.cgi?id=34511
+
+ * Scripts/rebaseline-chromium-webkit-tests:
+ * Scripts/run-chromium-webkit-tests:
+ * Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py:
+ * Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py:
+ * Scripts/webkitpy/layout_tests/layout_package/test_expectations.py:
+ * Scripts/webkitpy/layout_tests/layout_package/test_files.py:
+ * Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py:
+ * Scripts/webkitpy/layout_tests/port/__init__.py:
+ * Scripts/webkitpy/layout_tests/port/apache_http_server.py:
+ * Scripts/webkitpy/layout_tests/port/base.py: Added.
+ * Scripts/webkitpy/layout_tests/port/chromium.py: Added.
+ * Scripts/webkitpy/layout_tests/port/chromium_linux.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_mac.py:
+ * Scripts/webkitpy/layout_tests/port/chromium_win.py:
+ * Scripts/webkitpy/layout_tests/port/http_server.py:
+ * Scripts/webkitpy/layout_tests/port/http_server_base.py:
+ * Scripts/webkitpy/layout_tests/port/path_utils.py: Removed.
+ * Scripts/webkitpy/layout_tests/port/websocket_server.py:
+ * Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py:
+ * Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py:
+ * Scripts/webkitpy/layout_tests/test_types/image_diff.py:
+ * Scripts/webkitpy/layout_tests/test_types/test_type_base.py:
+ * Scripts/webkitpy/layout_tests/test_types/text_diff.py:
+
+2010-01-19 Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Reviewed by Dave Hyatt.
+
+ Implement flattening of framesets
+ https://bugs.webkit.org/show_bug.cgi?id=32717
+
+ Add support for testing frame flattening with the Qt DRT
+
+ * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+ (LayoutTestController::setFrameSetFlatteningEnabled):
+ * DumpRenderTree/qt/LayoutTestControllerQt.h:
+
+2010-02-03 Chris Jerdonek <cjerdonek@webkit.org>
+
+ Reviewed by Shinichiro Hamaji.
+
+ Provided a way in check-webkit-style to specify filter rules
+ on a per file or folder basis, via a configuration variable.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33684
+
+ * Scripts/webkitpy/style/checker.py:
+ - Added _PATH_RULES_SPECIFIER configuration variable.
+ - In ProcessorOptions class--
+ - Changed the CategoryFilter attribute to FilterConfiguration.
+ - Added path parameter to is_reportable().
+ - Renamed ArgumentDefaults filter_rules attribute to
+ base_filter_rules.
+ - Updated ArgumentPrinter class.
+ - Added filter rule validation to ArgumentParser (instead of
+ in CategoryFilter constructor).
+
+ * Scripts/webkitpy/style/checker_unittest.py:
+ - Updated unit tests as necessary.
+ - Added unit tests for PATH_RULES_SPECIFIER.
+
+ * Scripts/webkitpy/style/error_handlers.py:
+ - Updated DefaultStyleErrorHandler to use file path when
+ calling is_reportable().
+
+ * Scripts/webkitpy/style/error_handlers_unittest.py:
+ - Updated unit tests as necessary.
+
+ * Scripts/webkitpy/style/filter.py:
+ - Marked CategoryFilter internal with an underscore.
+ - Removed argument validation from CategoryFilter.
+ - Added FilterConfiguration class.
+
+ * Scripts/webkitpy/style/filter_unittest.py:
+ - Updated CategoryFilterTest class.
+ - Added FilterConfigurationTest unit tests.
+
+ * Scripts/webkitpy/style/processors/cpp.py:
+ - Removed _is_test_filename() code.
+ - Removed hard-coded path checks from check_include_line().
+
+ * Scripts/webkitpy/style/processors/cpp_unittest.py:
+ - Removed three unit tests related to exempted files.
+
+2010-02-05 Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] Apply the command line options as settings to the
+ graphics system.
+
+ * QtLauncher/main.cpp:
+ (LauncherWindow::LauncherWindow):
+ (requiresGraphicsView):
+ (LauncherApplication::handleUserOptions):
+ * QtLauncher/webview.h:
+ (WebViewGraphicsBased::setItemCacheMode):
+
+2010-02-05 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Notify user that run-webkit-tests has to be run under Cygwin
+
+ The script will bail out if run under Windows shell or Msys.
+
+ * Scripts/run-webkit-tests:
+ * Scripts/webkitdirs.pm:
+
+2010-02-05 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Generate convenience headers (QWebView, etc) using qmake
+
+ In Qt this is done using syncqt, but we use a pro-file instead
+ that generates makefile-rules for each of the extra headers.
+
+ These extra headers are installed alongside the normal headers.
+
+ * Scripts/webkitdirs.pm: Run qmake and make on new API-DerivedSources
+
+2010-02-05 Andras Becsi <abecsi@webkit.org>
+
+ Unreviewed typo fix.
+
+ Fix wrong whitespace alignment introduced in r54342.
+
+ * Scripts/run-webkit-tests:
+
+2010-02-04 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Timothy Hatcher.
+
+ Build fix. Remove a symbol corresponding to an inline function from the linker export
+ file to prevent a weak external failure.
+
+ * Scripts/check-for-weak-vtables-and-externals: Renamed from WebKitTools/Scripts/check-for-weak-vtables.
+ Teach the script how to detect weak external symbols so that these errors can be caught immediately
+ in the future.
+
+2010-02-04 Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Rubberstamped by Oliver Hunt.
+
+ [Qt] Make it possible to choose whether the launcher should
+ use the traditional QWidget based QWebView or the newer
+ QGraphics based QGraphicsWebView on a QGraphicsView.
+
+ * QtLauncher/main.cpp:
+ (LauncherWindow::LauncherWindow):
+ (LauncherWindow::eventFilter):
+ (LauncherWindow::loadStarted):
+ (LauncherWindow::print):
+ (LauncherWindow::screenshot):
+ (LauncherWindow::setEditable):
+ (LauncherWindow::setupUI):
+ (main):
+ * QtLauncher/webview.cpp:
+ (WebViewGraphicsBased::WebViewGraphicsBased):
+ (WebViewGraphicsBased::resizeEvent):
+ (GraphicsWebView::mousePressEvent):
+ (GraphicsWebView::contextMenuEvent):
+ * QtLauncher/webview.h:
+ (WebViewTraditional::WebViewTraditional):
+ (GraphicsWebView::GraphicsWebView):
+ (WebViewGraphicsBased::setPage):
+
+2010-02-04 Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Rubberstamped by Oliver Hunt.
+
+ [Qt] QtLauncher cleanup.
+
+ Refactor option handling out in utility functions and make the
+ arguments more Qt compatible.
+
+ * QtLauncher/main.cpp:
+ (requiresGraphicsView):
+ (LauncherApplication::handleUserOptions):
+ * QtLauncher/utils.cpp:
+ (takeOptionValue):
+ (formatKeys):
+ (enumToKeys):
+ (appQuit):
+ * QtLauncher/utils.h:
+
+2010-02-04 Andras Becsi <abecsi@inf.u-szeged.hu>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Implement a locking and scheduling mechanism for http testing sessions to be able
+ to run multiple instances of run-webkit-tests parallel on the same machine.
+ If a test session wants to run http tests and this feature is enabled, the pending
+ sessions create lockfiles with sequential lock numbers. These locks are used to schedule
+ the running test sessions in first come first served order. An exclusive lock ensures
+ that the lock numbers are sequential to avoid deadlocks and starvation.
+ Because the buildbot master specifies the flags used by slaves we need an environment
+ variable too to be able to use the feature per-slave.
+ Exporting WEBKIT_WAIT_FOR_HTTPD=1 before testing or using the --wait-for-httpd
+ flag enables this feature, otherwise this patch has no effect on the testing whatsoever.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33153
+
+ * Scripts/run-webkit-tests:
+ * Scripts/webkitperl/httpd.pm:
+
2010-01-22 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
Reviewed by Simon Hausmann.
diff --git a/WebKitTools/DrawTest/AppDelegate.h b/WebKitTools/DrawTest/AppDelegate.h
deleted file mode 100644
index 7103bb8..0000000
--- a/WebKitTools/DrawTest/AppDelegate.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import <Cocoa/Cocoa.h>
-
-
-@interface AppDelegate : NSObject {
- IBOutlet NSWindow *svgImageRepTestWindow;
-}
-
-- (IBAction)showTestsPanel:(id)sender;
-- (IBAction)showImageRepTestWindow:(id)sender;
-- (IBAction)showInspectorPanel:(id)sender;
-
-@end
diff --git a/WebKitTools/DrawTest/AppDelegate.m b/WebKitTools/DrawTest/AppDelegate.m
deleted file mode 100644
index 0f20b35..0000000
--- a/WebKitTools/DrawTest/AppDelegate.m
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-#import "AppDelegate.h"
-
-#import "TestController.h"
-#import "DrawTestInspectorController.h"
-
-@implementation AppDelegate
-
-- (IBAction)showTestsPanel:(id)sender
-{
- [[TestController sharedController] showTestsPanel:sender];
-}
-
-- (IBAction)showImageRepTestWindow:(id)sender
-{
- [svgImageRepTestWindow makeKeyAndOrderFront:sender];
-}
-
-- (IBAction)showInspectorPanel:(id)sender
-{
- [[DrawTestInspectorController sharedInstance] showInspectorPanel:sender];
-}
-
-- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
-{
- return NO;
-}
-
-@end
diff --git a/WebKitTools/DrawTest/DrawTest.xcodeproj/project.pbxproj b/WebKitTools/DrawTest/DrawTest.xcodeproj/project.pbxproj
deleted file mode 100644
index cb6a265..0000000
--- a/WebKitTools/DrawTest/DrawTest.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,387 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 42;
- objects = {
-
-/* Begin PBXBuildFile section */
- 78662E6D096B4E1600907EA7 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78662E6C096B4E1600907EA7 /* WebKit.framework */; };
- 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; };
- 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
- 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
- 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
- A8C006CF0898634600BA5114 /* SVGTest.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006B00898634600BA5114 /* SVGTest.m */; };
- A8C006D00898634600BA5114 /* ScalingImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006B20898634600BA5114 /* ScalingImageView.m */; };
- A8C006D20898634600BA5114 /* DrawTestView.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006B50898634600BA5114 /* DrawTestView.m */; };
- A8C006D30898634600BA5114 /* DrawTestToolbarController.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006B70898634600BA5114 /* DrawTestToolbarController.m */; };
- A8C006D40898634600BA5114 /* DrawTestInspectorController.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006BB0898634600BA5114 /* DrawTestInspectorController.m */; };
- A8C006D50898634600BA5114 /* DrawTestDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006BD0898634600BA5114 /* DrawTestDocument.m */; };
- A8C006E10898634600BA5114 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006CA0898634600BA5114 /* AppDelegate.m */; };
- A8C006E20898634600BA5114 /* TestViewerSplitView.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006CC0898634600BA5114 /* TestViewerSplitView.m */; };
- A8C006E30898634600BA5114 /* TestController.m in Sources */ = {isa = PBXBuildFile; fileRef = A8C006CE0898634600BA5114 /* TestController.m */; };
- A8C006F3089865E900BA5114 /* DrawTestDocument.nib in Resources */ = {isa = PBXBuildFile; fileRef = A8C006ED089865E900BA5114 /* DrawTestDocument.nib */; };
- A8C006F4089865E900BA5114 /* Inspector.nib in Resources */ = {isa = PBXBuildFile; fileRef = A8C006EF089865E900BA5114 /* Inspector.nib */; };
- A8C006F5089865E900BA5114 /* TestViewer.nib in Resources */ = {isa = PBXBuildFile; fileRef = A8C006F1089865E900BA5114 /* TestViewer.nib */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
- 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
- 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
- 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
- 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
- 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
- 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
- 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
- 32CA4F630368D1EE00C91783 /* DrawTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTest_Prefix.pch; sourceTree = "<group>"; };
- 78662E6C096B4E1600907EA7 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
- 8D1107320486CEB800E47090 /* DrawTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DrawTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
- A8C006AF0898634600BA5114 /* TestController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestController.h; sourceTree = "<group>"; };
- A8C006B00898634600BA5114 /* SVGTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGTest.m; sourceTree = "<group>"; };
- A8C006B10898634600BA5114 /* SVGTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTest.h; sourceTree = "<group>"; };
- A8C006B20898634600BA5114 /* ScalingImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScalingImageView.m; sourceTree = "<group>"; };
- A8C006B30898634600BA5114 /* ScalingImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScalingImageView.h; sourceTree = "<group>"; };
- A8C006B50898634600BA5114 /* DrawTestView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawTestView.m; sourceTree = "<group>"; };
- A8C006B60898634600BA5114 /* DrawTestView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTestView.h; sourceTree = "<group>"; };
- A8C006B70898634600BA5114 /* DrawTestToolbarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawTestToolbarController.m; sourceTree = "<group>"; };
- A8C006B80898634600BA5114 /* DrawTestDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTestDocument.h; sourceTree = "<group>"; };
- A8C006BA0898634600BA5114 /* DrawTestToolbarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTestToolbarController.h; sourceTree = "<group>"; };
- A8C006BB0898634600BA5114 /* DrawTestInspectorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawTestInspectorController.m; sourceTree = "<group>"; };
- A8C006BC0898634600BA5114 /* DrawTestInspectorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawTestInspectorController.h; sourceTree = "<group>"; };
- A8C006BD0898634600BA5114 /* DrawTestDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawTestDocument.m; sourceTree = "<group>"; };
- A8C006CA0898634600BA5114 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
- A8C006CB0898634600BA5114 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
- A8C006CC0898634600BA5114 /* TestViewerSplitView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestViewerSplitView.m; sourceTree = "<group>"; };
- A8C006CD0898634600BA5114 /* TestViewerSplitView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestViewerSplitView.h; sourceTree = "<group>"; };
- A8C006CE0898634600BA5114 /* TestController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestController.m; sourceTree = "<group>"; };
- A8C006EE089865E900BA5114 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/DrawTestDocument.nib; sourceTree = "<group>"; };
- A8C006F0089865E900BA5114 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/Inspector.nib; sourceTree = "<group>"; };
- A8C006F2089865E900BA5114 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/TestViewer.nib; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 8D11072E0486CEB800E47090 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
- 78662E6D096B4E1600907EA7 /* WebKit.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 080E96DDFE201D6D7F000001 /* Classes */ = {
- isa = PBXGroup;
- children = (
- A8C006E6089863B100BA5114 /* Test Browser */,
- A8C006E5089863A100BA5114 /* Viewer */,
- A8C006CB0898634600BA5114 /* AppDelegate.h */,
- A8C006CA0898634600BA5114 /* AppDelegate.m */,
- A8C006B30898634600BA5114 /* ScalingImageView.h */,
- A8C006B20898634600BA5114 /* ScalingImageView.m */,
- );
- name = Classes;
- sourceTree = "<group>";
- };
- 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
- isa = PBXGroup;
- children = (
- 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
- 78662E6C096B4E1600907EA7 /* WebKit.framework */,
- );
- name = "Linked Frameworks";
- sourceTree = "<group>";
- };
- 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
- isa = PBXGroup;
- children = (
- 29B97324FDCFA39411CA2CEA /* AppKit.framework */,
- 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
- 29B97325FDCFA39411CA2CEA /* Foundation.framework */,
- );
- name = "Other Frameworks";
- sourceTree = "<group>";
- };
- 19C28FACFE9D520D11CA2CBB /* Products */ = {
- isa = PBXGroup;
- children = (
- 8D1107320486CEB800E47090 /* DrawTest.app */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- 29B97314FDCFA39411CA2CEA /* DrawTest */ = {
- isa = PBXGroup;
- children = (
- 080E96DDFE201D6D7F000001 /* Classes */,
- 29B97315FDCFA39411CA2CEA /* Other Sources */,
- 29B97317FDCFA39411CA2CEA /* Resources */,
- 29B97323FDCFA39411CA2CEA /* Frameworks */,
- 19C28FACFE9D520D11CA2CBB /* Products */,
- );
- name = DrawTest;
- sourceTree = "<group>";
- };
- 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
- isa = PBXGroup;
- children = (
- 32CA4F630368D1EE00C91783 /* DrawTest_Prefix.pch */,
- 29B97316FDCFA39411CA2CEA /* main.m */,
- );
- name = "Other Sources";
- sourceTree = "<group>";
- };
- 29B97317FDCFA39411CA2CEA /* Resources */ = {
- isa = PBXGroup;
- children = (
- A8C006ED089865E900BA5114 /* DrawTestDocument.nib */,
- 8D1107310486CEB800E47090 /* Info.plist */,
- 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
- A8C006EF089865E900BA5114 /* Inspector.nib */,
- 29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
- A8C006F1089865E900BA5114 /* TestViewer.nib */,
- );
- name = Resources;
- sourceTree = "<group>";
- };
- 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
- 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
- );
- name = Frameworks;
- sourceTree = "<group>";
- };
- A8C006E5089863A100BA5114 /* Viewer */ = {
- isa = PBXGroup;
- children = (
- A8C006B80898634600BA5114 /* DrawTestDocument.h */,
- A8C006BD0898634600BA5114 /* DrawTestDocument.m */,
- A8C006BA0898634600BA5114 /* DrawTestToolbarController.h */,
- A8C006B70898634600BA5114 /* DrawTestToolbarController.m */,
- A8C006B60898634600BA5114 /* DrawTestView.h */,
- A8C006B50898634600BA5114 /* DrawTestView.m */,
- );
- name = Viewer;
- sourceTree = "<group>";
- };
- A8C006E6089863B100BA5114 /* Test Browser */ = {
- isa = PBXGroup;
- children = (
- A8C006BC0898634600BA5114 /* DrawTestInspectorController.h */,
- A8C006BB0898634600BA5114 /* DrawTestInspectorController.m */,
- A8C006B10898634600BA5114 /* SVGTest.h */,
- A8C006B00898634600BA5114 /* SVGTest.m */,
- A8C006AF0898634600BA5114 /* TestController.h */,
- A8C006CE0898634600BA5114 /* TestController.m */,
- A8C006CD0898634600BA5114 /* TestViewerSplitView.h */,
- A8C006CC0898634600BA5114 /* TestViewerSplitView.m */,
- );
- name = "Test Browser";
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 8D1107260486CEB800E47090 /* DrawTest */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = A8C006740898624E00BA5114 /* Build configuration list for PBXNativeTarget "DrawTest" */;
- buildPhases = (
- 8D1107290486CEB800E47090 /* Resources */,
- 8D11072C0486CEB800E47090 /* Sources */,
- 8D11072E0486CEB800E47090 /* Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = DrawTest;
- productInstallPath = "$(HOME)/Applications";
- productName = DrawTest;
- productReference = 8D1107320486CEB800E47090 /* DrawTest.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 29B97313FDCFA39411CA2CEA /* Project object */ = {
- isa = PBXProject;
- buildConfigurationList = A8C006780898624E00BA5114 /* Build configuration list for PBXProject "DrawTest" */;
- compatibilityVersion = "Xcode 2.4";
- hasScannedForEncodings = 1;
- mainGroup = 29B97314FDCFA39411CA2CEA /* DrawTest */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 8D1107260486CEB800E47090 /* DrawTest */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 8D1107290486CEB800E47090 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- A8C006F3089865E900BA5114 /* DrawTestDocument.nib in Resources */,
- 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
- A8C006F4089865E900BA5114 /* Inspector.nib in Resources */,
- 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */,
- A8C006F5089865E900BA5114 /* TestViewer.nib in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 8D11072C0486CEB800E47090 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- A8C006E10898634600BA5114 /* AppDelegate.m in Sources */,
- A8C006D50898634600BA5114 /* DrawTestDocument.m in Sources */,
- A8C006D40898634600BA5114 /* DrawTestInspectorController.m in Sources */,
- A8C006D30898634600BA5114 /* DrawTestToolbarController.m in Sources */,
- A8C006D20898634600BA5114 /* DrawTestView.m in Sources */,
- 8D11072D0486CEB800E47090 /* main.m in Sources */,
- A8C006D00898634600BA5114 /* ScalingImageView.m in Sources */,
- A8C006CF0898634600BA5114 /* SVGTest.m in Sources */,
- A8C006E30898634600BA5114 /* TestController.m in Sources */,
- A8C006E20898634600BA5114 /* TestViewerSplitView.m in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXVariantGroup section */
- 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
- isa = PBXVariantGroup;
- children = (
- 089C165DFE840E0CC02AAC07 /* English */,
- );
- name = InfoPlist.strings;
- sourceTree = "<group>";
- };
- 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = {
- isa = PBXVariantGroup;
- children = (
- 29B97319FDCFA39411CA2CEA /* English */,
- );
- name = MainMenu.nib;
- sourceTree = "<group>";
- };
- A8C006ED089865E900BA5114 /* DrawTestDocument.nib */ = {
- isa = PBXVariantGroup;
- children = (
- A8C006EE089865E900BA5114 /* English */,
- );
- name = DrawTestDocument.nib;
- sourceTree = "<group>";
- };
- A8C006EF089865E900BA5114 /* Inspector.nib */ = {
- isa = PBXVariantGroup;
- children = (
- A8C006F0089865E900BA5114 /* English */,
- );
- name = Inspector.nib;
- sourceTree = "<group>";
- };
- A8C006F1089865E900BA5114 /* TestViewer.nib */ = {
- isa = PBXVariantGroup;
- children = (
- A8C006F2089865E900BA5114 /* English */,
- );
- name = TestViewer.nib;
- sourceTree = "<group>";
- };
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
- A8C006750898624E00BA5114 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
- GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = DrawTest_Prefix.pch;
- GCC_TREAT_WARNINGS_AS_ERRORS = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- INFOPLIST_FILE = Info.plist;
- INSTALL_PATH = "$(HOME)/Applications";
- PREBINDING = NO;
- PRODUCT_NAME = DrawTest;
- WRAPPER_EXTENSION = app;
- ZERO_LINK = YES;
- };
- name = Debug;
- };
- A8C006760898624E00BA5114 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
- GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = DrawTest_Prefix.pch;
- GCC_TREAT_WARNINGS_AS_ERRORS = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- INFOPLIST_FILE = Info.plist;
- INSTALL_PATH = "$(HOME)/Applications";
- PREBINDING = NO;
- PRODUCT_NAME = DrawTest;
- WRAPPER_EXTENSION = app;
- ZERO_LINK = NO;
- };
- name = Release;
- };
- A8C006790898624E00BA5114 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- DEBUG_INFORMATION_FORMAT = dwarf;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- };
- name = Debug;
- };
- A8C0067A0898624E00BA5114 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- DEBUG_INFORMATION_FORMAT = dwarf;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- A8C006740898624E00BA5114 /* Build configuration list for PBXNativeTarget "DrawTest" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- A8C006750898624E00BA5114 /* Debug */,
- A8C006760898624E00BA5114 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- A8C006780898624E00BA5114 /* Build configuration list for PBXProject "DrawTest" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- A8C006790898624E00BA5114 /* Debug */,
- A8C0067A0898624E00BA5114 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
-}
diff --git a/WebKitTools/DrawTest/DrawTestDocument.h b/WebKitTools/DrawTest/DrawTestDocument.h
deleted file mode 100644
index b0b16d9..0000000
--- a/WebKitTools/DrawTest/DrawTestDocument.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import <Cocoa/Cocoa.h>
-
-@class DrawTestView;
-@class DrawTestToolbarController;
-
-@interface DrawTestDocument : NSDocument
-{
- IBOutlet DrawTestView *drawView;
- IBOutlet NSDrawer *debugDrawer;
-
- DrawTestToolbarController *toolbarController;
-}
-
-// Debug menu
-- (IBAction)dumpSVGToConsole:(id)sender;
-- (IBAction)toggleDebugDrawer:(id)sender;
-- (IBAction)runWindowResizeTest:(id)sender;
-
-@end
diff --git a/WebKitTools/DrawTest/DrawTestDocument.m b/WebKitTools/DrawTest/DrawTestDocument.m
deleted file mode 100644
index c71e7ad..0000000
--- a/WebKitTools/DrawTest/DrawTestDocument.m
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import "DrawTestDocument.h"
-#import "DrawTestView.h"
-#import "DrawTestToolbarController.h"
-#import <WebKit/WebView.h>
-#import <WebKit/WebFrame.h>
-#import <WebKit/WebDataSource.h>
-
-@implementation DrawTestDocument
-
-- (id)initWithType:(NSString *)typeName error:(NSError **)outError
-{
- if (outError) {
- NSDictionary *errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:
- @"No document could be created.", NSLocalizedDescriptionKey,
- @"New document creation not yet supported.", NSLocalizedFailureReasonErrorKey,
- nil];
- *outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:errorInfo];
- }
- [self release];
- return nil;
-}
-
-- (void)dealloc
-{
- [toolbarController release];
- [super dealloc];
-}
-
-- (NSString *)windowNibName
-{
- return @"DrawTestDocument";
-}
-
-- (BOOL)readFromFile:(NSString *)filename ofType:(NSString *)docType
-{
- // TODO: Check the validity of the document before returning YES.
- return YES;
-}
-
-- (void)windowControllerDidLoadNib:(NSWindowController *)aController
-{
- [super windowControllerDidLoadNib:aController];
- toolbarController = [[DrawTestToolbarController alloc] initWithDrawView:drawView];
- [drawView setDocument:[self fileURL]];
-}
-
-- (IBAction)dumpSVGToConsole:(id)sender
-{
- WebDataSource* dataSource = [[drawView mainFrame] dataSource];
- NSLog(@"SVG Markup for file %@:\n%@", [self fileURL], [[dataSource representation] documentSource]);
-}
-
-- (IBAction)openSourceForSelection:(id)sender
-{
- // TODO: The "path" message (below) will not produce a valid pathname if we are dealing with a remote file.
- NSString *filename = [[self fileURL] path];
- [[NSWorkspace sharedWorkspace] openFile:filename withApplication:@"TextEdit"];
-}
-
-- (NSData *)dataRepresentationOfType:(NSString *)aType
-{
- WebDataSource* dataSource = [[drawView mainFrame] dataSource];
- return [dataSource data];
-}
-
-#pragma mark -
-#pragma mark Debug Methods
-
-- (IBAction)toggleDebugDrawer:(id)sender
-{
- [debugDrawer toggle:sender];
-}
-
-- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
-{
- return nil;
-}
-
-- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
-{
- return NO;
-}
-
-- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
-{
- return 0;
-}
-
-- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
-{
- return nil;
-}
-
-- (IBAction)runWindowResizeTest:(id)sender
-{
- NSWindow *window = [drawView window];
- NSScreen *screen = [window screen];
- float screenHeight = [screen visibleFrame].size.height;
- NSRect originalFrame = [window frame];
- // initial setup
- BOOL toolbarVisible = [[window toolbar] isVisible];
- if (toolbarVisible) [window toggleToolbarShown:self];
- [window setFrame:NSMakeRect(0,screenHeight-100,100,100) display:YES];
-
- // grab time.
- CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
-
- // run test
- for (int x = 0; x < 3; x++) {
- for (float size = 100; size < 500.f; size += 20.f) {
- [window setFrame:NSMakeRect(0, screenHeight-size, size, size) display:YES];
- }
- }
-
- double elapsed = CFAbsoluteTimeGetCurrent() - start;
-
- // log
- NSLog(@"Window resize test: %fs", elapsed);
-
- // restore
- if (toolbarVisible) [window toggleToolbarShown:self];
- [window setFrame:originalFrame display:YES];
-}
-
-@end
diff --git a/WebKitTools/DrawTest/DrawTestInspectorController.h b/WebKitTools/DrawTest/DrawTestInspectorController.h
deleted file mode 100644
index 43c06f0..0000000
--- a/WebKitTools/DrawTest/DrawTestInspectorController.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import <Cocoa/Cocoa.h>
-
-
-@interface DrawTestInspectorController : NSObject {
- IBOutlet NSPanel *_inspectorPanel;
-}
-
-+ (id)sharedInstance;
-
-- (IBAction)showInspectorPanel:(id)sender;
-
-@end
diff --git a/WebKitTools/DrawTest/DrawTestInspectorController.m b/WebKitTools/DrawTest/DrawTestInspectorController.m
deleted file mode 100644
index 604bf03..0000000
--- a/WebKitTools/DrawTest/DrawTestInspectorController.m
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import "DrawTestInspectorController.h"
-
-@implementation DrawTestInspectorController
-
-+ (id)sharedInstance
-{
- static DrawTestInspectorController *__sharedController = nil;
- if (!__sharedController) {
- __sharedController = [[self alloc] init];
- }
- return __sharedController;
-}
-
-- (IBAction)showInspectorPanel:(id)sender
-{
- if (!_inspectorPanel) {
- [NSBundle loadNibNamed:@"Inspector" owner:self];
- }
- [_inspectorPanel makeKeyAndOrderFront:self];
-}
-
-
-@end
diff --git a/WebKitTools/DrawTest/DrawTestToolbarController.h b/WebKitTools/DrawTest/DrawTestToolbarController.h
deleted file mode 100644
index a69fb57..0000000
--- a/WebKitTools/DrawTest/DrawTestToolbarController.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import <Cocoa/Cocoa.h>
-
-@class WebView;
-
-@interface DrawTestToolbarController : NSObject {
- WebView *_drawView;
- NSMutableDictionary *_toolbarItems;
-}
-
-- (id)initWithDrawView:(WebView *)drawView;
-
-@end
diff --git a/WebKitTools/DrawTest/DrawTestToolbarController.m b/WebKitTools/DrawTest/DrawTestToolbarController.m
deleted file mode 100644
index 9190252..0000000
--- a/WebKitTools/DrawTest/DrawTestToolbarController.m
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import "DrawTestToolbarController.h"
-
-enum
-{
- ToolbarBrowseToolTag = 0,
- ToolbarPanToolTag,
- ToolbarZoomToolTag,
-
- ToolbarPointerToolTag,
- ToolbarLineToolTag,
- ToolbarRectangleToolTag,
- ToolbarElipseToolTag,
- ToolbarTriangleToolTag,
- ToolbarPolyLineToolTag,
- ToolbarArcToolTag,
-
- ToolbarDeleteSelectionTag,
-
- ToolbarMoveForwardTag,
- ToolbarMoveBackwardTag,
- ToolbarMoveToFrontTag,
- ToolbarMoveToBackTag,
- ToolbarMiscItem
-};
-
-// Constants
-NSString *ToolbarIdentifier = @"Main Document Toolbar";
-
-NSString *ToolbarBrowseToolIdentifier = @"Browse";
-NSString *ToolbarPanToolIdentifier = @"Pan";
-NSString *ToolbarZoomToolIdentifier = @"Zoom";
-
-NSString *ToolbarPointerToolIdentifier = @"Pointer";
-NSString *ToolbarRectangleToolIdentifier = @"Rectangle";
-NSString *ToolbarElipseToolIdentifier = @"Oval";
-NSString *ToolbarTriangleToolIdentifier = @"Triangle";
-NSString *ToolbarPolyLineToolIdentifier = @"PolyLine";
-NSString *ToolbarArcToolIdentifier = @"Arc";
-
-NSString *ToolbarDeleteShapeIdentifier = @"Delete";
-NSString *ToolbarMoveForwardIdentifier = @"Forward";
-NSString *ToolbarMoveBackwardIdentifier = @"Backward";
-NSString *ToolbarMoveToFrontIdentifier = @"Front";
-NSString *ToolbarMoveToBackIdentifier = @"Back";
-
-NSString *ToolbarPointerToolImage = @"Toolbar_Pointer";
-NSString *ToolbarRectangleToolImage = @"Toolbar_Rectangle";
-NSString *ToolbarElipseToolImage = @"Toolbar_Oval";
-NSString *ToolbarTriangleToolImage = @"Toolbar_Triangle";
-
-NSString *ToolbarDeleteShapeImage = @"Toolbar_Delete";
-NSString *ToolbarMoveForwardImage = @"Toolbar_Forward";
-NSString *ToolbarMoveBackwardImage = @"Toolbar_Backward";
-NSString *ToolbarMoveToFrontImage = @"Toolbar_Front";
-NSString *ToolbarMoveToBackImage = @"Toolbar_Back";
-
-@interface DrawTestToolbarController (InternalMethods)
-- (void)setupToolbar;
-- (void)addToolbarItemWithIdentifier:(NSString *)identifier withImage:(NSString *)image withTag:(int)tag;
-- (void)addToolbarItemWithIdentifier:(NSString *)identifier withImage:(NSString *)image;
-- (void)addToolbarItem:(NSString *)identifier
- withLabel:(NSString *)label
- withPaletteLabel:(NSString *)paletteLabel
- withImage:(NSString *)imageName
- withToolTip:(NSString *)toolTip
- withTag:(int)tag;
-@end
-
-
-@implementation DrawTestToolbarController
-
-- (id)initWithDrawView:(WebView *)drawView
-{
- if (self = [super init]){
- _drawView = [drawView retain];
- [self setupToolbar]; // could be done lazily.
- }
- return self;
-}
-
-- (void)dealloc
-{
- [_toolbarItems release];
- [super dealloc];
-}
-
-
-- (void)addToolbarItemWithIdentifier:(NSString *)identifier withImage:(NSString *)image withTag:(int)tag
-{
-
- [self addToolbarItem:identifier
- withLabel:identifier
- withPaletteLabel:identifier
- withImage:image
- withToolTip:identifier
- withTag:tag];
-}
-
-- (void)addToolbarItemWithIdentifier:(NSString *)identifier withImage:(NSString *)image
-{
- [self addToolbarItemWithIdentifier:identifier withImage:image withTag:ToolbarMiscItem];
-}
-
-- (void)addToolbarItem:(NSString *)identifier
- withLabel:(NSString *)label
- withPaletteLabel:(NSString *)paletteLabel
- withImage:(NSString *)imageName
- withToolTip:(NSString *)toolTip
- withTag:(int)tag
-{
- NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:identifier] autorelease];
-
- [item setLabel:label];
- [item setPaletteLabel:paletteLabel];
- [item setToolTip:toolTip];
- [item setImage:[NSImage imageNamed:imageName]];
- [item setTarget:self];
- [item setAction:@selector(clickedToolbarItem:)];
- [item setTag:tag];
-
- [_toolbarItems setObject:item forKey:identifier];
-}
-
-- (void)setupToolbar
-{
- _toolbarItems = [[NSMutableDictionary alloc] init];
-
- [self addToolbarItemWithIdentifier:ToolbarBrowseToolIdentifier
- withImage:ToolbarPointerToolImage
- withTag:ToolbarBrowseToolTag];
- [[_toolbarItems objectForKey:ToolbarBrowseToolIdentifier] setImage:[[NSCursor pointingHandCursor] image]];
-
- [self addToolbarItemWithIdentifier:ToolbarPanToolIdentifier
- withImage:ToolbarPointerToolImage
- withTag:ToolbarPanToolTag];
- [[_toolbarItems objectForKey:ToolbarPanToolIdentifier] setImage:[[NSCursor openHandCursor] image]];
-
- [self addToolbarItemWithIdentifier:ToolbarZoomToolIdentifier
- withImage:ToolbarPointerToolImage
- withTag:ToolbarZoomToolTag];
-
-
- [self addToolbarItemWithIdentifier:ToolbarPointerToolIdentifier
- withImage:ToolbarPointerToolImage
- withTag:ToolbarPointerToolTag];
-
- [self addToolbarItemWithIdentifier:ToolbarRectangleToolIdentifier
- withImage:ToolbarRectangleToolImage
- withTag:ToolbarRectangleToolTag];
-
- [self addToolbarItemWithIdentifier:ToolbarElipseToolIdentifier
- withImage:ToolbarElipseToolImage
- withTag:ToolbarElipseToolTag];
-
- [self addToolbarItemWithIdentifier:ToolbarTriangleToolIdentifier
- withImage:ToolbarTriangleToolImage
- withTag:ToolbarTriangleToolTag];
-
- [self addToolbarItemWithIdentifier:ToolbarDeleteShapeIdentifier
- withImage:ToolbarDeleteShapeImage
- withTag:ToolbarDeleteSelectionTag];
-
- [self addToolbarItemWithIdentifier:ToolbarMoveForwardIdentifier
- withImage:ToolbarMoveForwardImage
- withTag:ToolbarMoveForwardTag];
-
- [self addToolbarItemWithIdentifier:ToolbarMoveBackwardIdentifier
- withImage:ToolbarMoveBackwardImage
- withTag:ToolbarMoveBackwardTag];
-
- [self addToolbarItemWithIdentifier:ToolbarMoveToFrontIdentifier
- withImage:ToolbarMoveToFrontImage
- withTag:ToolbarMoveToFrontTag];
-
- [self addToolbarItemWithIdentifier:ToolbarMoveToBackIdentifier
- withImage:ToolbarMoveToBackImage
- withTag:ToolbarMoveToBackTag];
-
-
- NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier:ToolbarIdentifier] autorelease];
-
- [toolbar setAllowsUserCustomization:YES];
- [toolbar setAutosavesConfiguration:YES];
- [toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
- [toolbar setSizeMode:NSToolbarSizeModeSmall];
- [toolbar setDisplayMode:NSToolbarDisplayModeLabelOnly];
- [toolbar setDelegate:self];
- [toolbar setSelectedItemIdentifier:ToolbarBrowseToolIdentifier];
- [toolbar setVisible:NO];
-
- [[_drawView window] setToolbar:toolbar];
-}
-
-
-- (void)clickedToolbarItem:(id)sender
-{
- int tag = [sender tag];
-
- switch(tag) {
-#if 0
- case ToolbarBrowseToolTag:
- [_drawView setToolMode:DrawViewToolBrowse];
- break;
- case ToolbarPanToolTag:
- [_drawView setToolMode:DrawViewToolPan];
- break;
- case ToolbarZoomToolTag:
- [_drawView setToolMode:DrawViewToolZoom];
- break;
- case ToolbarPointerToolTag:
- [_drawView setToolMode:DrawViewToolArrow];
- break;
- case ToolbarRectangleToolTag:
- [_drawView setToolMode:DrawViewToolRectangle];
- break;
- case ToolbarElipseToolTag:
- [_drawView setToolMode:DrawViewToolElipse];
- break;
- case ToolbarTriangleToolTag:
- [_drawView setToolMode:DrawViewToolTriangle];
- break;
- case ToolbarMoveForwardTag:
- [_drawView moveSelectionForward:sender];
- break;
- case ToolbarMoveBackwardTag:
- [_drawView moveSelectionBackward:sender];
- break;
- case ToolbarDeleteSelectionTag:
- [_drawView deleteSelection:sender];
- break;
-#endif
- default:
- NSLog(@"Toolbar item: %i not implemented!", tag);
- }
-
- [_drawView setNeedsDisplay:YES];
-}
-
-// NSToolbar delegate methods
-- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdent
- willBeInsertedIntoToolbar:(BOOL)willBeInserted
-{
- NSToolbarItem * toolbarItem = [_toolbarItems objectForKey:itemIdent];
-
- if( toolbarItem == nil )
- toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdent] autorelease];
-
- return toolbarItem;
-}
-
-- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
-{
- return [NSArray arrayWithObjects:
- ToolbarBrowseToolIdentifier,
- ToolbarPanToolIdentifier,
- ToolbarZoomToolIdentifier,
- ToolbarPointerToolIdentifier,
- ToolbarRectangleToolIdentifier,
- ToolbarElipseToolIdentifier,
- ToolbarTriangleToolIdentifier,
- ToolbarDeleteShapeIdentifier,
- NSToolbarShowColorsItemIdentifier,
- ToolbarMoveForwardIdentifier,
- ToolbarMoveBackwardIdentifier,
- ToolbarMoveToFrontIdentifier,
- ToolbarMoveToBackIdentifier,
- NSToolbarCustomizeToolbarItemIdentifier,
- NSToolbarFlexibleSpaceItemIdentifier,
- NSToolbarSpaceItemIdentifier,
- NSToolbarSeparatorItemIdentifier, nil];
-}
-
-- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
-{
- return [NSArray arrayWithObjects:
- ToolbarBrowseToolIdentifier,
- ToolbarPanToolIdentifier,
- //ToolbarZoomToolIdentifier,
- NSToolbarFlexibleSpaceItemIdentifier,
- ToolbarPointerToolIdentifier,
- ToolbarRectangleToolIdentifier,
- ToolbarElipseToolIdentifier,
- //ToolbarTriangleToolIdentifier,
- //NSToolbarSeparatorItemIdentifier,
- ToolbarDeleteShapeIdentifier,
- //ToolbarMoveForwardIdentifier,
- //ToolbarMoveBackwardIdentifier,
- //ToolbarMoveToFrontIdentifier,
- //ToolbarMoveToBackIdentifier,
- NSToolbarSeparatorItemIdentifier,
- //NSToolbarShowColorsItemIdentifier,
- //NSToolbarFlexibleSpaceItemIdentifier,
- NSToolbarCustomizeToolbarItemIdentifier,
- nil];
-}
-
-- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
-{
- return [NSArray arrayWithObjects:
- ToolbarBrowseToolIdentifier,
- ToolbarPanToolIdentifier,
- ToolbarZoomToolIdentifier,
- ToolbarPointerToolIdentifier,
- ToolbarRectangleToolIdentifier,
- ToolbarElipseToolIdentifier,
- ToolbarTriangleToolIdentifier,
- nil];
-}
-
-- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
-{
- BOOL enabled = YES;
-
-#if 0
- switch([theItem tag]) {
- case ToolbarMoveForwardTag:
- case ToolbarMoveBackwardTag:
- case ToolbarMoveToFrontTag:
- case ToolbarMoveToBackTag:
- case ToolbarDeleteSelectionTag:
- enabled = ([[_drawView selectedCanvasItems] count] != 0);
- }
-#endif
-
- return enabled;
-}
-
-@end
diff --git a/WebKitTools/DrawTest/DrawTestView.h b/WebKitTools/DrawTest/DrawTestView.h
deleted file mode 100644
index 95d5956..0000000
--- a/WebKitTools/DrawTest/DrawTestView.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import <Cocoa/Cocoa.h>
-
-#import <WebKit/WebView.h>
-
-@interface DrawTestView : WebView
-{
-
-}
-
-- (void)setDocument:(NSURL *)documentURL;
-
-@end
diff --git a/WebKitTools/DrawTest/DrawTestView.m b/WebKitTools/DrawTest/DrawTestView.m
deleted file mode 100644
index c865f99..0000000
--- a/WebKitTools/DrawTest/DrawTestView.m
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import <WebKit/WebFrame.h>
-
-#import "DrawTestView.h"
-
-@implementation DrawTestView
-
-- (void)setDocument:(NSURL *)documentURL
-{
- [[self mainFrame] loadRequest:[NSURLRequest requestWithURL:documentURL]];
-}
-
-- (BOOL)acceptsFirstResponder
-{
- return YES;
-}
-
-@end
diff --git a/WebKitTools/DrawTest/DrawTest_Prefix.pch b/WebKitTools/DrawTest/DrawTest_Prefix.pch
deleted file mode 100644
index 8393f01..0000000
--- a/WebKitTools/DrawTest/DrawTest_Prefix.pch
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-//
-// Prefix header for all source files of the 'DrawTest' target in the 'DrawTest' project
-//
-
-#ifdef __OBJC__
-#import <Cocoa/Cocoa.h>
-
-#define foreacharray(__variable, __container) \
- for (int __variable##__i=0, __variable##__n=[__container count]; \
- __variable##__i < __variable##__n && (__variable = [__container objectAtIndex:__variable##__i]); \
- ++__variable##__i)
-#endif
diff --git a/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/classes.nib b/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/classes.nib
deleted file mode 100644
index 296ffc3..0000000
--- a/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/classes.nib
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- IBClasses = (
- {
- ACTIONS = {toggleShowDebugAxes = id; toggleShowDebugString = id; };
- CLASS = DrawTestView;
- LANGUAGE = ObjC;
- SUPERCLASS = DrawView;
- },
- {
- ACTIONS = {
- deleteSelection = id;
- moveSelectionBackward = id;
- moveSelectionForward = id;
- zoomIn = id;
- zoomOriginal = id;
- zoomOut = id;
- zoomToFit = id;
- };
- CLASS = DrawView;
- LANGUAGE = ObjC;
- SUPERCLASS = NSView;
- },
- {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
- {
- ACTIONS = {dumpSVGToConsole = id; };
- CLASS = MyDocument;
- LANGUAGE = ObjC;
- OUTLETS = {drawView = KCanvasTestView; };
- SUPERCLASS = NSDocument;
- },
- {CLASS = NSSegmentedControl; LANGUAGE = ObjC; SUPERCLASS = NSControl; }
- );
- IBVersion = 1;
-} \ No newline at end of file
diff --git a/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/info.nib b/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/info.nib
deleted file mode 100644
index 3c96fd5..0000000
--- a/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/info.nib
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBDocumentLocation</key>
- <string>86 30 356 240 0 0 1024 746 </string>
- <key>IBEditorPositions</key>
- <dict>
- <key>50</key>
- <string>377 327 270 342 0 0 1024 746 </string>
- </dict>
- <key>IBFramework Version</key>
- <string>437.0</string>
- <key>IBOpenObjects</key>
- <array>
- <integer>50</integer>
- <integer>5</integer>
- </array>
- <key>IBSystem Version</key>
- <string>8C42</string>
-</dict>
-</plist>
diff --git a/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/keyedobjects.nib b/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/keyedobjects.nib
deleted file mode 100644
index b78ff2c..0000000
--- a/WebKitTools/DrawTest/English.lproj/DrawTestDocument.nib/keyedobjects.nib
+++ /dev/null
Binary files differ
diff --git a/WebKitTools/DrawTest/English.lproj/InfoPlist.strings b/WebKitTools/DrawTest/English.lproj/InfoPlist.strings
deleted file mode 100644
index 0a7822d..0000000
--- a/WebKitTools/DrawTest/English.lproj/InfoPlist.strings
+++ /dev/null
Binary files differ
diff --git a/WebKitTools/DrawTest/English.lproj/Inspector.nib/classes.nib b/WebKitTools/DrawTest/English.lproj/Inspector.nib/classes.nib
deleted file mode 100644
index 725f5a4..0000000
--- a/WebKitTools/DrawTest/English.lproj/Inspector.nib/classes.nib
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- IBClasses = (
- {
- CLASS = DrawTestInspectorController;
- LANGUAGE = ObjC;
- OUTLETS = {"_inspectorPanel" = NSPanel; };
- SUPERCLASS = NSObject;
- },
- {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
- );
- IBVersion = 1;
-} \ No newline at end of file
diff --git a/WebKitTools/DrawTest/English.lproj/Inspector.nib/info.nib b/WebKitTools/DrawTest/English.lproj/Inspector.nib/info.nib
deleted file mode 100644
index d930763..0000000
--- a/WebKitTools/DrawTest/English.lproj/Inspector.nib/info.nib
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBDocumentLocation</key>
- <string>261 184 356 240 0 0 1024 746 </string>
- <key>IBFramework Version</key>
- <string>437.0</string>
- <key>IBOpenObjects</key>
- <array>
- <integer>7</integer>
- </array>
- <key>IBSystem Version</key>
- <string>8B9</string>
-</dict>
-</plist>
diff --git a/WebKitTools/DrawTest/English.lproj/Inspector.nib/keyedobjects.nib b/WebKitTools/DrawTest/English.lproj/Inspector.nib/keyedobjects.nib
deleted file mode 100644
index 02869ca..0000000
--- a/WebKitTools/DrawTest/English.lproj/Inspector.nib/keyedobjects.nib
+++ /dev/null
Binary files differ
diff --git a/WebKitTools/DrawTest/English.lproj/MainMenu.nib/classes.nib b/WebKitTools/DrawTest/English.lproj/MainMenu.nib/classes.nib
deleted file mode 100644
index c0ca441..0000000
--- a/WebKitTools/DrawTest/English.lproj/MainMenu.nib/classes.nib
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- IBClasses = (
- {
- ACTIONS = {showImageRepTestWindow = id; showInspectorPanel = id; showTestsPanel = id; };
- CLASS = AppDelegate;
- LANGUAGE = ObjC;
- OUTLETS = {svgImageRepTestWindow = NSWindow; };
- SUPERCLASS = NSObject;
- },
- {
- ACTIONS = {
- dumpSVGToConsole = id;
- openSelectionInViewer = id;
- openSourceForSelection = id;
- runWindowResizeTest = id;
- showCompositeWindow = id;
- showImageRepTestWindow = id;
- showInspectorPanel = id;
- showTestsPanel = id;
- toggleDebugDrawer = id;
- toggleFilterSupport = id;
- toggleShowDebugAxes = id;
- toggleShowDebugString = id;
- toggleViewersScaleRule = id;
- zoomIn = id;
- zoomOriginal = id;
- zoomOut = id;
- zoomToContent = id;
- };
- CLASS = FirstResponder;
- LANGUAGE = ObjC;
- SUPERCLASS = NSObject;
- },
- {CLASS = KCanvasTestView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
- {
- ACTIONS = {dumpSVGToConsole = id; };
- CLASS = MyDocument;
- LANGUAGE = ObjC;
- OUTLETS = {canvasView = KCanvasTestView; };
- SUPERCLASS = NSDocument;
- }
- );
- IBVersion = 1;
-} \ No newline at end of file
diff --git a/WebKitTools/DrawTest/English.lproj/MainMenu.nib/info.nib b/WebKitTools/DrawTest/English.lproj/MainMenu.nib/info.nib
deleted file mode 100644
index 9b783e0..0000000
--- a/WebKitTools/DrawTest/English.lproj/MainMenu.nib/info.nib
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBDocumentLocation</key>
- <string>274 58 356 240 0 0 1024 746 </string>
- <key>IBEditorPositions</key>
- <dict>
- <key>29</key>
- <string>128 678 355 44 0 0 1024 746 </string>
- </dict>
- <key>IBFramework Version</key>
- <string>439.0</string>
- <key>IBOpenObjects</key>
- <array>
- <integer>29</integer>
- </array>
- <key>IBSystem Version</key>
- <string>8C32</string>
-</dict>
-</plist>
diff --git a/WebKitTools/DrawTest/English.lproj/MainMenu.nib/keyedobjects.nib b/WebKitTools/DrawTest/English.lproj/MainMenu.nib/keyedobjects.nib
deleted file mode 100644
index 642b5ae..0000000
--- a/WebKitTools/DrawTest/English.lproj/MainMenu.nib/keyedobjects.nib
+++ /dev/null
Binary files differ
diff --git a/WebKitTools/DrawTest/English.lproj/TestViewer.nib/classes.nib b/WebKitTools/DrawTest/English.lproj/TestViewer.nib/classes.nib
deleted file mode 100644
index eb82ec7..0000000
--- a/WebKitTools/DrawTest/English.lproj/TestViewer.nib/classes.nib
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- IBClasses = (
- {CLASS = DrawView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
- {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
- {CLASS = KCanvasTestView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
- {CLASS = MyImageView; LANGUAGE = ObjC; SUPERCLASS = NSImageView; },
- {
- ACTIONS = {
- browse = id;
- jumpToParentDirectory = id;
- openSelectionInViewer = id;
- openSourceForSelection = id;
- openTestViewerForSelection = id;
- showCompositeWindow = id;
- showTestWindow = id;
- showTestsPanel = id;
- toggleViewersScaleRule = id;
- };
- CLASS = TestController;
- LANGUAGE = ObjC;
- OUTLETS = {
- "_compositeImageView" = NSImageView;
- "_compositeWindow" = NSWindow;
- "_parentDirectoryPopup" = NSPopUpButton;
- "_splitView" = TestViewerSplitView;
- "_testPanel" = NSPanel;
- "_testWindow" = NSWindow;
- "_testsArrayController" = NSArrayController;
- "_testsTableView" = NSTableView;
- };
- SUPERCLASS = NSObject;
- },
- {CLASS = TestViewerSplitView; LANGUAGE = ObjC; SUPERCLASS = NSView; }
- );
- IBVersion = 1;
-} \ No newline at end of file
diff --git a/WebKitTools/DrawTest/English.lproj/TestViewer.nib/info.nib b/WebKitTools/DrawTest/English.lproj/TestViewer.nib/info.nib
deleted file mode 100644
index ca801e8..0000000
--- a/WebKitTools/DrawTest/English.lproj/TestViewer.nib/info.nib
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBDocumentLocation</key>
- <string>263 119 356 240 0 0 1024 746 </string>
- <key>IBFramework Version</key>
- <string>437.0</string>
- <key>IBOpenObjects</key>
- <array>
- <integer>24</integer>
- <integer>60</integer>
- </array>
- <key>IBSystem Version</key>
- <string>8C26</string>
-</dict>
-</plist>
diff --git a/WebKitTools/DrawTest/English.lproj/TestViewer.nib/keyedobjects.nib b/WebKitTools/DrawTest/English.lproj/TestViewer.nib/keyedobjects.nib
deleted file mode 100644
index 46b8964..0000000
--- a/WebKitTools/DrawTest/English.lproj/TestViewer.nib/keyedobjects.nib
+++ /dev/null
Binary files differ
diff --git a/WebKitTools/DrawTest/Info.plist b/WebKitTools/DrawTest/Info.plist
deleted file mode 100644
index 0fd092b..0000000
--- a/WebKitTools/DrawTest/Info.plist
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//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>CFBundleDocumentTypes</key>
- <array>
- <dict>
- <key>CFBundleTypeExtensions</key>
- <array>
- <string>svg</string>
- </array>
- <key>CFBundleTypeName</key>
- <string>SVG Document</string>
- <key>CFBundleTypeOSTypes</key>
- <array>
- <string>????</string>
- </array>
- <key>CFBundleTypeRole</key>
- <string>Editor</string>
- <key>LSTypeIsPackage</key>
- <false/>
- <key>NSDocumentClass</key>
- <string>DrawTestDocument</string>
- <key>NSPersistentStoreTypeKey</key>
- <string>Binary</string>
- </dict>
- </array>
- <key>CFBundleExecutable</key>
- <string>DrawTest</string>
- <key>CFBundleGetInfoString</key>
- <string>420+, Copyright 2005, 2006 Apple Computer, Inc.</string>
- <key>CFBundleIdentifier</key>
- <string>com.apple.DrawTest</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1.0</string>
- <key>NSMainNibFile</key>
- <string>MainMenu</string>
- <key>NSPrincipalClass</key>
- <string>NSApplication</string>
-</dict>
-</plist>
diff --git a/WebKitTools/DrawTest/SVGTest.h b/WebKitTools/DrawTest/SVGTest.h
deleted file mode 100644
index 70eed41..0000000
--- a/WebKitTools/DrawTest/SVGTest.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import <Cocoa/Cocoa.h>
-
-@interface SVGTest : NSObject {
- NSString *_svgPath;
- NSString *_imagePath;
-
- NSImage *_image;
- NSImage *_compositeImage;
- BOOL _hasPassed;
-}
-
-+ (id)testWithSVGPath:(NSString *)svgPath imagePath:(NSString *)imagePath;
-- (id)initWithSVGPath:(NSString *)svgPath imagePath:(NSString *)imagePath;
-
-- (NSString *)imagePath;
-- (NSString *)svgPath;
-
-- (NSImage *)image;
-- (NSImage *)compositeImage;
-- (NSString *)name;
-
-@end
diff --git a/WebKitTools/DrawTest/SVGTest.m b/WebKitTools/DrawTest/SVGTest.m
deleted file mode 100644
index 4ea562d..0000000
--- a/WebKitTools/DrawTest/SVGTest.m
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import "SVGTest.h"
-
-#import <WebKit/WebView.h>
-
-@implementation SVGTest
-
-+ (id)testWithSVGPath:(NSString *)svgPath imagePath:(NSString *)imagePath
-{
- SVGTest *test = [[self alloc] initWithSVGPath:svgPath imagePath:imagePath];
- return [test autorelease];
-}
-
-static WebView *__sharedDrawView = nil;
-+ (WebView *)sharedDrawView
-{
- if (!__sharedDrawView) {
- __sharedDrawView = [[WebView alloc] initWithFrame:NSMakeRect(0,0,0,0)];
- }
- return __sharedDrawView;
-}
-
-- (id)initWithSVGPath:(NSString *)svgPath imagePath:(NSString *)imagePath
-{
- if (self = [super init]) {
- _svgPath = [svgPath copy];
- _imagePath = [imagePath copy];
- }
- return self;
-}
-
-- (NSString *)imagePath
-{
- return _imagePath;
-}
-
-- (NSString *)svgPath
-{
- return _svgPath;
-}
-
-- (NSImage *)image
-{
- if (!_image && _imagePath) {
- _image = [[NSImage alloc] initByReferencingFile:_imagePath];
- }
- return _image;
-}
-
-- (NSString *)name
-{
- NSMutableString *name = [[[[_svgPath lastPathComponent] stringByDeletingPathExtension] mutableCopy] autorelease];
- [name replaceOccurrencesOfString:@"_" withString:@" " options:0 range:NSMakeRange(0, [name length])];
- return [name capitalizedString];
-}
-
-- (void)generateCompositeIfNecessary
-{
- if (!_compositeImage) {
- WebView *view = [SVGTest sharedDrawView];
- NSSize svgSize = [view bounds].size;
-
- NSImage *image = [self image];
- NSSize imageSize = [image size];
-
- NSBitmapImageRep *svgImage = [view bitmapImageRepForCachingDisplayInRect:[view bounds]];
- [view cacheDisplayInRect:[view bounds] toBitmapImageRep:svgImage];
-
- NSSize unionSize = NSMakeSize(MAX(svgSize.width, imageSize.width), MAX(svgSize.height, imageSize.height));
- _compositeImage = [[NSImage alloc] initWithSize:unionSize];
-
- [_compositeImage lockFocus];
- [svgImage drawInRect:NSMakeRect(0,0,svgSize.width,svgSize.height)];
- [image drawInRect:NSMakeRect(0,0,imageSize.width,imageSize.height)
- fromRect:NSMakeRect(0,0,imageSize.width,imageSize.height)
- operation:NSCompositeXOR fraction:1.0];
- [_compositeImage unlockFocus];
- }
-}
-
-- (NSImage *)compositeImage
-{
- [self generateCompositeIfNecessary];
- return _compositeImage;
-}
-
-
-@end
diff --git a/WebKitTools/DrawTest/ScalingImageView.h b/WebKitTools/DrawTest/ScalingImageView.h
deleted file mode 100644
index 4370ff5..0000000
--- a/WebKitTools/DrawTest/ScalingImageView.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import <Cocoa/Cocoa.h>
-
-
-@interface ScalingImageView : NSImageView {
-
-}
-
-@end
diff --git a/WebKitTools/DrawTest/ScalingImageView.m b/WebKitTools/DrawTest/ScalingImageView.m
deleted file mode 100644
index 605397a..0000000
--- a/WebKitTools/DrawTest/ScalingImageView.m
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-
-#import "ScalingImageView.h"
-
-@implementation ScalingImageView
-
-/*
- This class offers two behaviors different from the standard NSImageView
- (and which were not available w/o subclassing)
- 1. Scale an image proportionally up to fit a larger view (NSImageView refuses)
- 2. Draw a background color w/o needing to show a bezel.
-*/
-
-- (void)drawRect:(NSRect)dirtyRect
-{
- [[NSColor whiteColor] set];
- NSRectFill(dirtyRect);
-
- NSSize imageSize = [[self image] size];
- float scale = 1.0f;
- if ([self imageScaling] == NSScaleProportionally && imageSize.width && imageSize.height) {
- float widthScale = [self bounds].size.width / imageSize.width;
- float heightScale = [self bounds].size.height / imageSize.height;
- scale = MIN(widthScale, heightScale);
- }
-
- float scaledHeight = imageSize.height * scale;
- NSRect destRect = NSMakeRect(0,[self bounds].size.height - scaledHeight,imageSize.width * scale, scaledHeight);
- [[self image] drawInRect:destRect
- fromRect:NSMakeRect(0,0,imageSize.width, imageSize.height) operation:NSCompositeSourceOver fraction:1.0];
-}
-
-@end
diff --git a/WebKitTools/DrawTest/TestController.h b/WebKitTools/DrawTest/TestController.h
deleted file mode 100644
index 1e781fe..0000000
--- a/WebKitTools/DrawTest/TestController.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import <Cocoa/Cocoa.h>
-
-@class DrawTestView;
-@class SVGTest;
-@class TestViewerSplitView;
-
-@interface TestController : NSObject {
- IBOutlet NSPanel *_testPanel;
- IBOutlet NSWindow *_testWindow;
- IBOutlet TestViewerSplitView *_splitView;
-
- IBOutlet NSArrayController *_testsArrayController;
- IBOutlet NSPopUpButton *_parentDirectoryPopup;
- IBOutlet NSTableView *_testsTableView;
-
- IBOutlet NSWindow *_compositeWindow;
- IBOutlet NSImageView *_compositeImageView;
-
-@private
- NSString *_currentPath;
- NSArray *_tests;
- SVGTest *_selectedTest;
-
- DrawTestView *_drawView;
- NSImageView *_imageView;
-}
-
-+ (id)sharedController;
-
-- (IBAction)showTestsPanel:(id)sender;
-- (IBAction)showTestWindow:(id)sender;
-- (IBAction)showCompositeWindow:(id)sender;
-
-- (IBAction)browse:(id)sender;
-- (IBAction)jumpToParentDirectory:(id)sender;
-- (IBAction)openTestViewerForSelection:(id)sender;
-- (IBAction)openSourceForSelection:(id)sender;
-- (IBAction)openSelectionInViewer:(id)sender;
-- (IBAction)toggleViewersScaleRule:(id)sender;
-
-- (NSArray *)tests;
-- (NSString *)currentPath;
-- (void)setCurrentPath:(NSString *)newPath;
-- (NSArray *)directoryHierarchy;
-
-@end
diff --git a/WebKitTools/DrawTest/TestController.m b/WebKitTools/DrawTest/TestController.m
deleted file mode 100644
index 506920b..0000000
--- a/WebKitTools/DrawTest/TestController.m
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2006 Nefaur Khandker <nefaurk@gmail.com> 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import "TestController.h"
-#import "SVGTest.h"
-#import "TestViewerSplitView.h"
-#import "ScalingImageView.h"
-#import "DrawTestView.h"
-
-#import <WebKit/WebView.h>
-
-@interface NSArray (TestControllerAdditions)
-- (id)firstObject;
-@end
-
-@implementation NSArray (TestControllerAdditions)
-- (id)firstObject
-{
- if ([self count])
- return [self objectAtIndex:0];
- return nil;
-}
-@end
-
-static TestController *__sharedInstance = nil;
-
-@implementation TestController
-
-- (id)init
-{
- if (self = [super init]) {
- NSString *path = [[NSUserDefaults standardUserDefaults] objectForKey:@"TestDirectory"];
- BOOL isDirectory = NO;
- if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory] || !isDirectory) {
- path = [@"~" stringByStandardizingPath];
- }
- [self setCurrentPath:path];
- }
- return self;
-}
-
-+ (void)initialize
-{
- [self setKeys:[NSArray arrayWithObject:@"currentPath"] triggerChangeNotificationsForDependentKey:@"directoryHierarchy"];
- [self setKeys:[NSArray arrayWithObject:@"currentPath"] triggerChangeNotificationsForDependentKey:@"tests"];
-}
-
-+ (id)sharedController
-{
- if (!__sharedInstance) {
- __sharedInstance = [[self alloc] init];
- }
- return __sharedInstance;
-}
-
-- (void)loadNibIfNecessary
-{
- if (!_testPanel) {
- [NSBundle loadNibNamed:@"TestViewer" owner:self];
- }
-}
-
-- (void)awakeFromNib
-{
- [_testsTableView setTarget:self];
- [_testsTableView setDoubleAction:@selector(openTestViewerForSelection:)];
- _drawView = [[DrawTestView alloc] initWithFrame:NSZeroRect];
- _imageView = [[ScalingImageView alloc] initWithFrame:NSZeroRect];
- [_splitView addSubview:_drawView];
- [_splitView addSubview:_imageView];
-}
-
-- (IBAction)showTestsPanel:(id)sender
-{
- [self loadNibIfNecessary];
- [_testPanel makeKeyAndOrderFront:sender];
-}
-
-- (IBAction)showTestWindow:(id)sender
-{
- [self loadNibIfNecessary];
- [_testWindow makeKeyAndOrderFront:sender];
-}
-
-- (IBAction)showCompositeWindow:(id)sender
-{
- [self loadNibIfNecessary];
- NSLog(@"showCompositeWindow: %@", _compositeWindow);
- [_compositeWindow makeKeyAndOrderFront:sender];
-}
-
-- (IBAction)browse:(id)sender
-{
- NSOpenPanel *openPanel = [NSOpenPanel openPanel];
- [openPanel setCanChooseDirectories:YES];
- [openPanel setCanChooseFiles:NO];
- [openPanel beginSheetForDirectory:nil file:nil modalForWindow:_testPanel modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
-}
-
-- (void)openPanelDidEnd:(NSOpenPanel *)openPanel returnCode:(int)returnCode contextInfo:(void *)contextInfo
-{
- if (returnCode == NSOKButton) {
- NSArray *folders = [openPanel filenames];
- NSString *selectedFolder = [folders firstObject];
- [self setCurrentPath:selectedFolder];
- }
-}
-
-- (IBAction)jumpToParentDirectory:(id)sender
-{
- int index = [_parentDirectoryPopup indexOfSelectedItem];
- NSArray *components = [_currentPath pathComponents];
- NSArray *newComponents = [components subarrayWithRange:NSMakeRange(0, [components count] - index)];
- NSString *newPath = [NSString pathWithComponents:newComponents];
- [self setCurrentPath:newPath];
-}
-
-- (void)setSelectedTest:(SVGTest *)selectedTest
-{
- id oldTest = _selectedTest;
- _selectedTest = [selectedTest retain];
- [oldTest release];
-
- if ([_testWindow isVisible]) {
- [_testWindow setTitle:[NSString stringWithFormat:@"Test Viewer - %@", [_selectedTest name]]];
- [_drawView setDocument:[NSURL fileURLWithPath:[_selectedTest svgPath]]];
- [_imageView setImage:[_selectedTest image]];
- if ([_compositeWindow isVisible])
- [_compositeImageView setImage:[_selectedTest compositeImage]];
- }
-}
-
-- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
-{
- [self setSelectedTest:[[_testsArrayController selectedObjects] firstObject]];
-}
-
-- (IBAction)openTestViewerForSelection:(id)sender
-{
- [self showTestWindow:sender];
- [_drawView setDocument:[NSURL fileURLWithPath:[_selectedTest svgPath]]];
- [_imageView setImage:[_selectedTest image]];
-}
-
-- (IBAction)openSourceForSelection:(id)sender
-{
- [[NSWorkspace sharedWorkspace] openFile:[_selectedTest svgPath] withApplication:@"TextEdit"];
-}
-
-- (IBAction)openSelectionInViewer:(id)sender
-{
- [[NSWorkspace sharedWorkspace] openFile:[_selectedTest svgPath]];
-}
-
-- (NSString *)imagePathForSVGPath:(NSString *)svgPath
-{
- // eventually this code will build an array instead...
-
- NSString *currentDirectory = [self currentPath];
- NSString *parentDirectory = [currentDirectory stringByDeletingLastPathComponent];
-
- NSString *testName = [[svgPath lastPathComponent] stringByDeletingPathExtension];
- NSString *imageName, *imageDirectory, *imagePath;
-
- // first look in ../png/test.png -- SVG 1.1 baselines
- // The SVG 1.1 spec has various different pngs, we should allow the
- // tester to choose...
- imageName = [[@"full-" stringByAppendingString:testName] stringByAppendingPathExtension:@"png"];
- imageDirectory = [parentDirectory stringByAppendingPathComponent:@"png"];
- imagePath = [imageDirectory stringByAppendingPathComponent:imageName];
- if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath]) return imagePath;
-
- // then look for ../name.png -- openclipart.org
- imageName = [testName stringByAppendingPathExtension:@"png"];
- imageDirectory = parentDirectory;
- imagePath = [imageDirectory stringByAppendingPathComponent:imageName];
- if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath]) return imagePath;
-
- // then look for ./name-w3c.png -- WebCore tests
- imageName = [[testName stringByAppendingString:@"-w3c"] stringByAppendingPathExtension:@"png"];
- imageDirectory = currentDirectory;
- imagePath = [imageDirectory stringByAppendingPathComponent:imageName];
- if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath]) return imagePath;
-
- // finally try name-baseline.png -- ksvg regression baselines
- imageName = [[testName stringByAppendingString:@"-baseline"] stringByAppendingPathExtension:@"png"];
- imageDirectory = currentDirectory;
- imagePath = [imageDirectory stringByAppendingPathComponent:imageName];
- if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath]) return imagePath;
-
- return nil;
-}
-
-- (NSArray *)tests
-{
- if (!_tests) {
- NSMutableArray *newTests = [[NSMutableArray alloc] init];
- NSArray *files = [[NSFileManager defaultManager] directoryContentsAtPath:[self currentPath]];
- NSString *file = nil;
- foreacharray(file, files) {
- if ([[file pathExtension] isEqualToString:@"svg"]) {
- NSString *svgPath = [[self currentPath] stringByAppendingPathComponent:file];
- NSString *imagePath = [self imagePathForSVGPath:svgPath];
- [newTests addObject:[SVGTest testWithSVGPath:svgPath imagePath:imagePath]];
- }
- }
- [self setValue:newTests forKey:@"tests"];
- }
- return _tests;
-}
-
-- (NSArray *)directoryHierarchy
-{
- // A hackish way to reverse an array.
- return [[[_currentPath pathComponents] reverseObjectEnumerator] allObjects];
-}
-
-- (NSString *)currentPath
-{
- return _currentPath;
-}
-
-- (void)setCurrentPath:(NSString *)newPath
-{
- if (![newPath isEqualToString:_currentPath]) {
- [_currentPath release];
- _currentPath = [newPath copy];
- [self setValue:nil forKey:@"tests"];
- }
-
- [[NSUserDefaults standardUserDefaults] setObject:_currentPath forKey:@"TestDirectory"];
-}
-
-- (IBAction)toggleViewersScaleRule:(id)sender
-{
-#if 0
- if ([_drawView imageScaling] == NSScaleProportionally) {
- [_drawView setImageScaling:NSScaleNone];
- [_imageView setImageScaling:NSScaleNone];
- } else {
- [_drawView setImageScaling:NSScaleProportionally];
- [_imageView setImageScaling:NSScaleProportionally];
- }
-#endif
-}
-
-@end
diff --git a/WebKitTools/DrawTest/TestViewerSplitView.h b/WebKitTools/DrawTest/TestViewerSplitView.h
deleted file mode 100644
index e663f23..0000000
--- a/WebKitTools/DrawTest/TestViewerSplitView.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-#import <Cocoa/Cocoa.h>
-
-@interface TestViewerSplitView : NSView {
- NSMutableArray *subviewLabels;
-}
-
-@end
diff --git a/WebKitTools/DrawTest/TestViewerSplitView.m b/WebKitTools/DrawTest/TestViewerSplitView.m
deleted file mode 100644
index 96f2055..0000000
--- a/WebKitTools/DrawTest/TestViewerSplitView.m
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-#import "TestViewerSplitView.h"
-
-@implementation TestViewerSplitView
-
-- (void)drawRect:(NSRect)rect
-{
- NSArray *subviews = [self subviews];
- int subviewCount = [subviews count];
- for (int x=0; x < subviewCount; x++) {
- NSView *subview = [subviews objectAtIndex:x];
- [subview drawRect:rect];
-#if 0
- NSString *label = [subviewLabels objectAtIndex:0];
- [label drawAtPoint:[subview frame].origin withAttributes:NULL];
-#endif
- }
-}
-
-- (void)retileSubviews
-{
- NSRect bounds = [self bounds];
- NSArray *subviews = [self subviews];
- int subviewCount = [subviews count];
- if (!subviewCount) return;
- float subviewWidth = bounds.size.width / subviewCount;
-
- for (int x=0; x < subviewCount; x++) {
- [[subviews objectAtIndex:x] setFrame:NSMakeRect(x * subviewWidth, 0, subviewWidth, bounds.size.height)];
- }
-}
-
-- (void)didAddSubview:(NSView *)subview
-{
- [super didAddSubview:subview];
- [self retileSubviews];
-}
-
-- (void)willRemoveSubview:(NSView *)subview
-{
- [super willRemoveSubview:subview];
- [self retileSubviews];
-}
-
-- (void)setFrame:(NSRect)newFrame
-{
- // ideally we also want to catch when the bounds changes without the
- // frame changing, but we're not bothering with that now - ECS 7/29/05
- [super setFrame:newFrame];
- [self retileSubviews];
-}
-
-@end
diff --git a/WebKitTools/DrawTest/main.m b/WebKitTools/DrawTest/main.m
deleted file mode 100644
index 90337b6..0000000
--- a/WebKitTools/DrawTest/main.m
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, 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 COMPUTER, 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 COMPUTER, 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.
- */
-
-int main (int argc, const char *argv[])
-{
- return NSApplicationMain(argc, argv);
-}
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
index 0537d7c..c2393c3 100644
--- a/WebKitTools/DumpRenderTree/LayoutTestController.cpp
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
@@ -465,26 +465,34 @@ static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function,
return JSValueMakeUndefined(context);
}
-static JSValueRef pageNumberForElementByIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+static bool parsePageParameters(JSContextRef context, int argumentCount, const JSValueRef* arguments, JSValueRef* exception, float& pageWidthInPixels, float& pageHeightInPixels)
{
// FIXME: These values should sync with maxViewWidth/Height in
// DumpRenderTree.mm. Factor these values out to somewhere.
- float pageWidthInPixels = 800;
- float pageHeightInPixels = 600;
+ pageWidthInPixels = 800;
+ pageHeightInPixels = 600;
switch (argumentCount) {
- case 1:
- break;
- case 3:
- pageWidthInPixels = static_cast<float>(JSValueToNumber(context, arguments[1], exception));
+ case 2:
+ pageWidthInPixels = static_cast<float>(JSValueToNumber(context, arguments[0], exception));
if (*exception)
- return JSValueMakeUndefined(context);
- pageHeightInPixels = static_cast<float>(JSValueToNumber(context, arguments[2], exception));
+ return false;
+ pageHeightInPixels = static_cast<float>(JSValueToNumber(context, arguments[1], exception));
if (*exception)
- return JSValueMakeUndefined(context);
+ return false;
+ case 0: // Fall through.
break;
default:
- return JSValueMakeUndefined(context);
+ return false;
}
+ return true;
+}
+
+static JSValueRef pageNumberForElementByIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ float pageWidthInPixels = 0;
+ float pageHeightInPixels = 0;
+ if (!parsePageParameters(context, argumentCount - 1, arguments + 1, exception, pageWidthInPixels, pageHeightInPixels))
+ return JSValueMakeUndefined(context);
JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
if (*exception)
@@ -495,6 +503,17 @@ static JSValueRef pageNumberForElementByIdCallback(JSContextRef context, JSObjec
return JSValueMakeNumber(context, pageNumber);
}
+static JSValueRef numberOfPagesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ float pageWidthInPixels = 0;
+ float pageHeightInPixels = 0;
+ if (!parsePageParameters(context, argumentCount, arguments, exception, pageWidthInPixels, pageHeightInPixels))
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ return JSValueMakeNumber(context, controller->numberOfPages(pageWidthInPixels, pageHeightInPixels));
+}
+
static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
// Has mac & windows implementation
@@ -897,6 +916,18 @@ static JSValueRef setXSSAuditorEnabledCallback(JSContextRef context, JSObjectRef
return JSValueMakeUndefined(context);
}
+static JSValueRef setFrameSetFlatteningEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Has mac & windows implementation
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(context);
+
+ LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+ controller->setFrameSetFlatteningEnabled(JSValueToBoolean(context, arguments[0]));
+
+ return JSValueMakeUndefined(context);
+}
+
static JSValueRef setAllowUniversalAccessFromFileURLsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
// Has mac & windows implementation
@@ -1329,6 +1360,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
{ "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "numberOfPages", numberOfPagesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "numberOfActiveAnimations", numberOfActiveAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "overridePreference", overridePreferenceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -1373,6 +1405,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
{ "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { "setFrameSetFlatteningEnabled", setFrameSetFlatteningEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setSelectTrailingWhitespaceEnabled", setSelectTrailingWhitespaceEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setSmartInsertDeleteEnabled", setSmartInsertDeleteEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.h b/WebKitTools/DumpRenderTree/LayoutTestController.h
index 76e7cb3..5f9df50 100644
--- a/WebKitTools/DumpRenderTree/LayoutTestController.h
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.h
@@ -56,6 +56,7 @@ public:
bool isCommandEnabled(JSStringRef name);
void keepWebHistory();
void notifyDone();
+ int numberOfPages(float pageWidthInPixels, float pageHeightInPixels);
void overridePreference(JSStringRef key, JSStringRef value);
int pageNumberForElementById(JSStringRef id, float pageWidthInPixels, float pageHeightInPixels);
JSStringRef pathToLocalResource(JSContextRef, JSStringRef url);
@@ -89,6 +90,7 @@ public:
void setUserStyleSheetEnabled(bool flag);
void setUserStyleSheetLocation(JSStringRef path);
void setXSSAuditorEnabled(bool flag);
+ void setFrameSetFlatteningEnabled(bool enable);
void waitForPolicyDelegate();
size_t webHistoryItemCount();
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp
index fa8aed1..e69da73 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp
@@ -133,6 +133,7 @@ enum {
ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM,
ID_PROPERTY_PRIVATE_BROWSING_ENABLED,
ID_PROPERTY_CACHED_PRIVATE_BROWSING_ENABLED,
+ ID_PROPERTY_THROW_EXCEPTION_PROPERTY,
NUM_PROPERTY_IDENTIFIERS
};
@@ -146,6 +147,7 @@ static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
"returnErrorFromNewStream",
"privateBrowsingEnabled",
"cachedPrivateBrowsingEnabled",
+ "testThrowExceptionProperty"
};
enum {
@@ -172,6 +174,8 @@ enum {
ID_DESTROY_NULL_STREAM,
ID_TEST_RELOAD_PLUGINS_NO_PAGES,
ID_TEST_RELOAD_PLUGINS_AND_PAGES,
+ ID_TEST_GET_BROWSER_PROPERTY,
+ ID_TEST_SET_BROWSER_PROPERTY,
NUM_METHOD_IDENTIFIERS
};
@@ -199,7 +203,9 @@ static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
"testFail",
"destroyNullStream",
"reloadPluginsNoPages",
- "reloadPluginsAndPages"
+ "reloadPluginsAndPages",
+ "testGetBrowserProperty",
+ "testSetBrowserProperty"
};
static NPUTF8* createCStringFromNPVariant(const NPVariant* variant)
@@ -264,6 +270,9 @@ static bool pluginGetProperty(NPObject* obj, NPIdentifier name, NPVariant* resul
} else if (name == pluginPropertyIdentifiers[ID_PROPERTY_CACHED_PRIVATE_BROWSING_ENABLED]) {
BOOLEAN_TO_NPVARIANT(plugin->cachedPrivateBrowsingMode, *result);
return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
+ browser->setexception(obj, "plugin object testThrowExceptionProperty SUCCESS");
+ return true;
}
return false;
}
@@ -280,6 +289,9 @@ static bool pluginSetProperty(NPObject* obj, NPIdentifier name, const NPVariant*
} else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
plugin->returnErrorFromNewStream = NPVARIANT_TO_BOOLEAN(*variant);
return true;
+ } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
+ browser->setexception(obj, "plugin object testThrowExceptionProperty SUCCESS");
+ return true;
}
return false;
@@ -789,6 +801,12 @@ static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* a
} else if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_AND_PAGES]) {
browser->reloadplugins(true);
return true;
+ } else if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) {
+ browser->getproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVariantToIdentifier(args[1]), result);
+ return true;
+ } else if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) {
+ browser->setproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVariantToIdentifier(args[1]), &args[2]);
+ return true;
}
return false;
diff --git a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp
index 5883ffb..8ef228a 100644
--- a/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp
+++ b/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp
@@ -119,8 +119,9 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, ch
NPBool supportsCocoa = false;
#ifndef NP_NO_CARBON
+ // A browser that doesn't know about NPNVsupportsCarbonBool is one that only supports Carbon event model.
if (browser->getvalue(instance, NPNVsupportsCarbonBool, &supportsCarbon) != NPERR_NO_ERROR)
- supportsCarbon = false;
+ supportsCarbon = true;
#endif
if (browser->getvalue(instance, NPNVsupportsCocoaBool, &supportsCocoa) != NPERR_NO_ERROR)
diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
index bad09fb..422e2c2 100644
--- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
@@ -55,6 +55,7 @@ void webkit_application_cache_set_maximum_size(unsigned long long size);
unsigned int webkit_worker_thread_count(void);
void webkit_white_list_access_from_origin(const gchar* sourceOrigin, const gchar* destinationProtocol, const gchar* destinationHost, bool allowDestinationSubdomains);
gchar* webkit_web_frame_counter_value_for_element_by_id(WebKitWebFrame* frame, const gchar* id);
+int webkit_web_frame_page_number_for_element_by_id(WebKitWebFrame* frame, const gchar* id, float pageWidth, float pageHeight);
void webkit_web_inspector_execute_script(WebKitWebInspector* inspector, long callId, const gchar* script);
}
@@ -140,7 +141,15 @@ void LayoutTestController::keepWebHistory()
// FIXME: implement
}
-int LayoutTestController::pageNumberForElementById(JSStringRef, float, float)
+int LayoutTestController::pageNumberForElementById(JSStringRef id, float pageWidth, float pageHeight)
+{
+ gchar* idGChar = JSStringCopyUTF8CString(id);
+ int pageNumber = webkit_web_frame_page_number_for_element_by_id(mainFrame, idGChar, pageWidth, pageHeight);
+ g_free(idGChar);
+ return pageNumber;
+}
+
+int LayoutTestController::numberOfPages(float, float)
{
// FIXME: implement
return -1;
@@ -325,6 +334,11 @@ void LayoutTestController::setXSSAuditorEnabled(bool flag)
g_object_set(G_OBJECT(settings), "enable-xss-auditor", flag, NULL);
}
+void LayoutTestController::setFrameSetFlatteningEnabled(bool flag)
+{
+ // FIXME: implement
+}
+
void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool flag)
{
WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame);
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
index 12e1941..7a4429b 100644
--- a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
@@ -421,8 +421,8 @@ static void resetDefaultsToConsistentValues()
[preferences setJavaScriptCanOpenWindowsAutomatically:YES];
[preferences setOfflineWebApplicationCacheEnabled:YES];
[preferences setDeveloperExtrasEnabled:NO];
- [preferences setXSSAuditorEnabled:NO];
[preferences setLoadsImagesAutomatically:YES];
+ [preferences setFrameSetFlatteningEnabled:NO];
if (persistentUserStyleSheetLocation) {
[preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]];
[preferences setUserStyleSheetEnabled:YES];
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
index 67c8c91..b726e72 100644
--- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -188,6 +188,11 @@ int LayoutTestController::pageNumberForElementById(JSStringRef id, float pageWid
return [mainFrame pageNumberForElement:element:pageWidthInPixels:pageHeightInPixels];
}
+int LayoutTestController::numberOfPages(float pageWidthInPixels, float pageHeightInPixels)
+{
+ return [mainFrame numberOfPages:pageWidthInPixels:pageHeightInPixels];
+}
+
size_t LayoutTestController::webHistoryItemCount()
{
return [[[WebHistory optionalSharedHistory] allItems] count];
@@ -319,6 +324,11 @@ void LayoutTestController::setXSSAuditorEnabled(bool enabled)
[[[mainFrame webView] preferences] setXSSAuditorEnabled:enabled];
}
+void LayoutTestController::setFrameSetFlatteningEnabled(bool enabled)
+{
+ [[[mainFrame webView] preferences] setFrameSetFlatteningEnabled:enabled];
+}
+
void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled)
{
[[[mainFrame webView] preferences] setAllowUniversalAccessFromFileURLs:enabled];
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
index ca48003..51c1181 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
@@ -37,7 +37,9 @@
#include <qwebsettings.h>
extern void qt_dump_editing_callbacks(bool b);
+extern void qt_dump_frame_loader(bool b);
extern void qt_dump_resource_load_callbacks(bool b);
+extern void qt_drt_setFrameSetFlatteningEnabled(QWebPage*, bool);
extern void qt_drt_setJavaScriptProfilingEnabled(QWebFrame*, bool enabled);
extern bool qt_drt_pauseAnimation(QWebFrame*, const QString& name, double time, const QString& elementId);
extern bool qt_drt_pauseTransitionOfProperty(QWebFrame*, const QString& name, double time, const QString& elementId);
@@ -48,6 +50,7 @@ extern void qt_drt_setDomainRelaxationForbiddenForURLScheme(bool forbidden, cons
extern void qt_drt_whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains);
extern QString qt_drt_counterValueForElementById(QWebFrame* qFrame, const QString& id);
extern int qt_drt_workerThreadCount();
+extern int qt_drt_pageNumberForElementById(QWebFrame* qFrame, const QString& id, float width, float height);
LayoutTestController::LayoutTestController(WebCore::DumpRenderTree* drt)
: QObject()
@@ -75,6 +78,7 @@ void LayoutTestController::reset()
m_webHistory = 0;
m_globalFlag = false;
qt_dump_editing_callbacks(false);
+ qt_dump_frame_loader(false);
qt_dump_resource_load_callbacks(false);
emit hidePage();
}
@@ -201,6 +205,11 @@ void LayoutTestController::dumpEditingCallbacks()
qt_dump_editing_callbacks(true);
}
+void LayoutTestController::dumpFrameLoadCallbacks()
+{
+ qt_dump_frame_loader(true);
+}
+
void LayoutTestController::dumpResourceLoadCallbacks()
{
qt_dump_resource_load_callbacks(true);
@@ -287,6 +296,11 @@ void LayoutTestController::hideWebInspector()
m_drt->webPage()->webInspector()->hide();
}
+void LayoutTestController::setFrameSetFlatteningEnabled(bool enabled)
+{
+ qt_drt_setFrameSetFlatteningEnabled(m_drt->webPage(), enabled);
+}
+
void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled)
{
m_drt->webPage()->settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, enabled);
@@ -421,6 +435,9 @@ void LayoutTestController::overridePreference(const QString& name, const QVarian
settings->setFontSize(QWebSettings::DefaultFontSize, value.toInt());
else if (name == "WebKitUsesPageCachePreferenceKey")
QWebSettings::setMaximumPagesInCache(value.toInt());
+ else
+ printf("ERROR: LayoutTestController::overridePreference() does not support the '%s' preference\n",
+ name.toLatin1().data());
}
void LayoutTestController::setUserStyleSheetLocation(const QString& url)
@@ -445,3 +462,14 @@ int LayoutTestController::workerThreadCount()
{
return qt_drt_workerThreadCount();
}
+
+int LayoutTestController::pageNumberForElementById(const QString& id, float width, float height)
+{
+ // If no size specified, webpage viewport size is used
+ if (!width && !height) {
+ width = m_drt->webPage()->viewportSize().width();
+ height = m_drt->webPage()->viewportSize().height();
+ }
+
+ return qt_drt_pageNumberForElementById(m_drt->webPage()->mainFrame(), id, width, height);
+}
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
index 365640d..64cbcc9 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
@@ -96,6 +96,7 @@ public slots:
void setGlobalFlag(bool flag) { m_globalFlag = flag; }
void handleErrorPages() { m_handleErrorPages = true; }
void dumpEditingCallbacks();
+ void dumpFrameLoadCallbacks();
void dumpResourceLoadCallbacks();
void queueBackNavigation(int howFarBackward);
void queueForwardNavigation(int howFarForward);
@@ -115,6 +116,8 @@ public slots:
void dumpSelectionRect() const {}
void showWebInspector();
void hideWebInspector();
+
+ void setFrameSetFlatteningEnabled(bool enable);
void setAllowUniversalAccessFromFileURLs(bool enable);
void setJavaScriptProfilingEnabled(bool enable);
void setFixedContentsSize(int width, int height);
@@ -146,6 +149,7 @@ public slots:
void setUserStyleSheetEnabled(bool enabled);
void setDomainRelaxationForbiddenForURLScheme(bool forbidden, const QString& scheme);
int workerThreadCount();
+ int pageNumberForElementById(const QString& id, float width = 0, float height = 0);
private slots:
void processWork();
diff --git a/WebKitTools/DumpRenderTree/qt/main.cpp b/WebKitTools/DumpRenderTree/qt/main.cpp
index 69d3c23..efcda57 100644
--- a/WebKitTools/DumpRenderTree/qt/main.cpp
+++ b/WebKitTools/DumpRenderTree/qt/main.cpp
@@ -48,6 +48,11 @@
#include <fontconfig/fontconfig.h>
#endif
+#ifdef Q_OS_WIN
+#include <io.h>
+#include <fcntl.h>
+#endif
+
#include <limits.h>
#include <signal.h>
@@ -101,6 +106,11 @@ static NO_RETURN void crashHandler(int sig)
int main(int argc, char* argv[])
{
+#ifdef Q_OS_WIN
+ _setmode(1, _O_BINARY);
+ _setmode(2, _O_BINARY);
+#endif
+
#ifdef Q_WS_X11
FcInit();
WebCore::DumpRenderTree::initializeFonts();
diff --git a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
index 1315f9e..261b9e6 100644
--- a/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
+++ b/WebKitTools/DumpRenderTree/win/DumpRenderTree.cpp
@@ -792,6 +792,7 @@ static void resetDefaultsToConsistentValues(IWebPreferences* preferences)
prefsPrivate->setExperimentalNotificationsEnabled(TRUE);
prefsPrivate->setShouldPaintNativeControls(FALSE); // FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592>
prefsPrivate->setXSSAuditorEnabled(FALSE);
+ prefsPrivate->setFrameSetFlatteningEnabled(FALSE);
prefsPrivate->setOfflineWebApplicationCacheEnabled(TRUE);
}
setAlwaysAcceptCookies(false);
diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
index 4f5e925..34fd2e6 100644
--- a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
@@ -372,6 +372,23 @@ void LayoutTestController::setXSSAuditorEnabled(bool enabled)
prefsPrivate->setXSSAuditorEnabled(enabled);
}
+void LayoutTestController::setFrameSetFlatteningEnabled(bool enabled)
+{
+ COMPtr<IWebView> webView;
+ if (FAILED(frame->webView(&webView)))
+ return;
+
+ COMPtr<IWebPreferences> preferences;
+ if (FAILED(webView->preferences(&preferences)))
+ return;
+
+ COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
+ if (!prefsPrivate)
+ return;
+
+ prefsPrivate->setFrameSetFlatteningEnabled(enabled);
+}
+
void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled)
{
COMPtr<IWebView> webView;
@@ -1109,3 +1126,9 @@ int LayoutTestController::pageNumberForElementById(JSStringRef, float, float)
// FIXME: implement
return -1;
}
+
+int LayoutTestController::numberOfPages(float, float)
+{
+ // FIXME: implement
+ return -1;
+}
diff --git a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
index 82b1d4d..08a2f6a 100644
--- a/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
+++ b/WebKitTools/DumpRenderTree/win/TestNetscapePlugin/main.cpp
@@ -71,6 +71,19 @@ NPError __stdcall NP_Shutdown()
return NPERR_NO_ERROR;
}
+static void executeScript(const PluginObject* object, const char* script)
+{
+ NPObject *windowScriptObject;
+ browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
+
+ NPString npScript;
+ npScript.UTF8Characters = script;
+ npScript.UTF8Length = strlen(script);
+
+ NPVariant browserResult;
+ browser->evaluate(object->npp, windowScriptObject, &npScript, &browserResult);
+ browser->releasevariantvalue(&browserResult);
+}
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved)
{
@@ -84,6 +97,8 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, ch
obj->onStreamDestroy = _strdup(argv[i]);
else if (_stricmp(argn[i], "onURLNotify") == 0 && !obj->onURLNotify)
obj->onURLNotify = _strdup(argv[i]);
+ else if (_stricmp(argn[i], "onDestroy") == 0 && !obj->onDestroy)
+ obj->onDestroy = _strdup(argv[i]);
else if (_stricmp(argn[i], "logSrc") == 0) {
for (int i = 0; i < argc; i++)
if (_stricmp(argn[i], "src") == 0)
@@ -113,6 +128,11 @@ NPError NPP_Destroy(NPP instance, NPSavedData **save)
if (obj->onStreamDestroy)
free(obj->onStreamDestroy);
+ if (obj->onDestroy) {
+ executeScript(obj, obj->onDestroy);
+ free(obj->onDestroy);
+ }
+
if (obj->logDestroy)
printf("PLUGIN: NPP_Destroy\n");
@@ -135,20 +155,6 @@ NPError NPP_SetWindow(NPP instance, NPWindow *window)
return NPERR_NO_ERROR;
}
-static void executeScript(const PluginObject* obj, const char* script)
-{
- NPObject *windowScriptObject;
- browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
-
- NPString npScript;
- npScript.UTF8Characters = script;
- npScript.UTF8Length = strlen(script);
-
- NPVariant browserResult;
- browser->evaluate(obj->npp, windowScriptObject, &npScript, &browserResult);
- browser->releasevariantvalue(&browserResult);
-}
-
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
{
PluginObject* obj = (PluginObject*)instance->pdata;
diff --git a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
index 6d3b624..3bc84cd 100644
--- a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
+++ b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
@@ -170,6 +170,11 @@ void LayoutTestController::setXSSAuditorEnabled(bool enabled)
// FIXME: implement
}
+void LayoutTestController::setFrameSetFlatteningEnabled(bool enabled)
+{
+ // FIXME: implement
+}
+
void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled)
{
// FIXME: implement
@@ -365,3 +370,9 @@ int LayoutTestController::pageNumberForElementById(JSStringRef, float, float)
// FIXME: implement
return -1;
}
+
+int LayoutTestController::numberOfPages(float, float)
+{
+ // FIXME: implement
+ return -1;
+} \ No newline at end of file
diff --git a/WebKitTools/QtLauncher/QtLauncher.pro b/WebKitTools/QtLauncher/QtLauncher.pro
index e448f69..7dcc8e4 100644
--- a/WebKitTools/QtLauncher/QtLauncher.pro
+++ b/WebKitTools/QtLauncher/QtLauncher.pro
@@ -24,6 +24,8 @@ DESTDIR = ../../bin
include(../../WebKit.pri)
+INCLUDEPATH += ../../JavaScriptCore
+
QT += network
macx:QT+=xml
QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR
diff --git a/WebKitTools/QtLauncher/main.cpp b/WebKitTools/QtLauncher/main.cpp
index 31bca8e..c725c2f 100644
--- a/WebKitTools/QtLauncher/main.cpp
+++ b/WebKitTools/QtLauncher/main.cpp
@@ -70,6 +70,14 @@
void QWEBKIT_EXPORT qt_drt_garbageCollector_collect();
#endif
+
+static bool gUseGraphicsView = false;
+static bool gUseCompositing = false;
+static bool gCacheWebView = false;
+static bool gShowFrameRate = false;
+static QGraphicsView::ViewportUpdateMode gViewportUpdateMode = QGraphicsView::MinimalViewportUpdate;
+
+
class LauncherWindow : public MainWindow {
Q_OBJECT
@@ -85,8 +93,6 @@ public:
bool eventFilter(QObject* obj, QEvent* event);
#endif
- QWebView* webView() const { return view; }
-
protected slots:
void loadStarted();
void loadFinished();
@@ -109,6 +115,8 @@ protected slots:
void selectElements();
void setTouchMocking(bool on);
+ void toggleAcceleratedCompositing(bool toggle);
+ void initializeView(bool useGraphicsView = false);
public slots:
void newWindow(const QString& url = QString());
@@ -121,7 +129,7 @@ private:
QVector<int> zoomLevels;
int currentZoom;
- QWebView* view;
+ QWidget* m_view;
WebInspector* inspector;
QAction* formatMenuAction;
@@ -140,14 +148,15 @@ LauncherWindow::LauncherWindow(QString url)
QSplitter* splitter = new QSplitter(Qt::Vertical, this);
setCentralWidget(splitter);
- view = new WebViewTraditional(splitter);
- view->setPage(page());
-
-#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
- view->installEventFilter(this);
- touchMocking = false;
+#if defined(Q_WS_S60)
+ showMaximized();
+#else
+ resize(800, 600);
#endif
+ m_view = 0;
+ initializeView();
+
connect(page(), SIGNAL(loadStarted()), this, SLOT(loadStarted()));
connect(page(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
connect(page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)),
@@ -238,7 +247,7 @@ void LauncherWindow::sendTouchEvent()
bool LauncherWindow::eventFilter(QObject* obj, QEvent* event)
{
- if (!touchMocking || obj != view)
+ if (!touchMocking || obj != m_view)
return QObject::eventFilter(obj, event);
if (event->type() == QEvent::MouseButtonPress
@@ -290,7 +299,7 @@ bool LauncherWindow::eventFilter(QObject* obj, QEvent* event)
touchPoint.setState(Qt::TouchPointPressed);
touchPoint.setId(1);
touchPoint.setScreenPos(QCursor::pos());
- touchPoint.setPos(view->mapFromGlobal(QCursor::pos()));
+ touchPoint.setPos(m_view->mapFromGlobal(QCursor::pos()));
touchPoint.setPressure(1);
touchPoints.append(touchPoint);
sendTouchEvent();
@@ -305,7 +314,7 @@ bool LauncherWindow::eventFilter(QObject* obj, QEvent* event)
void LauncherWindow::loadStarted()
{
- view->setFocus(Qt::OtherFocusReason);
+ m_view->setFocus(Qt::OtherFocusReason);
}
void LauncherWindow::loadFinished()
@@ -362,14 +371,14 @@ void LauncherWindow::print()
#if !defined(QT_NO_PRINTER)
QPrintPreviewDialog dlg(this);
connect(&dlg, SIGNAL(paintRequested(QPrinter*)),
- view, SLOT(print(QPrinter*)));
+ m_view, SLOT(print(QPrinter*)));
dlg.exec();
#endif
}
void LauncherWindow::screenshot()
{
- QPixmap pixmap = QPixmap::grabWidget(view);
+ QPixmap pixmap = QPixmap::grabWidget(m_view);
QLabel* label = new QLabel;
label->setAttribute(Qt::WA_DeleteOnClose);
label->setWindowTitle("Screenshot - Preview");
@@ -385,7 +394,7 @@ void LauncherWindow::screenshot()
void LauncherWindow::setEditable(bool on)
{
- view->page()->setContentEditable(on);
+ page()->setContentEditable(on);
formatMenuAction->setVisible(on);
}
@@ -429,6 +438,38 @@ void LauncherWindow::setTouchMocking(bool on)
#endif
}
+void LauncherWindow::toggleAcceleratedCompositing(bool toggle)
+{
+ page()->settings()->setAttribute(QWebSettings::AcceleratedCompositingEnabled, toggle);
+}
+
+void LauncherWindow::initializeView(bool useGraphicsView)
+{
+ delete m_view;
+
+ QSplitter* splitter = static_cast<QSplitter*>(centralWidget());
+
+ if (!useGraphicsView) {
+ WebViewTraditional* view = new WebViewTraditional(splitter);
+ view->setPage(page());
+ m_view = view;
+ } else {
+ WebViewGraphicsBased* view = new WebViewGraphicsBased(splitter);
+ view->setPage(page());
+ view->setViewportUpdateMode(gViewportUpdateMode);
+ view->setItemCacheMode(gCacheWebView ? QGraphicsItem::DeviceCoordinateCache : QGraphicsItem::NoCache);
+ if (gShowFrameRate)
+ view->enableFrameRateMeasurement();
+ page()->settings()->setAttribute(QWebSettings::AcceleratedCompositingEnabled, gUseCompositing);
+ m_view = view;
+ }
+
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ m_view->installEventFilter(this);
+ touchMocking = false;
+#endif
+}
+
void LauncherWindow::newWindow(const QString& url)
{
LauncherWindow* mw = new LauncherWindow(url);
@@ -459,8 +500,8 @@ void LauncherWindow::setupUI()
setEditable->setCheckable(true);
QMenu* viewMenu = menuBar()->addMenu("&View");
- viewMenu->addAction(view->pageAction(QWebPage::Stop));
- viewMenu->addAction(view->pageAction(QWebPage::Reload));
+ viewMenu->addAction(page()->action(QWebPage::Stop));
+ viewMenu->addAction(page()->action(QWebPage::Reload));
viewMenu->addSeparator();
QAction* zoomIn = viewMenu->addAction("Zoom &In", this, SLOT(zoomIn()));
QAction* zoomOut = viewMenu->addAction("Zoom &Out", this, SLOT(zoomOut()));
@@ -498,11 +539,21 @@ void LauncherWindow::setupUI()
touchMockAction->setCheckable(true);
touchMockAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_T));
#endif
+
+ QAction* toggleAcceleratedCompositing = toolsMenu->addAction("Toggle Accelerated Compositing", this, SLOT(toggleAcceleratedCompositing(bool)));
+ toggleAcceleratedCompositing->setCheckable(true);
+ toggleAcceleratedCompositing->setChecked(false);
+
+ QAction* toggleGraphicsView = toolsMenu->addAction("Toggle use of QGraphicsView", this, SLOT(initializeView(bool)));
+ toggleGraphicsView->setCheckable(true);
+ toggleGraphicsView->setChecked(false);
}
-QWebPage* WebPage::createWindow(QWebPage::WebWindowType)
+QWebPage* WebPage::createWindow(QWebPage::WebWindowType type)
{
LauncherWindow* mw = new LauncherWindow;
+ if (type == WebModalDialog)
+ mw->setWindowModality(Qt::ApplicationModal);
mw->show();
return mw->page();
}
@@ -549,9 +600,6 @@ private:
void handleUserOptions();
void applyDefaultSettings();
- QList<QString> enumToKeys(const QMetaObject o, const QString& name, const QString& strip);
- QString formatKeys(QList<QString> keys);
-
private:
bool m_isRobotized;
QStringList m_urls;
@@ -582,36 +630,11 @@ LauncherApplication::LauncherApplication(int& argc, char** argv)
handleUserOptions();
}
-QString LauncherApplication::formatKeys(QList<QString> keys)
-{
- QString result;
- for (int i = 0; i < keys.count() - 1; i++)
- result.append(keys.at(i) + "|");
- result.append(keys.last());
- return result;
-}
-
-QList<QString> LauncherApplication::enumToKeys(const QMetaObject o, const QString& name, const QString& strip)
-{
- QList<QString> list;
-
- int enumIndex = o.indexOfEnumerator(name.toLatin1().data());
- QMetaEnum enumerator = o.enumerator(enumIndex);
-
- if (enumerator.isValid()) {
- for (int i = 0; i < enumerator.keyCount(); i++) {
- QString key(enumerator.valueToKey(i));
- list.append(key.remove(strip));
- }
- }
-
- return list;
-}
-
-static void fail(const QString& errorMsg)
+static void requiresGraphicsView(const QString& option)
{
- qDebug() << "ERROR:" << errorMsg.toLatin1().data();
- exit(1);
+ if (gUseGraphicsView)
+ return;
+ appQuit(1, QString("%1 only works in combination with the -graphicsbased option").arg(option));
}
void LauncherApplication::handleUserOptions()
@@ -625,56 +648,62 @@ void LauncherApplication::handleUserOptions()
QList<QString> updateModes(enumToKeys(QGraphicsView::staticMetaObject,
"ViewportUpdateMode", "ViewportUpdate"));
- if (args.contains("--help")) {
+ if (args.contains("-help")) {
qDebug() << "Usage:" << programName.toLatin1().data()
- << "[--graphicsbased]"
- << "[--compositing]"
- << QString("[--viewport-update-mode %1]").arg(formatKeys(updateModes)).toLatin1().data()
- << "[--cache-webview]"
+ << "[-graphicsbased]"
+ << "[-compositing]"
+ << QString("[-viewport-update-mode %1]").arg(formatKeys(updateModes)).toLatin1().data()
+ << "[-cache-webview]"
+ << "[-show-fps]"
<< "[-r list]"
<< "URLs";
- exit(0);
+ appQuit(0);
}
- bool useGraphicsView = false;
+ if (args.contains("-graphicsbased"))
+ gUseGraphicsView = true;
- if (args.contains("--graphicsbased"))
- useGraphicsView = true;
+ if (args.contains("-compositing")) {
+ requiresGraphicsView("-compositing");
+ gUseCompositing = true;
+ }
- if (args.contains("--compositing") && useGraphicsView)
- QWebSettings::globalSettings()->setAttribute(QWebSettings::AcceleratedCompositingEnabled, true);
+ if (args.contains("-show-fps")) {
+ requiresGraphicsView("-show-fps");
+ gShowFrameRate = true;
+ }
- if (args.contains("--cache-webview") && useGraphicsView)
- ; // view->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+ if (args.contains("-cache-webview")) {
+ requiresGraphicsView("-cache-webview");
+ gCacheWebView = true;
+ }
- int modeIndex = args.indexOf("--viewport-update-mode");
- if (modeIndex != -1 && ++modeIndex < args.count() && !args.at(modeIndex).startsWith("-")) {
- QString mode = args.takeAt(modeIndex);
- if (useGraphicsView) {
- int idx = updateModes.indexOf(mode);
- if (idx != -1) {
- ; // view->setViewportUpdateMode(static_cast<QGraphicsView::ViewportUpdateMode>(idx));
- } else {
- fail(QString("--viewport-update-mode value has to be one of [%1]")
- .arg(formatKeys(updateModes)).toLatin1().data());
- }
- }
+ QString arg1("-viewport-update-mode");
+ int modeIndex = args.indexOf(arg1);
+ if (modeIndex != -1) {
+ requiresGraphicsView(arg1);
+
+ QString mode = takeOptionValue(&args, modeIndex);
+ if (mode.isEmpty())
+ appQuit(1, QString("%1 needs a value of one of [%2]").arg(arg1).arg(formatKeys(updateModes)));
+ int idx = updateModes.indexOf(mode);
+ if (idx == -1)
+ appQuit(1, QString("%1 value has to be one of [%2]").arg(arg1).arg(formatKeys(updateModes)));
+
+ gViewportUpdateMode = static_cast<QGraphicsView::ViewportUpdateMode>(idx);
}
int robotIndex = args.indexOf("-r");
if (robotIndex != -1) {
- if (++robotIndex < args.count() && !args.at(robotIndex).startsWith("-")) {
- QString listFile = args.takeAt(robotIndex);
- if (!QFile::exists(listFile))
- fail(QString("The list file supplied to -r does not exist."));
- else {
- m_isRobotized = true;
- m_urls = QStringList(listFile);
- return;
- }
- }
- else
- fail(QString("-r needs a list file to start in robotized mode"));
+ QString listFile = takeOptionValue(&args, robotIndex);
+ if (listFile.isEmpty())
+ appQuit(1, "-r needs a list file to start in robotized mode");
+ if (!QFile::exists(listFile))
+ appQuit(1, "The list file supplied to -r does not exist.");
+
+ m_isRobotized = true;
+ m_urls = QStringList(listFile);
+ return;
}
int lastArg = args.lastIndexOf(QRegExp("^-.*"));
@@ -687,10 +716,9 @@ int main(int argc, char **argv)
LauncherApplication app(argc, argv);
if (app.isRobotized()) {
- LauncherWindow* window = new LauncherWindow;
- QWebView* view = window->webView();
- UrlLoader loader(view->page()->mainFrame(), app.urls().at(0));
- QObject::connect(view->page()->mainFrame(), SIGNAL(loadFinished(bool)), &loader, SLOT(loadNext()));
+ LauncherWindow* window = new LauncherWindow();
+ UrlLoader loader(window->page()->mainFrame(), app.urls().at(0));
+ QObject::connect(window->page()->mainFrame(), SIGNAL(loadFinished(bool)), &loader, SLOT(loadNext()));
loader.loadNext();
window->show();
return launcherMain(app);
diff --git a/WebKitTools/QtLauncher/mainwindow.cpp b/WebKitTools/QtLauncher/mainwindow.cpp
index 2662f5e..47755ec 100644
--- a/WebKitTools/QtLauncher/mainwindow.cpp
+++ b/WebKitTools/QtLauncher/mainwindow.cpp
@@ -50,6 +50,9 @@ MainWindow::MainWindow(const QString& url)
void MainWindow::buildUI()
{
QToolBar* bar = addToolBar("Navigation");
+#if defined(Q_WS_S60)
+ bar->setIconSize(QSize(16, 16));
+#endif
bar->addAction(page()->action(QWebPage::Back));
bar->addAction(page()->action(QWebPage::Forward));
bar->addAction(page()->action(QWebPage::Reload));
@@ -61,7 +64,12 @@ void MainWindow::buildUI()
QCompleter* completer = new QCompleter(this);
urlEdit->setCompleter(completer);
completer->setModel(&urlModel);
+#if defined(Q_WS_S60)
+ addToolBarBreak();
+ addToolBar("Location")->addWidget(urlEdit);
+#else
bar->addWidget(urlEdit);
+#endif
connect(page()->mainFrame(), SIGNAL(titleChanged(const QString&)),
this, SLOT(setWindowTitle(const QString&)));
diff --git a/WebKitTools/QtLauncher/utils.cpp b/WebKitTools/QtLauncher/utils.cpp
index 7013f46..2d45dd0 100644
--- a/WebKitTools/QtLauncher/utils.cpp
+++ b/WebKitTools/QtLauncher/utils.cpp
@@ -27,6 +27,54 @@
#include "utils.h"
+
+QString takeOptionValue(QStringList* arguments, int index)
+{
+ QString result;
+
+ if (++index < arguments->count() && !arguments->at(index).startsWith("-"))
+ result = arguments->takeAt(index);
+
+ return result;
+}
+
+QString formatKeys(QList<QString> keys)
+{
+ QString result;
+ for (int i = 0; i < keys.count() - 1; i++)
+ result.append(keys.at(i) + "|");
+ result.append(keys.last());
+ return result;
+}
+
+QList<QString> enumToKeys(const QMetaObject o, const QString& name, const QString& strip)
+{
+ QList<QString> list;
+
+ int enumIndex = o.indexOfEnumerator(name.toLatin1().data());
+ QMetaEnum enumerator = o.enumerator(enumIndex);
+
+ if (enumerator.isValid()) {
+ for (int i = 0; i < enumerator.keyCount(); i++) {
+ QString key(enumerator.valueToKey(i));
+ list.append(key.remove(strip));
+ }
+ }
+
+ return list;
+}
+
+void appQuit(int exitCode, const QString& msg)
+{
+ if (!msg.isEmpty()) {
+ if (exitCode > 0)
+ qDebug("ERROR: %s", msg.toLatin1().data());
+ else
+ qDebug() << msg;
+ }
+ exit(exitCode);
+}
+
QUrl urlFromUserInput(const QString& string)
{
QString input(string);
@@ -40,3 +88,5 @@ QUrl urlFromUserInput(const QString& string)
return QUrl(input);
#endif
}
+
+
diff --git a/WebKitTools/QtLauncher/utils.h b/WebKitTools/QtLauncher/utils.h
index afe771e..9a16067 100644
--- a/WebKitTools/QtLauncher/utils.h
+++ b/WebKitTools/QtLauncher/utils.h
@@ -28,8 +28,17 @@
#ifndef utils_h
#define utils_h
+#include <wtf/AlwaysInline.h>
+
#include <QtCore>
+// options handling
+QString takeOptionValue(QStringList* arguments, int index);
+QString formatKeys(QList<QString> keys);
+QList<QString> enumToKeys(const QMetaObject o, const QString& name, const QString& strip);
+
+NO_RETURN void appQuit(int status, const QString& msg = QString());
+
QUrl urlFromUserInput(const QString& input);
#endif
diff --git a/WebKitTools/QtLauncher/webview.cpp b/WebKitTools/QtLauncher/webview.cpp
index d08da4c..443fc3e 100644
--- a/WebKitTools/QtLauncher/webview.cpp
+++ b/WebKitTools/QtLauncher/webview.cpp
@@ -33,6 +33,64 @@
#include "webview.h"
#include <QtGui>
+#include <QGraphicsScene>
+
+WebViewGraphicsBased::WebViewGraphicsBased(QWidget* parent)
+ : QGraphicsView(parent)
+ , m_item(new GraphicsWebView)
+ , m_numPaintsTotal(0)
+ , m_numPaintsSinceLastMeasure(0)
+ , m_measureFps(false)
+{
+ setScene(new QGraphicsScene(this));
+ scene()->addItem(m_item);
+
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+}
+
+void WebViewGraphicsBased::resizeEvent(QResizeEvent* event)
+{
+ QGraphicsView::resizeEvent(event);
+ QRectF rect(QPoint(0, 0), event->size());
+ m_item->setGeometry(rect);
+}
+
+void WebViewGraphicsBased::enableFrameRateMeasurement()
+{
+ m_measureFps = true;
+ m_lastConsultTime = m_startTime = QTime::currentTime();
+ QTimer* updateTimer = new QTimer(this);
+ updateTimer->setInterval(1000);
+ connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateFrameRate()));
+ updateTimer->start();
+}
+
+void WebViewGraphicsBased::updateFrameRate()
+{
+ QTime now = QTime::currentTime();
+
+ int interval = m_lastConsultTime.msecsTo(now);
+ int total = m_startTime.msecsTo(now);
+
+ int average = total ? m_numPaintsTotal * 1000 / total : 0;
+ int current = interval ? m_numPaintsSinceLastMeasure * 1000 / interval : 0;
+
+ qDebug("[FPS] average: %d, current: %d", average, current);
+
+ m_lastConsultTime = now;
+ m_numPaintsSinceLastMeasure = 0;
+}
+
+void WebViewGraphicsBased::paintEvent(QPaintEvent* event)
+{
+ QGraphicsView::paintEvent(event);
+ if (!m_measureFps)
+ return;
+ m_numPaintsSinceLastMeasure++;
+ m_numPaintsTotal++;
+}
static QMenu* createContextMenu(QWebPage* page, QPoint position)
{
@@ -49,7 +107,7 @@ static QMenu* createContextMenu(QWebPage* page, QPoint position)
return menu;
}
-void WebViewGraphicsBased::mousePressEvent(QGraphicsSceneMouseEvent* event)
+void GraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
setProperty("mouseButtons", QVariant::fromValue(int(event->buttons())));
setProperty("keyboardModifiers", QVariant::fromValue(int(event->modifiers())));
@@ -65,7 +123,7 @@ void WebViewTraditional::mousePressEvent(QMouseEvent* event)
QWebView::mousePressEvent(event);
}
-void WebViewGraphicsBased::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
+void GraphicsWebView::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
{
QMenu* menu = createContextMenu(page(), event->pos().toPoint());
menu->exec(mapToScene(event->pos()).toPoint());
diff --git a/WebKitTools/QtLauncher/webview.h b/WebKitTools/QtLauncher/webview.h
index 68f220e..83bd801 100644
--- a/WebKitTools/QtLauncher/webview.h
+++ b/WebKitTools/QtLauncher/webview.h
@@ -36,27 +36,56 @@
#include "webpage.h"
#include <qwebview.h>
#include <qgraphicswebview.h>
+#include <QGraphicsView>
+#include <QGraphicsWidget>
+#include <QTime>
-class WebViewGraphicsBased : public QGraphicsWebView {
+class WebViewTraditional : public QWebView {
+ Q_OBJECT
+
+public:
+ WebViewTraditional(QWidget* parent) : QWebView(parent) {}
+
+protected:
+ virtual void contextMenuEvent(QContextMenuEvent*);
+ virtual void mousePressEvent(QMouseEvent*);
+};
+
+
+class GraphicsWebView : public QGraphicsWebView {
Q_OBJECT
public:
- WebViewGraphicsBased(QGraphicsItem* parent = 0) : QGraphicsWebView(parent) {};
+ GraphicsWebView(QGraphicsItem* parent = 0) : QGraphicsWebView(parent) {};
protected:
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
virtual void mousePressEvent(QGraphicsSceneMouseEvent*);
};
-class WebViewTraditional : public QWebView {
+
+class WebViewGraphicsBased : public QGraphicsView {
Q_OBJECT
public:
- WebViewTraditional(QWidget* parent) : QWebView(parent) {}
+ WebViewGraphicsBased(QWidget* parent);
+ virtual void resizeEvent(QResizeEvent*);
+ void setPage(QWebPage* page) { m_item->setPage(page); }
+ void setItemCacheMode(QGraphicsItem::CacheMode mode) { m_item->setCacheMode(mode); }
-protected:
- virtual void contextMenuEvent(QContextMenuEvent*);
- virtual void mousePressEvent(QMouseEvent*);
+ void enableFrameRateMeasurement();
+ virtual void paintEvent(QPaintEvent* event);
+
+public slots:
+ void updateFrameRate();
+
+private:
+ GraphicsWebView* m_item;
+ int m_numPaintsTotal;
+ int m_numPaintsSinceLastMeasure;
+ QTime m_startTime;
+ QTime m_lastConsultTime;
+ bool m_measureFps;
};
#endif
diff --git a/WebKitTools/Scripts/build-webkit b/WebKitTools/Scripts/build-webkit
index 8171fba..5ae1aae 100755
--- a/WebKitTools/Scripts/build-webkit
+++ b/WebKitTools/Scripts/build-webkit
@@ -36,6 +36,7 @@ use FindBin;
use Getopt::Long qw(:config pass_through);
use lib $FindBin::Bin;
use webkitdirs;
+use webkitperl::features;
use POSIX;
sub formatBuildTime($);
@@ -52,7 +53,7 @@ my $startTime = time();
my ($threeDCanvasSupport, $threeDRenderingSupport, $channelMessagingSupport, $clientBasedGeolocationSupport, $databaseSupport, $datagridSupport, $datalistSupport,
$domStorageSupport, $eventsourceSupport, $filtersSupport, $geolocationSupport, $iconDatabaseSupport, $indexedDatabaseSupport,
- $javaScriptDebuggerSupport, $mathmlSupport, $offlineWebApplicationSupport, $sharedWorkersSupport,
+ $javaScriptDebuggerSupport, $mathmlSupport, $offlineWebApplicationSupport, $rubySupport, $sharedWorkersSupport,
$svgSupport, $svgAnimationSupport, $svgAsImageSupport, $svgDOMObjCBindingsSupport, $svgFontsSupport,
$svgForeignObjectSupport, $svgUseSupport, $videoSupport, $webSocketsSupport, $wmlSupport, $wcssSupport, $xhtmlmpSupport, $workersSupport,
$xpathSupport, $xsltSupport, $coverageSupport, $notificationsSupport);
@@ -112,6 +113,9 @@ my @features = (
{ option => "offline-web-applications", desc => "Toggle Offline Web Application Support",
define => "ENABLE_OFFLINE_WEB_APPLICATIONS", default => 1, value => \$offlineWebApplicationSupport },
+ { option => "ruby", desc => "Toggle HTML5 Ruby support",
+ define => "ENABLE_RUBY", default => 1, value => \$rubySupport },
+
{ option => "shared-workers", desc => "Toggle SharedWorkers support",
define => "ENABLE_SHARED_WORKERS", default => (isAppleWebKit() || isGtk()), value => \$sharedWorkersSupport },
@@ -169,6 +173,9 @@ if (isQt()) {
}
}
+# Additional environment parameters
+push @ARGV, split(/ /, $ENV{'BUILD_WEBKIT_ARGS'}) if ($ENV{'BUILD_WEBKIT_ARGS'});
+
# Initialize values from defaults
foreach (@ARGV) {
if ($_ eq '--minimal') {
@@ -316,7 +323,7 @@ if (isGtk()) {
}
# Force re-link of existing libraries if different than expected
-removeLibraryDependingOnSVG("WebCore", $svgSupport);
+removeLibraryDependingOnFeature("WebCore", "SVG", $svgSupport);
if (isInspectorFrontend()) {
exit exitStatus(copyInspectorFrontendFiles());
diff --git a/WebKitTools/Scripts/check-for-global-initializers b/WebKitTools/Scripts/check-for-global-initializers
index a74f57d..cf83048 100755
--- a/WebKitTools/Scripts/check-for-global-initializers
+++ b/WebKitTools/Scripts/check-for-global-initializers
@@ -107,7 +107,7 @@ for my $file (sort @files) {
next if $shortName eq "Node.o";
next if $shortName eq "Page.o";
next if $shortName eq "Range.o";
- next if $shortName eq "RenderBlockLineLayout.o";
+ next if $shortName eq "BidiRun.o";
next if $shortName eq "RenderObject.o";
next if $shortName eq "SubresourceLoader.o";
next if $shortName eq "SVGElementInstance.o";
diff --git a/WebKitTools/Scripts/check-for-weak-vtables b/WebKitTools/Scripts/check-for-weak-vtables-and-externals
index a10a236..a3dc364 100755
--- a/WebKitTools/Scripts/check-for-weak-vtables
+++ b/WebKitTools/Scripts/check-for-weak-vtables-and-externals
@@ -1,6 +1,6 @@
#!/usr/bin/perl
-# Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+# Copyright (C) 2006, 2007, 2008, 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
@@ -11,7 +11,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,10 +26,10 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# "check-for-weak-vtables" script for WebKit Open Source Project
+# "check-for-weak-vtables-and-externals" script for WebKit Open Source Project
# Intended to be invoked from an Xcode build step to check if there are
-# any weak vtables in a target.
+# any weak vtables or weak externals in a target.
use warnings;
use strict;
@@ -63,18 +63,27 @@ if (!defined $executablePathAge || !defined $buildTimestampAge || $executablePat
next;
}
my @weakVTableClasses = ();
+ my @weakExternalSymbols = ();
while (<NM>) {
if (/^STDOUT:/) {
- push @weakVTableClasses, $1 if /weak external vtable for (.*)$/;
+ # Ignore undefined, RTTI and typeinfo symbols.
+ next if /\bundefined\b/ or /\b__ZT[IS]/;
+
+ if (/weak external vtable for (.*)$/) {
+ push @weakVTableClasses, $1;
+ } elsif (/weak external (.*)$/) {
+ push @weakExternalSymbols, $1;
+ }
} else {
print STDERR if $_ ne "nm: no name list\n";
}
}
close NM;
- if (@weakVTableClasses) {
- my $shortName = $executablePath;
- $shortName =~ s/.*\///;
+ my $shortName = $executablePath;
+ $shortName =~ s/.*\///;
+
+ if (@weakVTableClasses) {
print "ERROR: $shortName has a weak vtable in it ($executablePath)\n";
print "ERROR: Fix by making sure the first virtual function in each of these classes is not an inline:\n";
for my $class (sort @weakVTableClasses) {
@@ -82,6 +91,16 @@ if (!defined $executablePathAge || !defined $buildTimestampAge || $executablePat
}
$sawError = 1;
}
+
+ if (@weakExternalSymbols) {
+ print "ERROR: $shortName has a weak external symbol in it ($executablePath)\n";
+ print "ERROR: A weak external symbol is generated when a symbol is defined in multiple compilation units and is also marked as being exported from the library.\n";
+ print "ERROR: A common cause of weak external symbols is when an inline function is listed in the linker export file.\n";
+ for my $symbol (sort @weakExternalSymbols) {
+ print "ERROR: symbol $symbol\n";
+ }
+ $sawError = 1;
+ }
}
if ($sawError and !$coverageBuild) {
diff --git a/WebKitTools/Scripts/rebaseline-chromium-webkit-tests b/WebKitTools/Scripts/rebaseline-chromium-webkit-tests
index 9a8a156..aea0edc 100755
--- a/WebKitTools/Scripts/rebaseline-chromium-webkit-tests
+++ b/WebKitTools/Scripts/rebaseline-chromium-webkit-tests
@@ -11,7 +11,7 @@
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
-# * Neither the Chromium name nor the names of its
+# * 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.
#
diff --git a/WebKitTools/Scripts/run-chromium-webkit-tests b/WebKitTools/Scripts/run-chromium-webkit-tests
index 9c027b8..221b5aa 100755
--- a/WebKitTools/Scripts/run-chromium-webkit-tests
+++ b/WebKitTools/Scripts/run-chromium-webkit-tests
@@ -11,7 +11,7 @@
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
-# * Neither the Chromium name nor the names of its
+# * 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.
#
@@ -33,6 +33,7 @@ import sys
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),
"webkitpy", "layout_tests"))
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))))
import run_chromium_webkit_tests
if __name__ == '__main__':
diff --git a/WebKitTools/Scripts/run-drawtest b/WebKitTools/Scripts/run-drawtest
deleted file mode 100755
index 2cd61de..0000000
--- a/WebKitTools/Scripts/run-drawtest
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/perl -w
-
-# Copyright (C) 2005 Apple Computer, 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.
-
-# Simplified "run" script for WebKit Open Source Project.
-
-use strict;
-use FindBin;
-use lib $FindBin::Bin;
-use webkitdirs;
-
-setConfiguration();
-my $productDir = productDir();
-
-# Check to see that all the frameworks are built (w/ SVG support).
-checkFrameworks();
-checkWebCoreSVGSupport(1);
-
-# Set up DYLD_FRAMEWORK_PATH to point to the product directory.
-print "Start DrawTest with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
-$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
-my $drawtestPath = "$productDir/DrawTest.app/Contents/MacOS/DrawTest";
-exec $drawtestPath or die;
diff --git a/WebKitTools/Scripts/run-iexploder-tests b/WebKitTools/Scripts/run-iexploder-tests
index 1b3976f..7f2f04f 100755
--- a/WebKitTools/Scripts/run-iexploder-tests
+++ b/WebKitTools/Scripts/run-iexploder-tests
@@ -101,9 +101,13 @@ sub runSafariWithIExploder()
print REDIRECT_HTML "</html>\n";
close REDIRECT_HTML;
- local %ENV;
- $ENV{DYLD_INSERT_LIBRARIES} = "/usr/lib/libgmalloc.dylib" if $guardMalloc;
- system "WebKitTools/Scripts/run-safari", "-NSOpen", "$iExploderTestDirectory/redirect.html";
+ if (!isAppleWebKit()) {
+ system "WebKitTools/Scripts/run-launcher", "$iExploderTestDirectory/redirect.html";
+ } else {
+ local %ENV;
+ $ENV{DYLD_INSERT_LIBRARIES} = "/usr/lib/libgmalloc.dylib" if $guardMalloc;
+ system "WebKitTools/Scripts/run-safari", "-NSOpen", "$iExploderTestDirectory/redirect.html";
+ }
}
sub configureAndOpenHTTPDIfNeeded()
@@ -114,8 +118,9 @@ sub configureAndOpenHTTPDIfNeeded()
my $webkitDirectory = getcwd();
my $testDirectory = $webkitDirectory . "/LayoutTests";
my $iExploderDirectory = $webkitDirectory . "/WebKitTools/iExploder";
- my $httpdConfig = "$testDirectory/http/conf/httpd.conf";
- $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+
+ my $httpdConfig = getHTTPDConfigPathForTestDirectory($testDirectory);
+
my $documentRoot = "$iExploderDirectory/htdocs";
my $typesConfig = "$testDirectory/http/conf/mime.types";
my $sslCertificate = "$testDirectory/http/conf/webkit-httpd.pem";
diff --git a/WebKitTools/Scripts/run-webkit-tests b/WebKitTools/Scripts/run-webkit-tests
index 6b21e48..809e078 100755
--- a/WebKitTools/Scripts/run-webkit-tests
+++ b/WebKitTools/Scripts/run-webkit-tests
@@ -67,6 +67,7 @@ use Time::HiRes qw(time usleep);
use List::Util 'shuffle';
use lib $FindBin::Bin;
+use webkitperl::features;
use webkitperl::httpd;
use webkitdirs;
use VCSUtils;
@@ -154,9 +155,15 @@ my $treatSkipped = "default";
my $useRemoteLinksToTests = 0;
my $useValgrind = 0;
my $verbose = 0;
+my $shouldWaitForHTTPD = 0;
my @leaksFilenames;
+if (isWindows() || isMsys()) {
+ print "This script has to be run under Cygwin to function correctly.\n";
+ exit 1;
+}
+
# Default to --no-http for wx for now.
$testHTTP = 0 if (isWx());
@@ -224,6 +231,7 @@ Usage: $programName [options] [testdir|testpath ...]
--exit-after-n-failures N Exit after the first N failures instead of running all tests
-h|--help Show this help message
--[no-]http Run (or do not run) http tests (default: $httpDefault)
+ --[no-]wait-for-httpd Wait for httpd if some other test session is using it already (same as WEBKIT_WAIT_FOR_HTTPD=1). (default: $shouldWaitForHTTPD)
-i|--ignore-tests Comma-separated list of directories or tests to ignore
--iterations n Number of times to run the set of tests (e.g. ABCABCABC)
--[no-]launch-safari Launch (or do not launch) Safari to display test results (default: $launchSafariDefault)
@@ -267,6 +275,7 @@ my $getOptionsResult = GetOptions(
'guard-malloc|g' => \$guardMalloc,
'help|h' => \$showHelp,
'http!' => \$testHTTP,
+ 'wait-for-httpd!' => \$shouldWaitForHTTPD,
'ignore-metrics!' => \$ignoreMetrics,
'ignore-tests|i=s' => \$ignoreTests,
'iterations=i' => \$iterations,
@@ -308,6 +317,8 @@ my $skippedOnly = $treatSkipped eq "only";
my $configuration = configuration();
+# We need an environment variable to be able to enable the feature per-slave
+$shouldWaitForHTTPD = $ENV{"WEBKIT_WAIT_FOR_HTTPD"} unless ($shouldWaitForHTTPD);
$verbose = 1 if $testsPerDumpTool == 1;
if ($shouldCheckLeaks && $testsPerDumpTool > 1000) {
@@ -410,12 +421,12 @@ my %ignoredDirectories = map { $_ => 1 } qw(platform);
my %ignoredLocalDirectories = map { $_ => 1 } qw(.svn _svn resources script-tests);
my %supportedFileExtensions = map { $_ => 1 } qw(html shtml xml xhtml pl php);
-if (!checkWebCoreMathMLSupport(0)) {
+if (!checkWebCoreFeatureSupport("MathML", 0)) {
$ignoredDirectories{'mathml'} = 1;
}
-# FIXME: We should fix webkitdirs.pm:hasSVG/WMLSupport() to do the correct feature detection for Cygwin.
-if (checkWebCoreSVGSupport(0)) {
+# FIXME: We should fix webkitperl/features.pm:hasFeature() to do the correct feature detection for Cygwin.
+if (checkWebCoreFeatureSupport("SVG", 0)) {
$supportedFileExtensions{'svg'} = 1;
} elsif (isCygwin()) {
$supportedFileExtensions{'svg'} = 1;
@@ -433,20 +444,20 @@ if (!$testMedia) {
$ignoredDirectories{'http/tests/media'} = 1;
}
-if (!checkWebCoreAcceleratedCompositingSupport(0)) {
+if (!checkWebCoreFeatureSupport("Accelerated Compositing", 0)) {
$ignoredDirectories{'compositing'} = 1;
}
-if (!checkWebCore3DRenderingSupport(0)) {
+if (!checkWebCoreFeatureSupport("3D Rendering", 0)) {
$ignoredDirectories{'animations/3d'} = 1;
$ignoredDirectories{'transforms/3d'} = 1;
}
-if (!checkWebCore3DCanvasSupport(0)) {
+if (!checkWebCoreFeatureSupport("3D Canvas", 0)) {
$ignoredDirectories{'fast/canvas/webgl'} = 1;
}
-if (checkWebCoreWMLSupport(0)) {
+if (checkWebCoreFeatureSupport("WML", 0)) {
$supportedFileExtensions{'wml'} = 1;
} else {
$ignoredDirectories{'http/tests/wml'} = 1;
@@ -454,14 +465,10 @@ if (checkWebCoreWMLSupport(0)) {
$ignoredDirectories{'wml'} = 1;
}
-if (!checkWebCoreXHTMLMPSupport(0)) {
+if (!checkWebCoreFeatureSupport("XHTMLMP", 0)) {
$ignoredDirectories{'fast/xhtmlmp'} = 1;
}
-if (!checkWebCoreWCSSSupport(0)) {
- $ignoredDirectories{'fast/wcss'} = 1;
-}
-
processIgnoreTests($ignoreTests, "ignore-tests") if $ignoreTests;
if (!$ignoreSkipped) {
if (!$skippedOnly || @ARGV == 0) {
@@ -943,7 +950,14 @@ for my $test (@tests) {
}
}
}
-printf "\n%0.2fs total testing time\n", (time - $overallStartTime) . "";
+my $totalTestingTime = time - $overallStartTime;
+my $waitTime = getWaitTime();
+if ($waitTime > 0.1) {
+ my $normalizedTestingTime = $totalTestingTime - $waitTime;
+ printf "\n%0.2fs HTTPD waiting time\n", $waitTime . "";
+ printf "%0.2fs normalized testing time", $normalizedTestingTime . "";
+}
+printf "\n%0.2fs total testing time\n", $totalTestingTime . "";
!$isDumpToolOpen || die "Failed to close $dumpToolName.\n";
@@ -1360,6 +1374,7 @@ sub configureAndOpenHTTPDIfNeeded()
my @defaultArgs = getDefaultConfigForTestDirectory($testDirectory);
@args = (@defaultArgs, @args);
+ waitForHTTPDLock() if $shouldWaitForHTTPD;
$isHttpdOpen = openHTTPD(@args);
}
@@ -1383,6 +1398,7 @@ sub openWebSocketServerIfNeeded()
"-d", "$webSocketHandlerDir",
"-s", "$webSocketHandlerScanDir",
"-m", "$webSocketHandlerMapFile",
+ "-x", "/websocket/tests/cookies",
"-l", "$logFile",
"--strict",
);
diff --git a/WebKitTools/Scripts/run-webkit-websocketserver b/WebKitTools/Scripts/run-webkit-websocketserver
index bbc5af6..64a724d 100755
--- a/WebKitTools/Scripts/run-webkit-websocketserver
+++ b/WebKitTools/Scripts/run-webkit-websocketserver
@@ -75,6 +75,7 @@ sub openWebSocketServer()
"-d", "$webSocketHandlerDir",
"-s", "$webSocketHandlerScanDir",
"-m", "$webSocketHandlerMapFile",
+ "-x", "/websocket/tests/cookies",
);
$ENV{"PYTHONPATH"} = $webSocketPythonPath;
diff --git a/WebKitTools/Scripts/test-webkitpy b/WebKitTools/Scripts/test-webkitpy
index ca58b50..cfd3434 100755
--- a/WebKitTools/Scripts/test-webkitpy
+++ b/WebKitTools/Scripts/test-webkitpy
@@ -43,6 +43,7 @@ from webkitpy.committers_unittest import *
from webkitpy.credentials_unittest import *
from webkitpy.diff_parser_unittest import *
from webkitpy.executive_unittest import *
+from webkitpy.grammar_unittest import *
from webkitpy.multicommandtool_unittest import *
from webkitpy.networktransaction_unittest import *
from webkitpy.patchcollection_unittest import *
@@ -51,6 +52,7 @@ from webkitpy.steps.steps_unittest import *
from webkitpy.steps.closebugforlanddiff_unittest import *
from webkitpy.steps.updatechangelogswithreview_unittests import *
from webkitpy.style.unittests import * # for check-webkit-style
+from webkitpy.user_unittest import *
from webkitpy.webkit_logging_unittest import *
from webkitpy.webkitport_unittest import *
diff --git a/WebKitTools/Scripts/build-drawtest b/WebKitTools/Scripts/webkit-build-directory
index fa9b7c2..a85c587 100755
--- a/WebKitTools/Scripts/build-drawtest
+++ b/WebKitTools/Scripts/webkit-build-directory
@@ -1,6 +1,6 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
-# Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (C) 2010 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -26,23 +26,40 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# Simplified build script for WebKit Open Source Project.
-# Modified copy of build-dumprendertree. Perhaps these could share code.
+# A script to expose WebKit's build directory detection logic to non-perl scripts.
-use strict;
use FindBin;
+use Getopt::Long;
+
use lib $FindBin::Bin;
use webkitdirs;
-checkRequiredSystemConfig();
-setConfiguration();
-chdirWebKit();
-my @options = XcodeOptions();
+my $showBaseProductDirectory = 0;
+my $showHelp = 0;
+
+my $programName = basename($0);
+my $usage = <<EOF;
+Usage: $programName [options]
+ --base Show the root build directory instead of one corresponding to the current target (e.g. Debug, Release)
+ --debug Show build directory for the Debug target
+ -h|--help Show this help message
+ --release Show build directory for the Release target
+EOF
+
+setConfiguration(); # Figure out from the command line if we're --debug or --release or the default.
+
+my $getOptionsResult = GetOptions(
+ 'base' => \$showBaseProductDirectory,
+ 'help|h' => \$showHelp,
+);
-# Check to see that all the frameworks are built (w/ SVG support).
-checkFrameworks();
-checkWebCoreSVGSupport(1);
+if (!$getOptionsResult || $showHelp) {
+ print STDERR $usage;
+ exit 1;
+}
-# Build
-chdir "WebKitTools/DrawTest" or die;
-exit system "xcodebuild", "-project", "DrawTest.xcodeproj", @options;
+if ($showBaseProductDirectory) {
+ print baseProductDir() . "\n";
+} else {
+ print productDir() . "\n";
+}
diff --git a/WebKitTools/Scripts/webkitdirs.pm b/WebKitTools/Scripts/webkitdirs.pm
index 8b2ecc1..a788b3d 100644
--- a/WebKitTools/Scripts/webkitdirs.pm
+++ b/WebKitTools/Scripts/webkitdirs.pm
@@ -573,222 +573,17 @@ sub builtDylibPathForName
}
# Check to see that all the frameworks are built.
-sub checkFrameworks
+sub checkFrameworks # FIXME: This is a poor name since only the Mac calls built WebCore a Framework.
{
return if isCygwin();
my @frameworks = ("JavaScriptCore", "WebCore");
- push(@frameworks, "WebKit") if isAppleMacWebKit();
+ push(@frameworks, "WebKit") if isAppleMacWebKit(); # FIXME: This seems wrong, all ports should have a WebKit these days.
for my $framework (@frameworks) {
my $path = builtDylibPathForName($framework);
die "Can't find built framework at \"$path\".\n" unless -e $path;
}
}
-sub libraryContainsSymbol
-{
- my $path = shift;
- my $symbol = shift;
-
- if (isCygwin() or isWindows()) {
- # FIXME: Implement this for Windows.
- return 0;
- }
-
- my $foundSymbol = 0;
- if (-e $path) {
- open NM, "-|", "nm", $path or die;
- while (<NM>) {
- $foundSymbol = 1 if /$symbol/;
- }
- close NM;
- }
- return $foundSymbol;
-}
-
-sub hasMathMLSupport
-{
- my $path = shift;
-
- return libraryContainsSymbol($path, "MathMLElement");
-}
-
-sub checkWebCoreMathMLSupport
-{
- my $required = shift;
- my $framework = "WebCore";
- my $path = builtDylibPathForName($framework);
- my $hasMathML = hasMathMLSupport($path);
- if ($required && !$hasMathML) {
- die "$framework at \"$path\" does not include MathML Support, please run build-webkit --mathml\n";
- }
- return $hasMathML;
-}
-
-sub hasSVGSupport
-{
- my $path = shift;
-
- if (isWx()) {
- return 0;
- }
-
- # We used to look for SVGElement but isSVGElement is a valid symbol in --no-svg builds.
- return libraryContainsSymbol($path, "SVGDefsElement");
-}
-
-sub removeLibraryDependingOnSVG
-{
- my $frameworkName = shift;
- my $shouldHaveSVG = shift;
-
- my $path = builtDylibPathForName($frameworkName);
- return unless -x $path;
-
- my $hasSVG = hasSVGSupport($path);
- system "rm -f $path" if ($shouldHaveSVG xor $hasSVG);
-}
-
-sub checkWebCoreSVGSupport
-{
- my $required = shift;
- my $framework = "WebCore";
- my $path = builtDylibPathForName($framework);
- my $hasSVG = hasSVGSupport($path);
- if ($required && !$hasSVG) {
- die "$framework at \"$path\" does not include SVG Support, please run build-webkit --svg\n";
- }
- return $hasSVG;
-}
-
-sub hasAcceleratedCompositingSupport
-{
- # On platforms other than Mac the Skipped files are used to skip compositing tests
- return 1 if !isAppleMacWebKit();
-
- my $path = shift;
- return libraryContainsSymbol($path, "GraphicsLayer");
-}
-
-sub checkWebCoreAcceleratedCompositingSupport
-{
- my $required = shift;
- my $framework = "WebCore";
- my $path = builtDylibPathForName($framework);
- my $hasAcceleratedCompositing = hasAcceleratedCompositingSupport($path);
- if ($required && !$hasAcceleratedCompositing) {
- die "$framework at \"$path\" does not use accelerated compositing\n";
- }
- return $hasAcceleratedCompositing;
-}
-
-sub has3DRenderingSupport
-{
- # On platforms other than Mac the Skipped files are used to skip 3D tests
- return 1 if !isAppleMacWebKit();
-
- my $path = shift;
- return libraryContainsSymbol($path, "WebCoreHas3DRendering");
-}
-
-sub checkWebCore3DRenderingSupport
-{
- my $required = shift;
- my $framework = "WebCore";
- my $path = builtDylibPathForName($framework);
- my $has3DRendering = has3DRenderingSupport($path);
- if ($required && !$has3DRendering) {
- die "$framework at \"$path\" does not include 3D rendering Support, please run build-webkit --3d-rendering\n";
- }
- return $has3DRendering;
-}
-
-sub has3DCanvasSupport
-{
- return 0 if isQt();
-
- my $path = shift;
- return libraryContainsSymbol($path, "WebGLShader");
-}
-
-sub checkWebCore3DCanvasSupport
-{
- my $required = shift;
- my $framework = "WebCore";
- my $path = builtDylibPathForName($framework);
- my $has3DCanvas = has3DCanvasSupport($path);
- if ($required && !$has3DCanvas) {
- die "$framework at \"$path\" does not include 3D Canvas Support, please run build-webkit --3d-canvas\n";
- }
- return $has3DCanvas;
-}
-
-sub hasWMLSupport
-{
- my $path = shift;
- return libraryContainsSymbol($path, "WMLElement");
-}
-
-sub removeLibraryDependingOnWML
-{
- my $frameworkName = shift;
- my $shouldHaveWML = shift;
-
- my $path = builtDylibPathForName($frameworkName);
- return unless -x $path;
-
- my $hasWML = hasWMLSupport($path);
- system "rm -f $path" if ($shouldHaveWML xor $hasWML);
-}
-
-sub checkWebCoreWMLSupport
-{
- my $required = shift;
- my $framework = "WebCore";
- my $path = builtDylibPathForName($framework);
- my $hasWML = hasWMLSupport($path);
- if ($required && !$hasWML) {
- die "$framework at \"$path\" does not include WML Support, please run build-webkit --wml\n";
- }
- return $hasWML;
-}
-
-sub hasXHTMLMPSupport
-{
- my $path = shift;
- return libraryContainsSymbol($path, "isXHTMLMPDocument");
-}
-
-sub checkWebCoreXHTMLMPSupport
-{
- my $required = shift;
- my $framework = "WebCore";
- my $path = builtDylibPathForName($framework);
- my $hasXHTMLMP = hasXHTMLMPSupport($path);
- if ($required && !$hasXHTMLMP) {
- die "$framework at \"$path\" does not include XHTML MP Support\n";
- }
- return $hasXHTMLMP;
-}
-
-sub hasWCSSSupport
-{
- # FIXME: When WCSS support is landed this should be updated to check for WCSS
- # being enabled in a manner similar to how we check for XHTML MP above.
- return 0;
-}
-
-sub checkWebCoreWCSSSupport
-{
- my $required = shift;
- my $framework = "WebCore";
- my $path = builtDylibPathForName($framework);
- my $hasWCSS = hasWCSSSupport($path);
- if ($required && !$hasWCSS) {
- die "$framework at \"$path\" does not include WCSS Support\n";
- }
- return $hasWCSS;
-}
-
sub isInspectorFrontend()
{
determineIsInspectorFrontend();
@@ -954,6 +749,11 @@ sub isWindows()
return ($^O eq "MSWin32") || 0;
}
+sub isMsys()
+{
+ return ($^O eq "msys") || 0;
+}
+
sub isLinux()
{
return ($^O eq "linux") || 0;
@@ -1107,7 +907,7 @@ sub determineWindowsSourceDir()
{
return if $windowsSourceDir;
my $sourceDir = sourceDir();
- chomp($windowsSourceDir = `cygpath -w $sourceDir`);
+ chomp($windowsSourceDir = `cygpath -w '$sourceDir'`);
}
sub windowsSourceDir()
@@ -1491,27 +1291,21 @@ sub buildQMakeProject($@)
my $dsMakefile = "Makefile.DerivedSources";
- print "Calling '$make $makeargs -f $dsMakefile generated_files' in " . $dir . "/JavaScriptCore\n\n";
- if ($make eq "nmake") {
- $result = system "pushd JavaScriptCore && $make $makeargs -f $dsMakefile generated_files && popd";
- } else {
- $result = system "$make $makeargs -C JavaScriptCore -f $dsMakefile generated_files";
- }
- if ($result ne 0) {
- die "Failed to generate JavaScriptCore's derived sources!\n";
- }
-
- print "Calling '$make $makeargs -f $dsMakefile generated_files' in " . $dir . "/WebCore\n\n";
- if ($make eq "nmake") {
- $result = system "pushd WebCore && $make $makeargs -f $dsMakefile generated_files && popd";
- } else {
- $result = system "$make $makeargs -C WebCore -f $dsMakefile generated_files";
- }
- if ($result ne 0) {
- die "Failed to generate WebCore's derived sources!\n";
+ # Iterate over different source directories manually to workaround a problem with qmake+extraTargets+s60
+ for my $subdir ("JavaScriptCore", "WebCore", "WebKit/qt/Api") {
+ print "Calling '$make $makeargs -f $dsMakefile generated_files' in " . $dir . "/$subdir\n\n";
+ if ($make eq "nmake") {
+ my $subdirWindows = $subdir;
+ $subdirWindows =~ s:/:\\:g;
+ $result = system "pushd $subdirWindows && $make $makeargs -f $dsMakefile generated_files && popd";
+ } else {
+ $result = system "$make $makeargs -C $subdir -f $dsMakefile generated_files";
+ }
+ if ($result ne 0) {
+ die "Failed to generate ${subdir}'s derived sources!\n";
+ }
}
-
push @buildArgs, "OUTPUT_DIR=" . baseProductDir() . "/$config";
push @buildArgs, sourceDir() . "/WebKit.pro";
if ($config =~ m/debug/i) {
diff --git a/WebKitTools/Scripts/webkitperl/features.pm b/WebKitTools/Scripts/webkitperl/features.pm
new file mode 100644
index 0000000..1f88022
--- /dev/null
+++ b/WebKitTools/Scripts/webkitperl/features.pm
@@ -0,0 +1,104 @@
+# Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved
+# Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+# Copyright (C) 2010 Andras Becsi (abecsi@inf.u-szeged.hu), University of Szeged
+#
+# 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.
+
+# Module to share code to detect the existance of features in built binaries.
+
+use strict;
+use warnings;
+
+BEGIN {
+ use Exporter ();
+ our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+ $VERSION = 1.00;
+ @ISA = qw(Exporter);
+ @EXPORT = qw(&checkWebCoreFeatureSupport
+ &removeLibraryDependingOnFeature);
+ %EXPORT_TAGS = ( );
+ @EXPORT_OK = ();
+}
+
+sub libraryContainsSymbol($$)
+{
+ my ($path, $symbol) = @_;
+
+ if (isCygwin() or isWindows()) {
+ # FIXME: Implement this for Windows.
+ return 0;
+ }
+
+ my $foundSymbol = 0;
+ if (-e $path) {
+ open NM, "-|", "nm", $path or die;
+ while (<NM>) {
+ $foundSymbol = 1 if /$symbol/; # FIXME: This should probably check for word boundaries before/after the symbol name.
+ }
+ close NM;
+ }
+ return $foundSymbol;
+}
+
+sub hasFeature($$)
+{
+ my ($featureName, $path) = @_;
+ my %symbolForFeature = (
+ "MathML" => "MathMLElement",
+ "SVG" => "SVGDefsElement", # We used to look for SVGElement but isSVGElement exists (and would match) in --no-svg builds.
+ "Accelerated Compositing" => "GraphicsLayer",
+ "3D Rendering" => "WebCoreHas3DRendering",
+ "3D Canvas" => "WebGLShader",
+ "WML" => "WMLElement",
+ "XHTMLMP" => "isXHTMLMPDocument",
+ );
+ my $symbolName = $symbolForFeature{$featureName};
+ die "Unknown feature: $featureName" unless $symbolName;
+ return libraryContainsSymbol($path, $symbolName);
+}
+
+sub checkWebCoreFeatureSupport($$)
+{
+ my ($feature, $required) = @_;
+ my $libraryName = "WebCore";
+ my $path = builtDylibPathForName($libraryName);
+ my $hasFeature = hasFeature($feature, $path);
+ if ($required && !$hasFeature) {
+ die "$libraryName at \"$path\" does not include $hasFeature support. See build-webkit --help\n";
+ }
+ return $hasFeature;
+}
+
+sub removeLibraryDependingOnFeature($$$)
+{
+ my ($libraryName, $featureName, $shouldHaveFeature) = @_;
+ my $path = builtDylibPathForName($libraryName);
+ return unless -x $path;
+
+ my $hasFeature = hasFeature($featureName, $path);
+ system "rm -f $path" if ($shouldHaveFeature xor $hasFeature);
+}
+
+1;
diff --git a/WebKitTools/Scripts/webkitperl/httpd.pm b/WebKitTools/Scripts/webkitperl/httpd.pm
index d082870..05eb21c 100644
--- a/WebKitTools/Scripts/webkitperl/httpd.pm
+++ b/WebKitTools/Scripts/webkitperl/httpd.pm
@@ -34,6 +34,7 @@ use warnings;
use File::Path;
use File::Spec;
use File::Spec::Functions;
+use Fcntl ':flock';
use IPC::Open2;
use webkitdirs;
@@ -43,20 +44,32 @@ BEGIN {
our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
$VERSION = 1.00;
@ISA = qw(Exporter);
- @EXPORT = qw(&getHTTPDPath &getDefaultConfigForTestDirectory &openHTTPD &closeHTTPD &getHTTPDPid &setShouldWaitForUserInterrupt);
+ @EXPORT = qw(&getHTTPDPath
+ &getHTTPDConfigPathForTestDirectory
+ &getDefaultConfigForTestDirectory
+ &openHTTPD
+ &closeHTTPD
+ &setShouldWaitForUserInterrupt
+ &waitForHTTPDLock
+ &getWaitTime);
%EXPORT_TAGS = ( );
@EXPORT_OK = ();
}
my $tmpDir = "/tmp";
+my $httpdLockPrefix = "WebKitHttpd.lock.";
+my $myLockFile;
+my $exclusiveLockFile = File::Spec->catfile($tmpDir, "WebKit.lock");
my $httpdPath;
my $httpdPidDir = File::Spec->catfile($tmpDir, "WebKit");
my $httpdPidFile = File::Spec->catfile($httpdPidDir, "httpd.pid");
my $httpdPid;
my $waitForUserInterrupt = 0;
+my $waitBeginTime;
+my $waitEndTime;
-$SIG{'INT'} = 'cleanup';
-$SIG{'TERM'} = 'cleanup';
+$SIG{'INT'} = 'handleInterrupt';
+$SIG{'TERM'} = 'handleInterrupt';
sub getHTTPDPath
{
@@ -73,24 +86,7 @@ sub getDefaultConfigForTestDirectory
my ($testDirectory) = @_;
die "No test directory has been specified." unless ($testDirectory);
- my $httpdConfig;
- getHTTPDPath();
- if (isCygwin()) {
- my $windowsConfDirectory = "$testDirectory/http/conf/";
- unless (-x "/usr/lib/apache/libphp4.dll") {
- copy("$windowsConfDirectory/libphp4.dll", "/usr/lib/apache/libphp4.dll");
- chmod(0755, "/usr/lib/apache/libphp4.dll");
- }
- $httpdConfig = "$windowsConfDirectory/cygwin-httpd.conf";
- } elsif (isDebianBased()) {
- $httpdConfig = "$testDirectory/http/conf/apache2-debian-httpd.conf";
- } elsif (isFedoraBased()) {
- $httpdConfig = "$testDirectory/http/conf/fedora-httpd.conf";
- } else {
- $httpdConfig = "$testDirectory/http/conf/httpd.conf";
- $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
- }
-
+ my $httpdConfig = getHTTPDConfigPathForTestDirectory($testDirectory);
my $documentRoot = "$testDirectory/http/tests";
my $jsTestResourcesDirectory = $testDirectory . "/fast/js/resources";
my $typesConfig = "$testDirectory/http/conf/mime.types";
@@ -119,6 +115,30 @@ sub getDefaultConfigForTestDirectory
}
+sub getHTTPDConfigPathForTestDirectory
+{
+ my ($testDirectory) = @_;
+ die "No test directory has been specified." unless ($testDirectory);
+ my $httpdConfig;
+ getHTTPDPath();
+ if (isCygwin()) {
+ my $windowsConfDirectory = "$testDirectory/http/conf/";
+ unless (-x "/usr/lib/apache/libphp4.dll") {
+ copy("$windowsConfDirectory/libphp4.dll", "/usr/lib/apache/libphp4.dll");
+ chmod(0755, "/usr/lib/apache/libphp4.dll");
+ }
+ $httpdConfig = "$windowsConfDirectory/cygwin-httpd.conf";
+ } elsif (isDebianBased()) {
+ $httpdConfig = "$testDirectory/http/conf/apache2-debian-httpd.conf";
+ } elsif (isFedoraBased()) {
+ $httpdConfig = "$testDirectory/http/conf/fedora-httpd.conf";
+ } else {
+ $httpdConfig = "$testDirectory/http/conf/httpd.conf";
+ $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+ }
+ return $httpdConfig;
+}
+
sub openHTTPD(@)
{
my (@args) = @_;
@@ -141,7 +161,10 @@ sub openHTTPD(@)
--$retryCount;
}
- die "Timed out waiting for httpd to quit" unless $retryCount;
+ if (!$retryCount) {
+ cleanUp();
+ die "Timed out waiting for httpd to quit";
+ }
}
}
@@ -156,7 +179,7 @@ sub openHTTPD(@)
}
if (!$retryCount) {
- rmtree $httpdPidDir;
+ cleanUp();
die "Timed out waiting for httpd to start";
}
@@ -172,20 +195,19 @@ sub openHTTPD(@)
sub closeHTTPD
{
close HTTPDIN;
+ my $retryCount = 20;
if ($httpdPid) {
kill 15, $httpdPid;
- my $retryCount = 20;
while (-f $httpdPidFile && $retryCount) {
sleep 1;
--$retryCount;
}
-
- if (!$retryCount) {
- print STDERR "Timed out waiting for httpd to terminate!\n";
- return 0;
- }
}
- rmdir $httpdPidDir;
+ cleanUp();
+ if (!$retryCount) {
+ print STDERR "Timed out waiting for httpd to terminate!\n";
+ return 0;
+ }
return 1;
}
@@ -194,9 +216,94 @@ sub setShouldWaitForUserInterrupt
$waitForUserInterrupt = 1;
}
-sub cleanup
+sub handleInterrupt
{
closeHTTPD();
print "\n";
exit(1);
}
+
+sub cleanUp
+{
+ rmdir $httpdPidDir;
+ unlink $exclusiveLockFile;
+ unlink $myLockFile if $myLockFile;
+}
+
+sub extractLockNumber
+{
+ my ($lockFile) = @_;
+ return -1 unless $lockFile;
+ return substr($lockFile, length($httpdLockPrefix));
+}
+
+sub getLockFiles
+{
+ opendir(TMPDIR, $tmpDir) or die "Could not open " . $tmpDir . ".";
+ my @lockFiles = grep {m/^$httpdLockPrefix\d+$/} readdir(TMPDIR);
+ @lockFiles = sort { extractLockNumber($a) <=> extractLockNumber($b) } @lockFiles;
+ closedir(TMPDIR);
+ return @lockFiles;
+}
+
+sub getNextAvailableLockNumber
+{
+ my @lockFiles = getLockFiles();
+ return 0 unless @lockFiles;
+ return extractLockNumber($lockFiles[-1]) + 1;
+}
+
+sub getLockNumberForCurrentRunning
+{
+ my @lockFiles = getLockFiles();
+ return 0 unless @lockFiles;
+ return extractLockNumber($lockFiles[0]);
+}
+
+sub waitForHTTPDLock
+{
+ $waitBeginTime = time;
+ scheduleHttpTesting();
+ # If we are the only one waiting for Apache just run the tests without any further checking
+ if (scalar getLockFiles() > 1) {
+ my $currentLockFile = File::Spec->catfile($tmpDir, "$httpdLockPrefix" . getLockNumberForCurrentRunning());
+ my $currentLockPid = <SCHEDULER_LOCK> if (-f $currentLockFile && open(SCHEDULER_LOCK, "<$currentLockFile"));
+ # Wait until we are allowed to run the http tests
+ while ($currentLockPid && $currentLockPid != $$) {
+ $currentLockFile = File::Spec->catfile($tmpDir, "$httpdLockPrefix" . getLockNumberForCurrentRunning());
+ if ($currentLockFile eq $myLockFile) {
+ $currentLockPid = <SCHEDULER_LOCK> if open(SCHEDULER_LOCK, "<$currentLockFile");
+ if ($currentLockPid != $$) {
+ print STDERR "\nPID mismatch.\n";
+ last;
+ }
+ } else {
+ sleep 1;
+ }
+ }
+ }
+ $waitEndTime = time;
+}
+
+sub scheduleHttpTesting
+{
+ # We need an exclusive lock file to avoid deadlocks and starvation and ensure that the scheduler lock numbers are sequential.
+ # The scheduler locks are used to schedule the running test sessions in first come first served order.
+ while (!(open(SEQUENTIAL_GUARD_LOCK, ">$exclusiveLockFile") && flock(SEQUENTIAL_GUARD_LOCK, LOCK_EX|LOCK_NB))) {}
+ $myLockFile = File::Spec->catfile($tmpDir, "$httpdLockPrefix" . getNextAvailableLockNumber());
+ open(SCHEDULER_LOCK, ">$myLockFile");
+ print SCHEDULER_LOCK "$$";
+ print SEQUENTIAL_GUARD_LOCK "$$";
+ close(SCHEDULER_LOCK);
+ close(SEQUENTIAL_GUARD_LOCK);
+ unlink $exclusiveLockFile;
+}
+
+sub getWaitTime
+{
+ my $waitTime = 0;
+ if ($waitBeginTime && $waitEndTime) {
+ $waitTime = $waitEndTime - $waitBeginTime;
+ }
+ return $waitTime;
+}
diff --git a/WebKitTools/Scripts/webkitpy/bugzilla.py b/WebKitTools/Scripts/webkitpy/bugzilla.py
index c1cf41d..4506af2 100644
--- a/WebKitTools/Scripts/webkitpy/bugzilla.py
+++ b/WebKitTools/Scripts/webkitpy/bugzilla.py
@@ -39,6 +39,7 @@ from datetime import datetime # used in timestamp()
from webkitpy.webkit_logging import error, log
from webkitpy.committers import CommitterList
from webkitpy.credentials import Credentials
+from webkitpy.user import User
# WebKit includes a built copy of BeautifulSoup in Scripts/webkitpy
# so this import should always succeed.
@@ -559,7 +560,7 @@ class Bugzilla(object):
for name in components:
i += 1
log("%2d. %s" % (i, name))
- result = int(raw_input("Enter a number: ")) - 1
+ result = int(User.prompt("Enter a number: ")) - 1
return components[result]
def _check_create_bug_response(self, response_html):
diff --git a/WebKitTools/Scripts/webkitpy/commands/upload.py b/WebKitTools/Scripts/webkitpy/commands/upload.py
index 8d23d8b..15bdfbb 100644
--- a/WebKitTools/Scripts/webkitpy/commands/upload.py
+++ b/WebKitTools/Scripts/webkitpy/commands/upload.py
@@ -41,10 +41,11 @@ from webkitpy.bugzilla import parse_bug_id
from webkitpy.commands.abstractsequencedcommand import AbstractSequencedCommand
from webkitpy.comments import bug_comment_from_svn_revision
from webkitpy.committers import CommitterList
-from webkitpy.grammar import pluralize
+from webkitpy.grammar import pluralize, join_with_separators
from webkitpy.webkit_logging import error, log
from webkitpy.mock import Mock
from webkitpy.multicommandtool import AbstractDeclarativeCommand
+from webkitpy.user import User
class CommitMessageForCurrentDiff(AbstractDeclarativeCommand):
name = "commit-message"
@@ -54,11 +55,45 @@ class CommitMessageForCurrentDiff(AbstractDeclarativeCommand):
os.chdir(tool.scm().checkout_root)
print "%s" % tool.scm().commit_message_for_this_commit().message()
+class CleanPendingCommit(AbstractDeclarativeCommand):
+ name = "clean-pending-commit"
+ help_text = "Clear r+ on obsolete patches so they do not appear in the pending-commit list."
+
+ # NOTE: This was designed to be generic, but right now we're only processing patches from the pending-commit list, so only r+ matters.
+ def _flags_to_clear_on_patch(self, patch):
+ if not patch.is_obsolete():
+ return None
+ what_was_cleared = []
+ if patch.review() == "+":
+ if patch.reviewer():
+ what_was_cleared.append("%s's review+" % patch.reviewer().full_name)
+ else:
+ what_was_cleared.append("review+")
+ return join_with_separators(what_was_cleared)
+
+ def execute(self, options, args, tool):
+ committers = CommitterList()
+ for bug_id in tool.bugs.queries.fetch_bug_ids_from_pending_commit_list():
+ bug = self.tool.bugs.fetch_bug(bug_id)
+ patches = bug.patches(include_obsolete=True)
+ for patch in patches:
+ flags_to_clear = self._flags_to_clear_on_patch(patch)
+ if not flags_to_clear:
+ continue
+ message = "Cleared %s from obsolete attachment %s so that this bug does not appear in http://webkit.org/pending-commit." % (flags_to_clear, patch.id())
+ self.tool.bugs.obsolete_attachment(patch.id(), message)
+
class AssignToCommitter(AbstractDeclarativeCommand):
name = "assign-to-committer"
help_text = "Assign bug to whoever attached the most recent r+'d patch"
+ def _patches_have_commiters(self, reviewed_patches):
+ for patch in reviewed_patches:
+ if not patch.committer():
+ return False
+ return True
+
def _assign_bug_to_last_patch_attacher(self, bug_id):
committers = CommitterList()
bug = self.tool.bugs.fetch_bug(bug_id)
@@ -71,6 +106,12 @@ class AssignToCommitter(AbstractDeclarativeCommand):
if not reviewed_patches:
log("Bug %s has no non-obsolete patches, ignoring." % bug_id)
return
+
+ # We only need to do anything with this bug if one of the r+'d patches does not have a valid committer (cq+ set).
+ if self._patches_have_commiters(reviewed_patches):
+ log("All reviewed patches on bug %s already have commit-queue+, ignoring." % bug_id)
+ return
+
latest_patch = reviewed_patches[-1]
attacher_email = latest_patch.attacher_email()
committer = committers.committer_by_email(attacher_email)
@@ -383,7 +424,7 @@ class CreateBug(AbstractDeclarativeCommand):
bug_id = tool.bugs.create_bug(bug_title, comment_text, options.component, diff_file, "Patch", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
def prompt_for_bug_title_and_comment(self):
- bug_title = raw_input("Bug title: ")
+ bug_title = User.prompt("Bug title: ")
print "Bug comment (hit ^D on blank line to end):"
lines = sys.stdin.readlines()
try:
diff --git a/WebKitTools/Scripts/webkitpy/commands/upload_unittest.py b/WebKitTools/Scripts/webkitpy/commands/upload_unittest.py
index 33001ac..7fa8797 100644
--- a/WebKitTools/Scripts/webkitpy/commands/upload_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/commands/upload_unittest.py
@@ -40,9 +40,12 @@ class UploadCommandsTest(CommandsTest):
expected_stdout = "Mock message\n"
self.assert_execute_outputs(CommitMessageForCurrentDiff(), [], expected_stdout=expected_stdout, tool=tool)
+ def test_clean_pending_commit(self):
+ self.assert_execute_outputs(CleanPendingCommit(), [])
+
def test_assign_to_committer(self):
tool = MockBugzillaTool()
- expected_stderr = "Bug 77 is already assigned to foo@foo.com (None).\nBug 76 has no non-obsolete patches, ignoring.\n"
+ expected_stderr = "Warning, attachment 128 on bug 42 has invalid committer (non-committer@example.com)\nBug 77 is already assigned to foo@foo.com (None).\nBug 76 has no non-obsolete patches, ignoring.\n"
self.assert_execute_outputs(AssignToCommitter(), [], expected_stderr=expected_stderr, tool=tool)
tool.bugs.reassign_bug.assert_called_with(42, "eric@webkit.org", "Attachment 128 was posted by a committer and has review+, assigning to Eric Seidel for commit.")
diff --git a/WebKitTools/Scripts/webkitpy/committers.py b/WebKitTools/Scripts/webkitpy/committers.py
index 0efb4e7..7af0987 100644
--- a/WebKitTools/Scripts/webkitpy/committers.py
+++ b/WebKitTools/Scripts/webkitpy/committers.py
@@ -65,6 +65,7 @@ committers_unable_to_review = [
Committer("Aaron Boodman", "aa@chromium.org"),
Committer("Adam Langley", "agl@chromium.org"),
Committer("Albert J. Wong", "ajwong@chromium.org"),
+ Committer("Alejandro G. Castro", ["alex@igalia.com", "alex@webkit.org"]),
Committer("Alexander Kellett", ["lypanov@mac.com", "a-lists001@lypanov.net", "lypanov@kde.org"]),
Committer("Alexander Pavlov", "apavlov@chromium.org"),
Committer("Andre Boule", "aboule@apple.com"),
diff --git a/WebKitTools/Scripts/webkitpy/credentials.py b/WebKitTools/Scripts/webkitpy/credentials.py
index a4d8e34..295c576 100644
--- a/WebKitTools/Scripts/webkitpy/credentials.py
+++ b/WebKitTools/Scripts/webkitpy/credentials.py
@@ -37,6 +37,7 @@ import re
from webkitpy.executive import Executive, ScriptError
from webkitpy.webkit_logging import log
from webkitpy.scm import Git
+from webkitpy.user import User
class Credentials(object):
@@ -124,7 +125,7 @@ class Credentials(object):
(username, password) = self._credentials_from_keychain(username)
if not username:
- username = raw_input("%s login: " % self.host)
+ username = User.prompt("%s login: " % self.host)
if not password:
password = getpass.getpass("%s password for %s: " % (self.host,
username))
diff --git a/WebKitTools/Scripts/webkitpy/grammar.py b/WebKitTools/Scripts/webkitpy/grammar.py
index 78809e0..651bbc9 100644
--- a/WebKitTools/Scripts/webkitpy/grammar.py
+++ b/WebKitTools/Scripts/webkitpy/grammar.py
@@ -43,3 +43,11 @@ def pluralize(noun, count):
if count != 1:
noun = plural(noun)
return "%d %s" % (count, noun)
+
+
+def join_with_separators(list_of_strings, separator=', ', last_separator=', and '):
+ if not list_of_strings:
+ return ""
+ if len(list_of_strings) == 1:
+ return list_of_strings[0]
+ return "%s%s%s" % (separator.join(list_of_strings[:-1]), last_separator, list_of_strings[-1])
diff --git a/WebKitTools/Scripts/webkitpy/grammar_unittest.py b/WebKitTools/Scripts/webkitpy/grammar_unittest.py
new file mode 100644
index 0000000..3d8b179
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/grammar_unittest.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2010 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.
+
+import unittest
+from webkitpy.grammar import join_with_separators
+
+class GrammarTest(unittest.TestCase):
+
+ def test_join_with_separators(self):
+ self.assertEqual(join_with_separators(["one", "two", "three"]), "one, two, and three")
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/driver_test.py b/WebKitTools/Scripts/webkitpy/layout_tests/driver_test.py
new file mode 100644
index 0000000..6e4ba99
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/driver_test.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 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.
+
+#
+# FIXME: this is a poor attempt at a unit tests driver. We should replace
+# this with something that actually uses a unit testing framework or
+# at least produces output that could be useful.
+
+"""Simple test client for the port/Driver interface."""
+
+import os
+import optparse
+import port
+
+
+def run_tests(port, options, tests):
+ # |image_path| is a path to the image capture from the driver.
+ image_path = 'image_result.png'
+ driver = port.start_driver(image_path, None)
+ for t in tests:
+ uri = port.filename_to_uri(os.path.join(port.layout_tests_dir(), t))
+ print "uri: " + uri
+ crash, timeout, checksum, output, err = \
+ driver.run_test(uri, int(options.timeout), None)
+ print "crash: " + str(crash)
+ print "timeout: " + str(timeout)
+ print "checksum: " + str(checksum)
+ print 'stdout: """'
+ print ''.join(output)
+ print '"""'
+ print 'stderr: """'
+ print ''.join(err)
+ print '"""'
+ print
+
+
+if __name__ == '__main__':
+ optparser = optparse.OptionParser()
+ optparser.add_option('-p', '--platform', action='store', default='mac',
+ help='Platform to test (e.g., "mac", "chromium-mac", etc.')
+ optparser.add_option('-t', '--target', action='store', default='Release',
+ help='build type ("Debug" or "Release")')
+ optparser.add_option('', '--timeout', action='store', default='2000',
+ help='test timeout in milliseconds (2000 by default)')
+ optparser.add_option('', '--wrapper', action='store')
+ optparser.add_option('', '--no-pixel-tests', action='store_true',
+ default=False,
+ help='disable pixel-to-pixel PNG comparisons')
+ options, args = optparser.parse_args()
+ p = port.get(options.platform, options)
+ run_tests(p, options, args)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
index f38a7ab..520ab1f 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
@@ -29,9 +29,9 @@
import logging
import os
+import simplejson
from layout_package import json_results_generator
-from port import path_utils
from layout_package import test_expectations
from layout_package import test_failures
@@ -45,7 +45,7 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGenerator):
WONTFIX = "wontfixCounts"
DEFERRED = "deferredCounts"
- def __init__(self, builder_name, build_name, build_number,
+ def __init__(self, port, builder_name, build_name, build_number,
results_file_base_path, builder_base_url,
test_timings, expectations, result_summary, all_tests):
"""Modifies the results.json file. Grabs it off the archive directory
@@ -56,7 +56,7 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGenerator):
results.
(see the comment of JSONResultsGenerator.__init__ for other Args)
"""
-
+ self._port = port
self._builder_name = builder_name
self._build_name = build_name
self._build_number = build_number
@@ -153,7 +153,7 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGenerator):
test, test_name, tests)
# Remove tests that don't exist anymore.
- full_path = os.path.join(path_utils.layout_tests_dir(), test_name)
+ full_path = os.path.join(self._port.layout_tests_dir(), test_name)
full_path = os.path.normpath(full_path)
if not os.path.exists(full_path):
del tests[test_name]
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
index dc24ade..84be0e1 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
@@ -29,19 +29,15 @@
import logging
import os
+import simplejson
import subprocess
import sys
import time
import urllib2
import xml.dom.minidom
-from port import path_utils
from layout_package import test_expectations
-sys.path.append(path_utils.path_from_base('third_party', 'WebKit',
- 'WebKitTools'))
-import simplejson
-
class JSONResultsGenerator(object):
@@ -80,7 +76,7 @@ class JSONResultsGenerator(object):
RESULTS_FILENAME = "results.json"
- def __init__(self, builder_name, build_name, build_number,
+ def __init__(self, port, builder_name, build_name, build_number,
results_file_base_path, builder_base_url,
test_timings, failures, passed_tests, skipped_tests, all_tests):
"""Modifies the results.json file. Grabs it off the archive directory
@@ -100,6 +96,7 @@ class JSONResultsGenerator(object):
all_tests: List of all the tests that were run. This should not
include skipped tests.
"""
+ self._port = port
self._builder_name = builder_name
self._build_name = build_name
self._build_number = build_number
@@ -122,22 +119,24 @@ class JSONResultsGenerator(object):
results_file.write(json)
results_file.close()
- def _get_svn_revision(self, in_directory=None):
+ def _get_svn_revision(self, in_directory):
"""Returns the svn revision for the given directory.
Args:
in_directory: The directory where svn is to be run.
"""
- output = subprocess.Popen(["svn", "info", "--xml"],
- cwd=in_directory,
- shell=(sys.platform == 'win32'),
- stdout=subprocess.PIPE).communicate()[0]
- try:
- dom = xml.dom.minidom.parseString(output)
- return dom.getElementsByTagName('entry')[0].getAttribute(
- 'revision')
- except xml.parsers.expat.ExpatError:
- return ""
+ if os.path.exists(os.path.join(in_directory, '.svn')):
+ output = subprocess.Popen(["svn", "info", "--xml"],
+ cwd=in_directory,
+ shell=(sys.platform == 'win32'),
+ stdout=subprocess.PIPE).communicate()[0]
+ try:
+ dom = xml.dom.minidom.parseString(output)
+ return dom.getElementsByTagName('entry')[0].getAttribute(
+ 'revision')
+ except xml.parsers.expat.ExpatError:
+ return ""
+ return ""
def _get_archived_json_results(self):
"""Reads old results JSON file if it exists.
@@ -305,16 +304,19 @@ class JSONResultsGenerator(object):
self._insert_item_into_raw_list(results_for_builder,
self._build_number, self.BUILD_NUMBERS)
- path_to_webkit = path_utils.path_from_base('third_party', 'WebKit',
- 'WebCore')
- self._insert_item_into_raw_list(results_for_builder,
- self._get_svn_revision(path_to_webkit),
- self.WEBKIT_SVN)
-
- path_to_chrome_base = path_utils.path_from_base()
- self._insert_item_into_raw_list(results_for_builder,
- self._get_svn_revision(path_to_chrome_base),
- self.CHROME_SVN)
+ # These next two branches test to see which source repos we can
+ # pull revisions from.
+ if hasattr(self._port, 'path_from_webkit_base'):
+ path_to_webkit = self._port.path_from_webkit_base()
+ self._insert_item_into_raw_list(results_for_builder,
+ self._get_svn_revision(path_to_webkit),
+ self.WEBKIT_SVN)
+
+ if hasattr(self._port, 'path_from_chromium_base'):
+ path_to_chrome = self._port.path_from_chromium_base()
+ self._insert_item_into_raw_list(results_for_builder,
+ self._get_svn_revision(path_to_chrome),
+ self.CHROME_SVN)
self._insert_item_into_raw_list(results_for_builder,
int(time.time()),
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
index 5b0d186..a3650ed 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_expectations.py
@@ -36,10 +36,7 @@ import os
import re
import sys
import time
-from port import path_utils
-sys.path.append(path_utils.path_from_base('third_party', 'WebKit',
- 'WebKitTools'))
import simplejson
# Test expectation and modifier constants.
@@ -53,12 +50,28 @@ import simplejson
class TestExpectations:
TEST_LIST = "test_expectations.txt"
- def __init__(self, tests, directory, platform, is_debug_mode, is_lint_mode,
- tests_are_present=True):
- """Reads the test expectations files from the given directory."""
- path = os.path.join(directory, self.TEST_LIST)
- self._expected_failures = TestExpectationsFile(path, tests, platform,
- is_debug_mode, is_lint_mode, tests_are_present=tests_are_present)
+ def __init__(self, port, tests, expectations, test_platform_name,
+ is_debug_mode, is_lint_mode, tests_are_present=True):
+ """Loads and parses the test expectations given in the string.
+ Args:
+ port: handle to object containing platform-specific functionality
+ test: list of all of the test files
+ expectations: test expectations as a string
+ test_platform_name: name of the platform to match expectations
+ against. Note that this may be different than
+ port.test_platform_name() when is_lint_mode is True.
+ is_debug_mode: whether to use the DEBUG or RELEASE modifiers
+ in the expectations
+ is_lint_mode: If True, just parse the expectations string
+ looking for errors.
+ tests_are_present: whether the test files exist in the file
+ system and can be probed for. This is useful for distinguishing
+ test files from directories, and is needed by the LTTF
+ dashboard, where the files aren't actually locally present.
+ """
+ self._expected_failures = TestExpectationsFile(port, expectations,
+ tests, test_platform_name, is_debug_mode, is_lint_mode,
+ tests_are_present=tests_are_present)
# TODO(ojan): Allow for removing skipped tests when getting the list of
# tests to run, but not when getting metrics.
@@ -230,9 +243,6 @@ class TestExpectationsFile:
EXPECTATION_ORDER = (PASS, CRASH, TIMEOUT, MISSING, IMAGE_PLUS_TEXT,
TEXT, IMAGE, FAIL, SKIP)
- BASE_PLATFORMS = ('linux', 'mac', 'win')
- PLATFORMS = BASE_PLATFORMS + ('win-xp', 'win-vista', 'win-7')
-
BUILD_TYPES = ('debug', 'release')
MODIFIERS = {'skip': SKIP,
@@ -251,37 +261,34 @@ class TestExpectationsFile:
'fail': FAIL,
'flaky': FLAKY}
- def __init__(self, path, full_test_list, platform, is_debug_mode,
- is_lint_mode, expectations_as_str=None, suppress_errors=False,
+ def __init__(self, port, expectations, full_test_list, test_platform_name,
+ is_debug_mode, is_lint_mode, suppress_errors=False,
tests_are_present=True):
"""
- path: The path to the expectation file. An error is thrown if a test is
- listed more than once.
+ expectations: Contents of the expectations file
full_test_list: The list of all tests to be run pending processing of
the expections for those tests.
- platform: Which platform from self.PLATFORMS to filter tests for.
+ test_platform_name: name of the platform to match expectations
+ against. Note that this may be different than
+ port.test_platform_name() when is_lint_mode is True.
is_debug_mode: Whether we testing a test_shell built debug mode.
is_lint_mode: Whether this is just linting test_expecatations.txt.
- expectations_as_str: Contents of the expectations file. Used instead of
- the path. This makes unittesting sane.
suppress_errors: Whether to suppress lint errors.
tests_are_present: Whether the test files are present in the local
filesystem. The LTTF Dashboard uses False here to avoid having to
keep a local copy of the tree.
"""
- self._path = path
- self._expectations_as_str = expectations_as_str
+ self._port = port
+ self._expectations = expectations
+ self._full_test_list = full_test_list
+ self._test_platform_name = test_platform_name
+ self._is_debug_mode = is_debug_mode
self._is_lint_mode = is_lint_mode
self._tests_are_present = tests_are_present
- self._full_test_list = full_test_list
self._suppress_errors = suppress_errors
self._errors = []
self._non_fatal_errors = []
- self._platform = self.to_test_platform_name(platform)
- if self._platform is None:
- raise Exception("Unknown platform '%s'" % (platform))
- self._is_debug_mode = is_debug_mode
# Maps relative test paths as listed in the expectations file to a
# list of maps containing modifiers and expectations for each time
@@ -320,27 +327,13 @@ class TestExpectationsFile:
"""Returns an object that can be iterated over. Allows for not caring
about whether we're iterating over a file or a new-line separated
string."""
- if self._expectations_as_str:
- iterable = [x + "\n" for x in
- self._expectations_as_str.split("\n")]
- # Strip final entry if it's empty to avoid added in an extra
- # newline.
- if iterable[len(iterable) - 1] == "\n":
- return iterable[:len(iterable) - 1]
- return iterable
- else:
- return open(self._path)
-
- def to_test_platform_name(self, name):
- """Returns the test expectation platform that will be used for a
- given platform name, or None if there is no match."""
- chromium_prefix = 'chromium-'
- name = name.lower()
- if name.startswith(chromium_prefix):
- name = name[len(chromium_prefix):]
- if name in self.PLATFORMS:
- return name
- return None
+ iterable = [x + "\n" for x in
+ self._expectations.split("\n")]
+ # Strip final entry if it's empty to avoid added in an extra
+ # newline.
+ if iterable[-1] == "\n":
+ return iterable[:-1]
+ return iterable
def get_test_set(self, modifier, expectation=None, include_skips=True):
if expectation is None:
@@ -398,6 +391,12 @@ class TestExpectationsFile:
no
"""
+ # FIXME - remove_platform_from file worked by writing a new
+ # test_expectations.txt file over the old one. Now that we're just
+ # parsing strings, we need to change this to return the new
+ # expectations string.
+ raise NotImplementedException('remove_platform_from_file')
+
new_file = self._path + '.new'
logging.debug('Original file: "%s"', self._path)
logging.debug('New file: "%s"', new_file)
@@ -430,11 +429,12 @@ class TestExpectationsFile:
elif action == ADD_PLATFORMS_EXCEPT_THIS:
parts = line.split(':')
new_options = parts[0]
- for p in self.PLATFORMS:
- p = p.upper();
+ for p in self._port.test_platform_names():
+ p = p.upper()
# This is a temp solution for rebaselining tool.
# Do not add tags WIN-7 and WIN-VISTA to test expectations
- # if the original line does not specify the platform option.
+ # if the original line does not specify the platform
+ # option.
# TODO(victorw): Remove WIN-VISTA and WIN-7 once we have
# reliable Win 7 and Win Vista buildbots setup.
if not p in (platform.upper(), 'WIN-VISTA', 'WIN-7'):
@@ -517,7 +517,7 @@ class TestExpectationsFile:
has_any_platform = False
for option in options:
- if option in self.PLATFORMS:
+ if option in self._port.test_platform_names():
has_any_platform = True
if not option == platform:
return REMOVE_PLATFORM
@@ -547,7 +547,7 @@ class TestExpectationsFile:
for option in options:
if option in self.MODIFIERS:
modifiers.add(option)
- elif option in self.PLATFORMS:
+ elif option in self._port.test_platform_names():
has_any_platform = True
elif option.startswith('bug'):
has_bug_id = True
@@ -590,7 +590,7 @@ class TestExpectationsFile:
options: list of options
"""
for opt in options:
- if self._platform.startswith(opt):
+ if self._test_platform_name.startswith(opt):
return True
return False
@@ -632,7 +632,7 @@ class TestExpectationsFile:
'indefinitely, then it should be just timeout.',
test_list_path)
- full_path = os.path.join(path_utils.layout_tests_dir(),
+ full_path = os.path.join(self._port.layout_tests_dir(),
test_list_path)
full_path = os.path.normpath(full_path)
# WebKit's way of skipping tests is to add a -disabled suffix.
@@ -662,7 +662,7 @@ class TestExpectationsFile:
else:
build_type = 'RELEASE'
print "\nFAILURES FOR PLATFORM: %s, BUILD_TYPE: %s" \
- % (self._platform.upper(), build_type)
+ % (self._test_platform_name.upper(), build_type)
for error in self._non_fatal_errors:
logging.error(error)
@@ -695,7 +695,7 @@ class TestExpectationsFile:
def _expand_tests(self, test_list_path):
"""Convert the test specification to an absolute, normalized
path and make sure directories end with the OS path separator."""
- path = os.path.join(path_utils.layout_tests_dir(), test_list_path)
+ path = os.path.join(self._port.layout_tests_dir(), test_list_path)
path = os.path.normpath(path)
path = self._fix_dir(path)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py
index b7e620d..3c087c0 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_files.py
@@ -36,7 +36,6 @@ under that directory."""
import glob
import os
-from port import path_utils
# When collecting test cases, we include any file with these extensions.
_supported_file_extensions = set(['.html', '.shtml', '.xml', '.xhtml', '.pl',
@@ -45,7 +44,7 @@ _supported_file_extensions = set(['.html', '.shtml', '.xml', '.xhtml', '.pl',
_skipped_directories = set(['.svn', '_svn', 'resources', 'script-tests'])
-def gather_test_files(paths):
+def gather_test_files(port, paths):
"""Generate a set of test files and return them.
Args:
@@ -57,14 +56,14 @@ def gather_test_files(paths):
if paths:
for path in paths:
# If there's an * in the name, assume it's a glob pattern.
- path = os.path.join(path_utils.layout_tests_dir(), path)
+ path = os.path.join(port.layout_tests_dir(), path)
if path.find('*') > -1:
filenames = glob.glob(path)
paths_to_walk.update(filenames)
else:
paths_to_walk.add(path)
else:
- paths_to_walk.add(path_utils.layout_tests_dir())
+ paths_to_walk.add(port.layout_tests_dir())
# Now walk all the paths passed in on the command line and get filenames
test_files = set()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py
index 9f52686..3452035 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_shell_thread.py
@@ -40,21 +40,22 @@ import logging
import os
import Queue
import signal
-import subprocess
import sys
import thread
import threading
import time
-from port import path_utils
import test_failures
-def process_output(proc, test_info, test_types, test_args, target, output_dir):
+def process_output(port, test_info, test_types, test_args, target, output_dir,
+ crash, timeout, test_run_time, actual_checksum,
+ output, error):
"""Receives the output from a test_shell process, subjects it to a number
of tests, and returns a list of failure types the test produced.
Args:
+ port: port-specific hooks
proc: an active test_shell process
test_info: Object containing the test filename, uri and timeout
test_types: list of test types to subject the output to
@@ -64,84 +65,39 @@ def process_output(proc, test_info, test_types, test_args, target, output_dir):
Returns: a list of failure objects and times for the test being processed
"""
- outlines = []
- extra_lines = []
failures = []
- crash = False
# Some test args, such as the image hash, may be added or changed on a
# test-by-test basis.
local_test_args = copy.copy(test_args)
- start_time = time.time()
-
- line = proc.stdout.readline()
-
- # Only start saving output lines once we've loaded the URL for the test.
- url = None
- test_string = test_info.uri.strip()
-
- while line.rstrip() != "#EOF":
- # Make sure we haven't crashed.
- if line == '' and proc.poll() is not None:
- failures.append(test_failures.FailureCrash())
-
- # This is hex code 0xc000001d, which is used for abrupt
- # termination. This happens if we hit ctrl+c from the prompt and
- # we happen to be waiting on the test_shell.
- # sdoyon: Not sure for which OS and in what circumstances the
- # above code is valid. What works for me under Linux to detect
- # ctrl+c is for the subprocess returncode to be negative SIGINT.
- # And that agrees with the subprocess documentation.
- if (-1073741510 == proc.returncode or
- - signal.SIGINT == proc.returncode):
- raise KeyboardInterrupt
- crash = True
- break
-
- # Don't include #URL lines in our output
- if line.startswith("#URL:"):
- url = line.rstrip()[5:]
- if url != test_string:
- logging.fatal("Test got out of sync:\n|%s|\n|%s|" %
- (url, test_string))
- raise AssertionError("test out of sync")
- elif line.startswith("#MD5:"):
- local_test_args.hash = line.rstrip()[5:]
- elif line.startswith("#TEST_TIMED_OUT"):
- # Test timed out, but we still need to read until #EOF.
- failures.append(test_failures.FailureTimeout())
- elif url:
- outlines.append(line)
- else:
- extra_lines.append(line)
-
- line = proc.stdout.readline()
-
- end_test_time = time.time()
-
- if len(extra_lines):
- extra = "".join(extra_lines)
- if crash:
- logging.debug("Stacktrace for %s:\n%s" % (test_string, extra))
- # Strip off "file://" since RelativeTestFilename expects
- # filesystem paths.
- filename = os.path.join(output_dir,
- path_utils.relative_test_filename(test_string[7:]))
- filename = os.path.splitext(filename)[0] + "-stack.txt"
- path_utils.maybe_make_directory(os.path.split(filename)[0])
- open(filename, "wb").write(extra)
- else:
- logging.debug("Previous test output extra lines after dump:\n%s" %
- extra)
+ local_test_args.hash = actual_checksum
+
+ if crash:
+ failures.append(test_failures.FailureCrash())
+ if timeout:
+ failures.append(test_failures.FailureTimeout())
+
+ if crash:
+ logging.debug("Stacktrace for %s:\n%s" % (test_info.filename, error))
+ # Strip off "file://" since RelativeTestFilename expects
+ # filesystem paths.
+ filename = os.path.join(output_dir, test_info.filename)
+ filename = os.path.splitext(filename)[0] + "-stack.txt"
+ port.maybe_make_directory(os.path.split(filename)[0])
+ open(filename, "wb").write(error)
+ elif error:
+ logging.debug("Previous test output extra lines after dump:\n%s" %
+ error)
# Check the output and save the results.
+ start_time = time.time()
time_for_diffs = {}
for test_type in test_types:
start_diff_time = time.time()
- new_failures = test_type.compare_output(test_info.filename,
- proc, ''.join(outlines),
- local_test_args, target)
+ new_failures = test_type.compare_output(port, test_info.filename,
+ output, local_test_args,
+ target)
# Don't add any more failures if we already have a crash, so we don't
# double-report those tests. We do double-report for timeouts since
# we still want to see the text and image output.
@@ -150,28 +106,11 @@ def process_output(proc, test_info, test_types, test_args, target, output_dir):
time_for_diffs[test_type.__class__.__name__] = (
time.time() - start_diff_time)
- total_time_for_all_diffs = time.time() - end_test_time
- test_run_time = end_test_time - start_time
+ total_time_for_all_diffs = time.time() - start_diff_time
return TestStats(test_info.filename, failures, test_run_time,
total_time_for_all_diffs, time_for_diffs)
-def start_test_shell(command, args):
- """Returns the process for a new test_shell started in layout-tests mode.
- """
- cmd = []
- # Hook for injecting valgrind or other runtime instrumentation,
- # used by e.g. tools/valgrind/valgrind_tests.py.
- wrapper = os.environ.get("BROWSER_WRAPPER", None)
- if wrapper != None:
- cmd += [wrapper]
- cmd += command + ['--layout-tests'] + args
- return subprocess.Popen(cmd,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
-
-
class TestStats:
def __init__(self, filename, failures, test_run_time,
@@ -186,17 +125,19 @@ class TestStats:
class SingleTestThread(threading.Thread):
"""Thread wrapper for running a single test file."""
- def __init__(self, test_shell_command, shell_args, test_info, test_types,
- test_args, target, output_dir):
+ def __init__(self, port, image_path, shell_args, test_info,
+ test_types, test_args, target, output_dir):
"""
Args:
+ port: object implementing port-specific hooks
test_info: Object containing the test filename, uri and timeout
output_dir: Directory to put crash stacks into.
See TestShellThread for documentation of the remaining arguments.
"""
threading.Thread.__init__(self)
- self._command = test_shell_command
+ self._port = port
+ self._image_path = image_path
self._shell_args = shell_args
self._test_info = test_info
self._test_types = test_types
@@ -205,10 +146,18 @@ class SingleTestThread(threading.Thread):
self._output_dir = output_dir
def run(self):
- proc = start_test_shell(self._command, self._shell_args +
- ["--time-out-ms=" + self._test_info.timeout, self._test_info.uri])
- self._test_stats = process_output(proc, self._test_info,
- self._test_types, self._test_args, self._target, self._output_dir)
+ driver = self._port.start_test_driver(self._image_path,
+ self._shell_args)
+ start = time.time()
+ crash, timeout, actual_checksum, output, error = \
+ driver.run_test(test_info.uri.strip(), test_info.timeout,
+ test_info.image_hash)
+ end = time.time()
+ self._test_stats = process_output(self._port,
+ self._test_info, self._test_types, self._test_args,
+ self._target, self._output_dir, crash, timeout, end - start,
+ actual_checksum, output, error)
+ driver.stop()
def get_test_stats(self):
return self._test_stats
@@ -216,17 +165,16 @@ class SingleTestThread(threading.Thread):
class TestShellThread(threading.Thread):
- def __init__(self, filename_list_queue, result_queue, test_shell_command,
- test_types, test_args, shell_args, options):
+ def __init__(self, port, filename_list_queue, result_queue,
+ test_types, test_args, image_path, shell_args, options):
"""Initialize all the local state for this test shell thread.
Args:
+ port: interface to port-specific hooks
filename_list_queue: A thread safe Queue class that contains lists
of tuples of (filename, uri) pairs.
result_queue: A thread safe Queue class that will contain tuples of
(test, failure lists) for the test results.
- test_shell_command: A list specifying the command+args for
- test_shell
test_types: A list of TestType objects to run the test output
against.
test_args: A TestArguments object to pass to each TestType.
@@ -236,13 +184,14 @@ class TestShellThread(threading.Thread):
run_webkit_tests; they are typically passed via the
run_webkit_tests.TestRunner class."""
threading.Thread.__init__(self)
+ self._port = port
self._filename_list_queue = filename_list_queue
self._result_queue = result_queue
self._filename_list = []
- self._test_shell_command = test_shell_command
self._test_types = test_types
self._test_args = test_args
- self._test_shell_proc = None
+ self._driver = None
+ self._image_path = image_path
self._shell_args = shell_args
self._options = options
self._canceled = False
@@ -379,11 +328,11 @@ class TestShellThread(threading.Thread):
# Print the error message(s).
error_str = '\n'.join([' ' + f.message() for f in failures])
logging.debug("%s %s failed:\n%s" % (self.getName(),
- path_utils.relative_test_filename(filename),
+ self._port.relative_test_filename(filename),
error_str))
else:
logging.debug("%s %s passed" % (self.getName(),
- path_utils.relative_test_filename(filename)))
+ self._port.relative_test_filename(filename)))
self._result_queue.put((filename, failures))
if batch_size > 0 and batch_count > batch_size:
@@ -407,7 +356,7 @@ class TestShellThread(threading.Thread):
Return:
A list of TestFailure objects describing the error.
"""
- worker = SingleTestThread(self._test_shell_command,
+ worker = SingleTestThread(self._port, self._image_path,
self._shell_args,
test_info,
self._test_types,
@@ -431,7 +380,7 @@ class TestShellThread(threading.Thread):
# tradeoff in order to avoid losing the rest of this thread's
# results.
logging.error('Test thread hung: killing all test_shells')
- path_utils.kill_all_test_shells()
+ worker._driver.stop()
try:
stats = worker.get_test_stats()
@@ -454,32 +403,23 @@ class TestShellThread(threading.Thread):
A list of TestFailure objects describing the error.
"""
self._ensure_test_shell_is_running()
- # Args to test_shell is a space-separated list of
- # "uri timeout pixel_hash"
- # The timeout and pixel_hash are optional. The timeout is used if this
- # test has a custom timeout. The pixel_hash is used to avoid doing an
- # image dump if the checksums match, so it should be set to a blank
- # value if we are generating a new baseline.
- # (Otherwise, an image from a previous run will be copied into
- # the baseline.)
+ # The pixel_hash is used to avoid doing an image dump if the
+ # checksums match, so it should be set to a blank value if we
+ # are generating a new baseline. (Otherwise, an image from a
+ # previous run will be copied into the baseline.)
image_hash = test_info.image_hash
if image_hash and self._test_args.new_baseline:
image_hash = ""
- self._test_shell_proc.stdin.write(("%s %s %s\n" %
- (test_info.uri, test_info.timeout, image_hash)))
-
- # If the test shell is dead, the above may cause an IOError as we
- # try to write onto the broken pipe. If this is the first test for
- # this test shell process, than the test shell did not
- # successfully start. If this is not the first test, then the
- # previous tests have caused some kind of delayed crash. We don't
- # try to recover here.
- self._test_shell_proc.stdin.flush()
-
- stats = process_output(self._test_shell_proc, test_info,
- self._test_types, self._test_args,
- self._options.target,
- self._options.results_directory)
+ start = time.time()
+ crash, timeout, actual_checksum, output, error = \
+ self._driver.run_test(test_info.uri, test_info.timeout, image_hash)
+ end = time.time()
+
+ stats = process_output(self._port, test_info, self._test_types,
+ self._test_args, self._options.target,
+ self._options.results_directory, crash,
+ timeout, end - start, actual_checksum,
+ output, error)
self._test_stats.append(stats)
return stats.failures
@@ -489,23 +429,12 @@ class TestShellThread(threading.Thread):
running tests singly, since those each start a separate test shell in
their own thread.
"""
- if (not self._test_shell_proc or
- self._test_shell_proc.poll() is not None):
- self._test_shell_proc = start_test_shell(self._test_shell_command,
- self._shell_args)
+ if (not self._driver or self._driver.poll() is not None):
+ self._driver = self._port.start_driver(
+ self._image_path, self._shell_args)
def _kill_test_shell(self):
"""Kill the test shell process if it's running."""
- if self._test_shell_proc:
- self._test_shell_proc.stdin.close()
- self._test_shell_proc.stdout.close()
- if self._test_shell_proc.stderr:
- self._test_shell_proc.stderr.close()
- if (sys.platform not in ('win32', 'cygwin') and
- not self._test_shell_proc.poll()):
- # Closing stdin/stdout/stderr hangs sometimes on OS X.
- null = open(os.devnull, "w")
- subprocess.Popen(["kill", "-9",
- str(self._test_shell_proc.pid)], stderr=null)
- null.close()
- self._test_shell_proc = None
+ if self._driver:
+ self._driver.stop()
+ self._driver = None
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py
index 1730085..3509675 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/__init__.py
@@ -27,24 +27,39 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Platform-specific utilities and pseudo-constants
+"""Port-specific entrypoints for the layout tests test infrastructure."""
-Any functions whose implementations or values differ from one platform to
-another should be defined in their respective <platform>.py
-modules. The appropriate one of those will be imported into this module to
-provide callers with a common, platform-independent interface.
-
-This file should only ever be imported by layout_package.path_utils.
-"""
import sys
-# We may not support the version of Python that a user has installed (Cygwin
-# especially has had problems), but we'll allow the platform utils to be
-# included in any case so we don't get an import error.
-if sys.platform in ('cygwin', 'win32'):
- from chromium_win import *
-elif sys.platform == 'darwin':
- from chromium_mac import *
-elif sys.platform in ('linux', 'linux2', 'freebsd7', 'openbsd4'):
- from chromium_linux import *
+
+def get(port_name=None, options=None):
+ """Returns an object implementing the Port interface. If
+ port_name is None, this routine attempts to guess at the most
+ appropriate port on this platform."""
+ port_to_use = port_name
+ if port_to_use is None:
+ if sys.platform == 'win32':
+ port_to_use = 'chromium-win'
+ elif sys.platform == 'linux2':
+ port_to_use = 'chromium-linux'
+ elif sys.platform == 'darwin':
+ port_to_use = 'chromium-mac'
+
+ if port_to_use == 'test':
+ import test
+ return test.TestPort(port_name, options)
+ elif port_to_use.startswith('mac'):
+ import mac
+ return mac.MacPort(port_name, options)
+ elif port_to_use.startswith('chromium-mac'):
+ import chromium_mac
+ return chromium_mac.ChromiumMacPort(port_name, options)
+ elif port_to_use.startswith('chromium-linux'):
+ import chromium_linux
+ return chromium_linux.ChromiumLinuxPort(port_name, options)
+ elif port_to_use.startswith('chromium-win'):
+ import chromium_win
+ return chromium_win.ChromiumWinPort(port_name, options)
+
+ raise NotImplementedError('unsupported port: %s' % port_to_use)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py
index 1fb0367..9ff3671 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py
@@ -37,19 +37,19 @@ import subprocess
import sys
import http_server_base
-import path_utils
-import port
class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
- def __init__(self, output_dir):
+ def __init__(self, port_obj, output_dir):
"""Args:
+ port_obj: handle to the platform-specific routines
output_dir: the absolute path to the layout test result directory
"""
+ http_server_base.HttpServerBase.__init__(self, port_obj)
self._output_dir = output_dir
self._httpd_proc = None
- path_utils.maybe_make_directory(output_dir)
+ port_obj.maybe_make_directory(output_dir)
self.mappings = [{'port': 8000},
{'port': 8080},
@@ -59,15 +59,14 @@ class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
# The upstream .conf file assumed the existence of /tmp/WebKit for
# placing apache files like the lock file there.
self._runtime_path = os.path.join("/tmp", "WebKit")
- path_utils.maybe_make_directory(self._runtime_path)
+ port_obj.maybe_make_directory(self._runtime_path)
# The PID returned when Apache is started goes away (due to dropping
# privileges?). The proper controlling PID is written to a file in the
# apache runtime directory.
self._pid_file = os.path.join(self._runtime_path, 'httpd.pid')
- test_dir = path_utils.path_from_base('third_party', 'WebKit',
- 'LayoutTests')
+ test_dir = self._port_obj.layout_tests_dir()
js_test_resources_dir = self._cygwin_safe_join(test_dir, "fast", "js",
"resources")
mime_types_path = self._cygwin_safe_join(test_dir, "http", "conf",
@@ -78,7 +77,7 @@ class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
error_log = self._cygwin_safe_join(output_dir, "error_log.txt")
document_root = self._cygwin_safe_join(test_dir, "http", "tests")
- executable = port.apache_executable_path()
+ executable = self._port_obj._path_to_apache()
if self._is_cygwin():
executable = self._get_cygwin_path(executable)
@@ -95,7 +94,8 @@ class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
os.environ.get("USER", ""))]
if self._is_cygwin():
- cygbin = path_utils.path_from_base('third_party', 'cygwin', 'bin')
+ cygbin = self._port_obj._path_from_base('third_party', 'cygwin',
+ 'bin')
# Not entirely sure why, but from cygwin we need to run the
# httpd command through bash.
self._start_cmd = [
@@ -146,7 +146,7 @@ class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
test_dir: absolute path to the LayoutTests directory.
output_dir: absolute path to the layout test results directory.
"""
- httpd_config = port.apache_config_file_path()
+ httpd_config = self._port_obj._path_to_apache_config_file()
httpd_config_copy = os.path.join(output_dir, "httpd.conf")
httpd_conf = open(httpd_config).read()
if self._is_cygwin():
@@ -156,22 +156,11 @@ class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
# plus the relative paths to the .so files listed in the .conf
# file. We have apache/cygwin checked into our tree so
# people don't have to install it into their cygwin.
- cygusr = path_utils.path_from_base('third_party', 'cygwin', 'usr')
+ cygusr = self._port_obj._path_from_base('third_party', 'cygwin',
+ 'usr')
httpd_conf = httpd_conf.replace('ServerRoot "/usr"',
'ServerRoot "%s"' % self._get_cygwin_path(cygusr))
- # TODO(ojan): Instead of writing an extra file, checkin a conf file
- # upstream. Or, even better, upstream/delete all our chrome http
- # tests so we don't need this special-cased DocumentRoot and then
- # just use the upstream
- # conf file.
- chrome_document_root = path_utils.path_from_base('webkit', 'data',
- 'layout_tests')
- if self._is_cygwin():
- chrome_document_root = self._get_cygwin_path(chrome_document_root)
- httpd_conf = (httpd_conf +
- self._get_virtual_host_config(chrome_document_root, 8081))
-
f = open(httpd_config_copy, 'wb')
f.write(httpd_conf)
f.close()
@@ -226,4 +215,4 @@ class LayoutTestApacheHttpd(http_server_base.HttpServerBase):
httpd_pid = None
if os.path.exists(self._pid_file):
httpd_pid = int(open(self._pid_file).readline())
- path_utils.shut_down_http_server(httpd_pid)
+ self._port_obj._shut_down_http_server(httpd_pid)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
new file mode 100644
index 0000000..ce06b44
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/base.py
@@ -0,0 +1,645 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 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 Google name 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.
+
+"""Abstract base class of Port-specific entrypoints for the layout tests
+test infrastructure (the Port and Driver classes)."""
+
+import cgi
+import difflib
+import errno
+import os
+import subprocess
+import sys
+
+import apache_http_server
+import http_server
+import websocket_server
+
+# Python bug workaround. See Port.wdiff_text() for an explanation.
+_wdiff_available = True
+
+
+# FIXME: This class should merge with webkitpy.webkit_port at some point.
+class Port(object):
+ """Abstract class for Port-specific hooks for the layout_test package.
+ """
+
+ def __init__(self, port_name=None, options=None):
+ self._name = port_name
+ self._options = options
+ self._helper = None
+ self._http_server = None
+ self._webkit_base_dir = None
+ self._websocket_server = None
+
+ def baseline_path(self):
+ """Return the absolute path to the directory to store new baselines
+ in for this port."""
+ raise NotImplementedError('Port.baseline_path')
+
+ def baseline_search_path(self):
+ """Return a list of absolute paths to directories to search under for
+ baselines. The directories are searched in order."""
+ raise NotImplementedError('Port.baseline_search_path')
+
+ def check_sys_deps(self):
+ """If the port needs to do some runtime checks to ensure that the
+ tests can be run successfully, they should be done here.
+
+ Returns whether the system is properly configured."""
+ raise NotImplementedError('Port.check_sys_deps')
+
+ def compare_text(self, actual_text, expected_text):
+ """Return whether or not the two strings are *not* equal. This
+ routine is used to diff text output.
+
+ While this is a generic routine, we include it in the Port
+ interface so that it can be overriden for testing purposes."""
+ return actual_text != expected_text
+
+ def diff_image(self, actual_filename, expected_filename, diff_filename):
+ """Compare two image files and produce a delta image file.
+
+ Return 1 if the two files are different, 0 if they are the same.
+ Also produce a delta image of the two images and write that into
+ |diff_filename|.
+
+ While this is a generic routine, we include it in the Port
+ interface so that it can be overriden for testing purposes."""
+ executable = self._path_to_image_diff()
+ cmd = [executable, '--diff', actual_filename, expected_filename,
+ diff_filename]
+ result = 1
+ try:
+ result = subprocess.call(cmd)
+ except OSError, e:
+ if e.errno == errno.ENOENT or e.errno == errno.EACCES:
+ _compare_available = False
+ else:
+ raise e
+ except ValueError:
+ # work around a race condition in Python 2.4's implementation
+ # of subprocess.Popen. See http://bugs.python.org/issue1199282 .
+ pass
+ return result
+
+ def diff_text(self, actual_text, expected_text,
+ actual_filename, expected_filename):
+ """Returns a string containing the diff of the two text strings
+ in 'unified diff' format.
+
+ While this is a generic routine, we include it in the Port
+ interface so that it can be overriden for testing purposes."""
+ diff = difflib.unified_diff(expected_text.splitlines(True),
+ actual_text.splitlines(True),
+ expected_filename,
+ actual_filename)
+ return ''.join(diff)
+
+ def expected_baselines(self, filename, suffix, all_baselines=False):
+ """Given a test name, finds where the baseline results are located.
+
+ Args:
+ filename: absolute filename to test file
+ suffix: file suffix of the expected results, including dot; e.g.
+ '.txt' or '.png'. This should not be None, but may be an empty
+ string.
+ all_baselines: If True, return an ordered list of all baseline paths
+ for the given platform. If False, return only the first one.
+ Returns
+ a list of ( platform_dir, results_filename ), where
+ platform_dir - abs path to the top of the results tree (or test
+ tree)
+ results_filename - relative path from top of tree to the results
+ file
+ (os.path.join of the two gives you the full path to the file,
+ unless None was returned.)
+ Return values will be in the format appropriate for the current
+ platform (e.g., "\\" for path separators on Windows). If the results
+ file is not found, then None will be returned for the directory,
+ but the expected relative pathname will still be returned.
+
+ This routine is generic but lives here since it is used in
+ conjunction with the other baseline and filename routines that are
+ platform specific.
+ """
+ testname = os.path.splitext(self.relative_test_filename(filename))[0]
+
+ baseline_filename = testname + '-expected' + suffix
+
+ baseline_search_path = self.baseline_search_path()
+
+ baselines = []
+ for platform_dir in baseline_search_path:
+ if os.path.exists(os.path.join(platform_dir, baseline_filename)):
+ baselines.append((platform_dir, baseline_filename))
+
+ if not all_baselines and baselines:
+ return baselines
+
+ # If it wasn't found in a platform directory, return the expected
+ # result in the test directory, even if no such file actually exists.
+ platform_dir = self.layout_tests_dir()
+ if os.path.exists(os.path.join(platform_dir, baseline_filename)):
+ baselines.append((platform_dir, baseline_filename))
+
+ if baselines:
+ return baselines
+
+ return [(None, baseline_filename)]
+
+ def expected_filename(self, filename, suffix):
+ """Given a test name, returns an absolute path to its expected results.
+
+ If no expected results are found in any of the searched directories,
+ the directory in which the test itself is located will be returned.
+ The return value is in the format appropriate for the platform
+ (e.g., "\\" for path separators on windows).
+
+ Args:
+ filename: absolute filename to test file
+ suffix: file suffix of the expected results, including dot; e.g. '.txt'
+ or '.png'. This should not be None, but may be an empty string.
+ platform: the most-specific directory name to use to build the
+ search list of directories, e.g., 'chromium-win', or
+ 'chromium-mac-leopard' (we follow the WebKit format)
+
+ This routine is generic but is implemented here to live alongside
+ the other baseline and filename manipulation routines.
+ """
+ platform_dir, baseline_filename = self.expected_baselines(
+ filename, suffix)[0]
+ if platform_dir:
+ return os.path.join(platform_dir, baseline_filename)
+ return os.path.join(self.layout_tests_dir(), baseline_filename)
+
+ def filename_to_uri(self, filename):
+ """Convert a test file to a URI."""
+ LAYOUTTEST_HTTP_DIR = "http/tests/"
+ LAYOUTTEST_WEBSOCKET_DIR = "websocket/tests/"
+
+ relative_path = self.relative_test_filename(filename)
+ port = None
+ use_ssl = False
+
+ if relative_path.startswith(LAYOUTTEST_HTTP_DIR):
+ # http/tests/ run off port 8000 and ssl/ off 8443
+ relative_path = relative_path[len(LAYOUTTEST_HTTP_DIR):]
+ port = 8000
+ elif relative_path.startswith(LAYOUTTEST_WEBSOCKET_DIR):
+ # websocket/tests/ run off port 8880 and 9323
+ # Note: the root is /, not websocket/tests/
+ port = 8880
+
+ # Make http/tests/local run as local files. This is to mimic the
+ # logic in run-webkit-tests.
+ #
+ # TODO(dpranke): remove the media reference and the SSL reference?
+ if (port and not relative_path.startswith("local/") and
+ not relative_path.startswith("media/")):
+ if relative_path.startswith("ssl/"):
+ port += 443
+ protocol = "https"
+ else:
+ protocol = "http"
+ return "%s://127.0.0.1:%u/%s" % (protocol, port, relative_path)
+
+ if sys.platform in ('cygwin', 'win32'):
+ return "file:///" + self.get_absolute_path(filename)
+ return "file://" + self.get_absolute_path(filename)
+
+ def get_absolute_path(self, filename):
+ """Return the absolute path in unix format for the given filename.
+
+ This routine exists so that platforms that don't use unix filenames
+ can convert accordingly."""
+ return os.path.abspath(filename)
+
+ def layout_tests_dir(self):
+ """Return the absolute path to the top of the LayoutTests directory."""
+ return self.path_from_webkit_base('LayoutTests')
+
+ def maybe_make_directory(self, *path):
+ """Creates the specified directory if it doesn't already exist."""
+ try:
+ os.makedirs(os.path.join(*path))
+ except OSError, e:
+ if e.errno != errno.EEXIST:
+ raise
+
+ def name(self):
+ """Return the name of the port (e.g., 'mac', 'chromium-win-xp').
+
+ Note that this is different from the test_platform_name(), which
+ may be different (e.g., 'win-xp' instead of 'chromium-win-xp'."""
+ return self._name
+
+ def num_cores(self):
+ """Return the number of cores/cpus available on this machine.
+
+ This routine is used to determine the default amount of parallelism
+ used by run-chromium-webkit-tests."""
+ raise NotImplementedError('Port.num_cores')
+
+ def path_from_webkit_base(self, *comps):
+ """Returns the full path to path made by joining the top of the
+ WebKit source tree and the list of path components in |*comps|."""
+ if not self._webkit_base_dir:
+ abspath = os.path.abspath(__file__)
+ self._webkit_base_dir = abspath[0:abspath.find('WebKitTools')]
+ return os.path.join(self._webkit_base_dir, *comps)
+
+ def remove_directory(self, *path):
+ """Recursively removes a directory, even if it's marked read-only.
+
+ Remove the directory located at *path, if it exists.
+
+ shutil.rmtree() doesn't work on Windows if any of the files
+ or directories are read-only, which svn repositories and
+ some .svn files are. We need to be able to force the files
+ to be writable (i.e., deletable) as we traverse the tree.
+
+ Even with all this, Windows still sometimes fails to delete a file,
+ citing a permission error (maybe something to do with antivirus
+ scans or disk indexing). The best suggestion any of the user
+ forums had was to wait a bit and try again, so we do that too.
+ It's hand-waving, but sometimes it works. :/
+ """
+ file_path = os.path.join(*path)
+ if not os.path.exists(file_path):
+ return
+
+ win32 = False
+ if sys.platform == 'win32':
+ win32 = True
+ # Some people don't have the APIs installed. In that case we'll do
+ # without.
+ try:
+ win32api = __import__('win32api')
+ win32con = __import__('win32con')
+ except ImportError:
+ win32 = False
+
+ def remove_with_retry(rmfunc, path):
+ os.chmod(path, stat.S_IWRITE)
+ if win32:
+ win32api.SetFileAttributes(path,
+ win32con.FILE_ATTRIBUTE_NORMAL)
+ try:
+ return rmfunc(path)
+ except EnvironmentError, e:
+ if e.errno != errno.EACCES:
+ raise
+ print 'Failed to delete %s: trying again' % repr(path)
+ time.sleep(0.1)
+ return rmfunc(path)
+ else:
+
+ def remove_with_retry(rmfunc, path):
+ if os.path.islink(path):
+ return os.remove(path)
+ else:
+ return rmfunc(path)
+
+ for root, dirs, files in os.walk(file_path, topdown=False):
+ # For POSIX: making the directory writable guarantees
+ # removability. Windows will ignore the non-read-only
+ # bits in the chmod value.
+ os.chmod(root, 0770)
+ for name in files:
+ remove_with_retry(os.remove, os.path.join(root, name))
+ for name in dirs:
+ remove_with_retry(os.rmdir, os.path.join(root, name))
+
+ remove_with_retry(os.rmdir, file_path)
+
+ def test_platform_name(self):
+ return self._name
+
+ def relative_test_filename(self, filename):
+ """Relative unix-style path for a filename under the LayoutTests
+ directory. Filenames outside the LayoutTests directory should raise
+ an error."""
+ return filename[len(self.layout_tests_dir()) + 1:]
+
+ def results_directory(self):
+ """Absolute path to the place to store the test results."""
+ raise NotImplemented('Port.results_directory')
+
+ def setup_test_run(self):
+ """This routine can be overridden to perform any port-specific
+ work that shouuld be done at the beginning of a test run."""
+ pass
+
+ def show_html_results_file(self, results_filename):
+ """This routine should display the HTML file pointed at by
+ results_filename in a users' browser."""
+ raise NotImplementedError('Port.show_html_results_file')
+
+ def start_driver(self, png_path, options):
+ """Starts a new test Driver and returns a handle to the object."""
+ raise NotImplementedError('Port.start_driver')
+
+ def start_helper(self):
+ """Start a layout test helper if needed on this port. The test helper
+ is used to reconfigure graphics settings and do other things that
+ may be necessary to ensure a known test configuration."""
+ raise NotImplementedError('Port.start_helper')
+
+ def start_http_server(self):
+ """Start a web server if it is available. Do nothing if
+ it isn't. This routine is allowed to (and may) fail if a server
+ is already running."""
+ if self._options.use_apache:
+ self._http_server = apache_http_server.LayoutTestApacheHttpd(self,
+ self._options.results_directory)
+ else:
+ self._http_server = http_server.Lighttpd(self,
+ self._options.results_directory)
+ self._http_server.start()
+
+ def start_websocket_server(self):
+ """Start a websocket server if it is available. Do nothing if
+ it isn't. This routine is allowed to (and may) fail if a server
+ is already running."""
+ self._websocket_server = websocket_server.PyWebSocket(self,
+ self._options.results_directory)
+ self._websocket_server.start()
+
+ def stop_helper(self):
+ """Shut down the test helper if it is running. Do nothing if
+ it isn't, or it isn't available."""
+ raise NotImplementedError('Port.stop_helper')
+
+ def stop_http_server(self):
+ """Shut down the http server if it is running. Do nothing if
+ it isn't, or it isn't available."""
+ if self._http_server:
+ self._http_server.stop()
+
+ def stop_websocket_server(self):
+ """Shut down the websocket server if it is running. Do nothing if
+ it isn't, or it isn't available."""
+ if self._websocket_server:
+ self._websocket_server.stop()
+
+ def test_expectations(self):
+ """Returns the test expectations for this port.
+
+ Basically this string should contain the equivalent of a
+ test_expectations file. See test_expectations.py for more details."""
+ raise NotImplementedError('Port.test_expectations')
+
+ def test_base_platform_names(self):
+ """Return a list of the 'base' platforms on your port. The base
+ platforms represent different architectures, operating systems,
+ or implementations (as opposed to different versions of a single
+ platform). For example, 'mac' and 'win' might be different base
+ platforms, wherease 'mac-tiger' and 'mac-leopard' might be
+ different platforms. This routine is used by the rebaselining tool
+ and the dashboards, and the strings correspond to the identifiers
+ in your test expectations (*not* necessarily the platform names
+ themselves)."""
+ raise NotImplementedError('Port.base_test_platforms')
+
+ def test_platform_name(self):
+ """Returns the string that corresponds to the given platform name
+ in the test expectations. This may be the same as name(), or it
+ may be different. For example, chromium returns 'mac' for
+ 'chromium-mac'."""
+ raise NotImplementedError('Port.test_platform_name')
+
+ def test_platforms(self):
+ """Returns the list of test platform identifiers as used in the
+ test_expectations and on dashboards, the rebaselining tool, etc.
+
+ Note that this is not necessarily the same as the list of ports,
+ which must be globally unique (e.g., both 'chromium-mac' and 'mac'
+ might return 'mac' as a test_platform name'."""
+ raise NotImplementedError('Port.platforms')
+
+ def version(self):
+ """Returns a string indicating the version of a given platform, e.g.
+ '-leopard' or '-xp'.
+
+ This is used to help identify the exact port when parsing test
+ expectations, determining search paths, and logging information."""
+ raise NotImplementedError('Port.version')
+
+ def wdiff_text(self, actual_filename, expected_filename):
+ """Returns a string of HTML indicating the word-level diff of the
+ contents of the two filenames. Returns an empty string if word-level
+ diffing isn't available."""
+ executable = self._path_to_wdiff()
+ cmd = [executable,
+ '--start-delete=##WDIFF_DEL##',
+ '--end-delete=##WDIFF_END##',
+ '--start-insert=##WDIFF_ADD##',
+ '--end-insert=##WDIFF_END##',
+ expected_filename,
+ actual_filename]
+ global _wdiff_available
+ result = ''
+ try:
+ # Python's Popen has a bug that causes any pipes opened to a
+ # process that can't be executed to be leaked. Since this
+ # code is specifically designed to tolerate exec failures
+ # to gracefully handle cases where wdiff is not installed,
+ # the bug results in a massive file descriptor leak. As a
+ # workaround, if an exec failure is ever experienced for
+ # wdiff, assume it's not available. This will leak one
+ # file descriptor but that's better than leaking each time
+ # wdiff would be run.
+ #
+ # http://mail.python.org/pipermail/python-list/
+ # 2008-August/505753.html
+ # http://bugs.python.org/issue3210
+ #
+ # It also has a threading bug, so we don't output wdiff if
+ # the Popen raises a ValueError.
+ # http://bugs.python.org/issue1236
+ if _wdiff_available:
+ try:
+ wdiff = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE).communicate()[0]
+ except ValueError, e:
+ # Working around a race in Python 2.4's implementation
+ # of Popen().
+ wdiff = ''
+ wdiff = cgi.escape(wdiff)
+ wdiff = wdiff.replace('##WDIFF_DEL##', '<span class=del>')
+ wdiff = wdiff.replace('##WDIFF_ADD##', '<span class=add>')
+ wdiff = wdiff.replace('##WDIFF_END##', '</span>')
+ result = '<head><style>.del { background: #faa; } '
+ result += '.add { background: #afa; }</style></head>'
+ result += '<pre>' + wdiff + '</pre>'
+ except OSError, e:
+ if (e.errno == errno.ENOENT or e.errno == errno.EACCES or
+ e.errno == errno.ECHILD):
+ _wdiff_available = False
+ else:
+ raise e
+ return result
+
+ #
+ # PROTECTED ROUTINES
+ #
+ # The routines below should only be called by routines in this class
+ # or any of its subclasses.
+ #
+
+ def _kill_process(self, pid):
+ """Forcefully kill a process.
+
+ This routine should not be used or needed generically, but can be
+ used in helper files like http_server.py."""
+ raise NotImplementedError('Port.kill_process')
+
+ def _path_to_apache(self):
+ """Returns the full path to the apache binary.
+
+ This is needed only by ports that use the apache_http_server module."""
+ raise NotImplementedError('Port.path_to_apache')
+
+ def _path_to_apache_config_file(self):
+ """Returns the full path to the apache binary.
+
+ This is needed only by ports that use the apache_http_server module."""
+ raise NotImplementedError('Port.path_to_apache_config_file')
+
+ def _path_to_driver(self):
+ """Returns the full path to the test driver (DumpRenderTree)."""
+ raise NotImplementedError('Port.path_to_driver')
+
+ def _path_to_helper(self):
+ """Returns the full path to the layout_test_helper binary, which
+ is used to help configure the system for the test run, or None
+ if no helper is needed.
+
+ This is likely only used by start/stop_helper()."""
+ raise NotImplementedError('Port._path_to_helper')
+
+ def _path_to_image_diff(self):
+ """Returns the full path to the image_diff binary, or None if it
+ is not available.
+
+ This is likely used only by diff_image()"""
+ raise NotImplementedError('Port.path_to_image_diff')
+
+ def _path_to_lighttpd(self):
+ """Returns the path to the LigHTTPd binary.
+
+ This is needed only by ports that use the http_server.py module."""
+ raise NotImplementedError('Port._path_to_lighttpd')
+
+ def _path_to_lighttpd_modules(self):
+ """Returns the path to the LigHTTPd modules directory.
+
+ This is needed only by ports that use the http_server.py module."""
+ raise NotImplementedError('Port._path_to_lighttpd_modules')
+
+ def _path_to_lighttpd_php(self):
+ """Returns the path to the LigHTTPd PHP executable.
+
+ This is needed only by ports that use the http_server.py module."""
+ raise NotImplementedError('Port._path_to_lighttpd_php')
+
+ def _path_to_wdiff(self):
+ """Returns the full path to the wdiff binary, or None if it is
+ not available.
+
+ This is likely used only by wdiff_text()"""
+ raise NotImplementedError('Port._path_to_wdiff')
+
+ def _shut_down_http_server(self, pid):
+ """Forcefully and synchronously kills the web server.
+
+ This routine should only be called from http_server.py or its
+ subclasses."""
+ raise NotImplementedError('Port._shut_down_http_server')
+
+ def _webkit_baseline_path(self, platform):
+ """Return the full path to the top of the baseline tree for a
+ given platform."""
+ return os.path.join(self.layout_tests_dir(), 'platform',
+ platform)
+
+
+class Driver:
+ """Abstract interface for the DumpRenderTree interface."""
+
+ def __init__(self, port, png_path, options):
+ """Initialize a Driver to subsequently run tests.
+
+ Typically this routine will spawn DumpRenderTree in a config
+ ready for subsequent input.
+
+ port - reference back to the port object.
+ png_path - an absolute path for the driver to write any image
+ data for a test (as a PNG). If no path is provided, that
+ indicates that pixel test results will not be checked.
+ options - any port-specific driver options."""
+ raise NotImplementedError('Driver.__init__')
+
+ def run_test(self, uri, timeout, checksum):
+ """Run a single test and return the results.
+
+ Note that it is okay if a test times out or crashes and leaves
+ the driver in an indeterminate state. The upper layers of the program
+ are responsible for cleaning up and ensuring things are okay.
+
+ uri - a full URI for the given test
+ timeout - number of milliseconds to wait before aborting this test.
+ checksum - if present, the expected checksum for the image for this
+ test
+
+ Returns a tuple of the following:
+ crash - a boolean indicating whether the driver crashed on the test
+ timeout - a boolean indicating whehter the test timed out
+ checksum - a string containing the checksum of the image, if
+ present
+ output - any text output
+ error - any unexpected or additional (or error) text output
+
+ Note that the image itself should be written to the path that was
+ specified in the __init__() call."""
+ raise NotImplementedError('Driver.run_test')
+
+ def poll(self):
+ """Returns None if the Driver is still running. Returns the returncode
+ if it has exited."""
+ raise NotImplementedError('Driver.poll')
+
+ def returncode(self):
+ """Returns the system-specific returncode if the Driver has stopped or
+ exited."""
+ raise NotImplementedError('Driver.returncode')
+
+ def stop(self):
+ raise NotImplementedError('Driver.stop')
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py
new file mode 100644
index 0000000..70a8dea
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py
@@ -0,0 +1,260 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 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.
+
+"""Chromium implementations of the Port interface."""
+
+import logging
+import os
+import shutil
+import signal
+import subprocess
+import sys
+import time
+
+import base
+import http_server
+import websocket_server
+
+
+class ChromiumPort(base.Port):
+ """Abstract base class for Chromium implementations of the Port class."""
+
+ def __init__(self, port_name=None, options=None):
+ base.Port.__init__(self, port_name, options)
+ self._chromium_base_dir = None
+
+ def baseline_path(self):
+ return self._chromium_baseline_path(self._name)
+
+ def check_sys_deps(self):
+ result = True
+ test_shell_binary_path = self._path_to_driver()
+ if os.path.exists(test_shell_binary_path):
+ proc = subprocess.Popen([test_shell_binary_path,
+ '--check-layout-test-sys-deps'])
+ if proc.wait() != 0:
+ logging.error("Aborting because system dependencies check "
+ "failed.")
+ logging.error("To override, invoke with --nocheck-sys-deps")
+ result = False
+ else:
+ logging.error('test driver is not found at %s' %
+ test_shell_binary_path)
+ result = False
+
+ image_diff_path = self._path_to_image_diff()
+ if (not os.path.exists(image_diff_path) and not
+ self._options.no_pixel_tests):
+ logging.error('image diff not found at %s' % image_diff_path)
+ logging.error("To override, invoke with --no-pixel-tests")
+ result = False
+
+ return result
+
+ def compare_text(self, actual_text, expected_text):
+ return actual_text != expected_text
+
+ def path_from_chromium_base(self, *comps):
+ """Returns the full path to path made by joining the top of the
+ Chromium source tree and the list of path components in |*comps|."""
+ if not self._chromium_base_dir:
+ abspath = os.path.abspath(__file__)
+ self._chromium_base_dir = abspath[0:abspath.find('third_party')]
+ return os.path.join(self._chromium_base_dir, *comps)
+
+ def results_directory(self):
+ return self.path_from_chromium_base('webkit', self._options.target,
+ self._options.results_directory)
+
+ def setup_test_run(self):
+ # Delete the disk cache if any to ensure a clean test run.
+ test_shell_binary_path = self._path_to_driver()
+ cachedir = os.path.split(test_shell_binary_path)[0]
+ cachedir = os.path.join(cachedir, "cache")
+ if os.path.exists(cachedir):
+ shutil.rmtree(cachedir)
+
+ def show_results_html_file(self, results_filename):
+ subprocess.Popen([self._path_to_driver(),
+ self.filename_to_uri(results_filename)])
+
+ def start_driver(self, image_path, options):
+ """Starts a new Driver and returns a handle to it."""
+ return ChromiumDriver(self, image_path, options)
+
+ def start_helper(self):
+ helper_path = self._path_to_helper()
+ if helper_path:
+ logging.debug("Starting layout helper %s" % helper_path)
+ self._helper = subprocess.Popen([helper_path],
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=None)
+ is_ready = self._helper.stdout.readline()
+ if not is_ready.startswith('ready'):
+ logging.error("layout_test_helper failed to be ready")
+
+ def stop_helper(self):
+ if self._helper:
+ logging.debug("Stopping layout test helper")
+ self._helper.stdin.write("x\n")
+ self._helper.stdin.close()
+ self._helper.wait()
+
+ def test_base_platform_names(self):
+ return ('linux', 'mac', 'win')
+
+ def test_expectations(self, options=None):
+ """Returns the test expectations for this port.
+
+ Basically this string should contain the equivalent of a
+ test_expectations file. See test_expectations.py for more details."""
+ expectations_file = self.path_from_chromium_base('webkit', 'tools',
+ 'layout_tests', 'test_expectations.txt')
+ return file(expectations_file, "r").read()
+
+ def test_platform_names(self):
+ return self.test_base_platform_names() + ('win-xp',
+ 'win-vista', 'win-7')
+
+ #
+ # PROTECTED METHODS
+ #
+ # These routines should only be called by other methods in this file
+ # or any subclasses.
+ #
+
+ def _chromium_baseline_path(self, platform):
+ if platform is None:
+ platform = self.name()
+ return self.path_from_chromium_base('webkit', 'data', 'layout_tests',
+ 'platform', platform, 'LayoutTests')
+
+
+class ChromiumDriver(base.Driver):
+ """Abstract interface for the DumpRenderTree interface."""
+
+ def __init__(self, port, image_path, options):
+ self._port = port
+ self._options = options
+ self._target = port._options.target
+ self._image_path = image_path
+
+ cmd = []
+ # Hook for injecting valgrind or other runtime instrumentation,
+ # used by e.g. tools/valgrind/valgrind_tests.py.
+ wrapper = os.environ.get("BROWSER_WRAPPER", None)
+ if wrapper != None:
+ cmd += [wrapper]
+ if self._port._options.wrapper:
+ # This split() isn't really what we want -- it incorrectly will
+ # split quoted strings within the wrapper argument -- but in
+ # practice it shouldn't come up and the --help output warns
+ # about it anyway.
+ cmd += self._options.wrapper.split()
+ cmd += [port._path_to_driver(), '--layout-tests']
+ if options:
+ cmd += options
+ self._proc = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+
+ def poll(self):
+ return self._proc.poll()
+
+ def returncode(self):
+ return self._proc.returncode
+
+ def run_test(self, uri, timeoutms, checksum):
+ output = []
+ error = []
+ crash = False
+ timeout = False
+ actual_uri = None
+ actual_checksum = None
+
+ start_time = time.time()
+ cmd = uri
+ if timeoutms:
+ cmd += ' ' + str(timeoutms)
+ if checksum:
+ cmd += ' ' + checksum
+ cmd += "\n"
+
+ self._proc.stdin.write(cmd)
+ line = self._proc.stdout.readline()
+ while line.rstrip() != "#EOF":
+ # Make sure we haven't crashed.
+ if line == '' and self.poll() is not None:
+ # This is hex code 0xc000001d, which is used for abrupt
+ # termination. This happens if we hit ctrl+c from the prompt
+ # and we happen to be waiting on the test_shell.
+ # sdoyon: Not sure for which OS and in what circumstances the
+ # above code is valid. What works for me under Linux to detect
+ # ctrl+c is for the subprocess returncode to be negative
+ # SIGINT. And that agrees with the subprocess documentation.
+ if (-1073741510 == self._proc.returncode or
+ - signal.SIGINT == self._proc.returncode):
+ raise KeyboardInterrupt
+ crash = True
+ break
+
+ # Don't include #URL lines in our output
+ if line.startswith("#URL:"):
+ actual_uri = line.rstrip()[5:]
+ if uri != actual_uri:
+ logging.fatal("Test got out of sync:\n|%s|\n|%s|" %
+ (uri, actual_uri))
+ raise AssertionError("test out of sync")
+ elif line.startswith("#MD5:"):
+ actual_checksum = line.rstrip()[5:]
+ elif line.startswith("#TEST_TIMED_OUT"):
+ timeout = True
+ # Test timed out, but we still need to read until #EOF.
+ elif actual_uri:
+ output.append(line)
+ else:
+ error.append(line)
+
+ line = self._proc.stdout.readline()
+
+ return (crash, timeout, actual_checksum, ''.join(output),
+ ''.join(error))
+
+ def stop(self):
+ if self._proc:
+ self._proc.stdin.close()
+ self._proc.stdout.close()
+ if self._proc.stderr:
+ self._proc.stderr.close()
+ if (sys.platform not in ('win32', 'cygwin') and
+ not self._proc.poll()):
+ # Closing stdin/stdout/stderr hangs sometimes on OS X.
+ null = open(os.devnull, "w")
+ subprocess.Popen(["kill", "-9",
+ str(self._proc.pid)], stderr=null)
+ null.close()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py
index 9ffc401..8fd5343 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_linux.py
@@ -27,222 +27,123 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""This is the Linux implementation of the port
- package. This file should only be imported by that package."""
+"""Chromium Mac implementation of the Port interface."""
import os
+import platform
import signal
import subprocess
-import sys
-import logging
-import chromium_win
-import path_utils
+import chromium
-
-def platform_name():
- """Returns the name of the platform we're currently running on."""
- return 'chromium-linux' + platform_version()
-
-
-def platform_version():
- """Returns the version string for the platform, e.g. '-vista' or
- '-snowleopard'. If the platform does not distinguish between
- minor versions, it returns ''."""
- return ''
-
-
-def get_num_cores():
- """Returns the number of cores on the machine. For hyperthreaded machines,
- this will be double the number of actual processors."""
- num_cores = os.sysconf("SC_NPROCESSORS_ONLN")
- if isinstance(num_cores, int) and num_cores > 0:
- return num_cores
- return 1
-
-
-def baseline_path(platform=None):
- """Returns the path relative to the top of the source tree for the
- baselines for the specified platform version. If |platform| is None,
- then the version currently in use is used."""
- if platform is None:
- platform = platform_name()
- return path_utils.path_from_base('webkit', 'data', 'layout_tests',
- 'platform', platform, 'LayoutTests')
-
-
-def baseline_search_path(platform=None):
- """Returns the list of directories to search for baselines/results, in
- order of preference. Paths are relative to the top of the source tree."""
- return [baseline_path(platform),
- chromium_win.baseline_path('chromium-win'),
- path_utils.webkit_baseline_path('win'),
- path_utils.webkit_baseline_path('mac')]
-
-
-def apache_executable_path():
- """Returns the executable path to start Apache"""
- path = os.path.join("/usr", "sbin", "apache2")
- if os.path.exists(path):
- return path
- print "Unable to fine Apache executable %s" % path
- _missing_apache()
-
-
-def apache_config_file_path():
- """Returns the path to Apache config file"""
- return path_utils.path_from_base("third_party", "WebKit", "LayoutTests",
- "http", "conf", "apache2-debian-httpd.conf")
-
-
-def lighttpd_executable_path():
- """Returns the executable path to start LigHTTPd"""
- binpath = "/usr/sbin/lighttpd"
- if os.path.exists(binpath):
- return binpath
- print "Unable to find LigHTTPd executable %s" % binpath
- _missing_lighttpd()
-
-
-def lighttpd_module_path():
- """Returns the library module path for LigHTTPd"""
- modpath = "/usr/lib/lighttpd"
- if os.path.exists(modpath):
- return modpath
- print "Unable to find LigHTTPd modules %s" % modpath
- _missing_lighttpd()
-
-
-def lighttpd_php_path():
- """Returns the PHP executable path for LigHTTPd"""
- binpath = "/usr/bin/php-cgi"
- if os.path.exists(binpath):
- return binpath
- print "Unable to find PHP CGI executable %s" % binpath
- _missing_lighttpd()
-
-
-def wdiff_path():
- """Path to the WDiff executable, which we assume is already installed and
- in the user's $PATH."""
- return 'wdiff'
-
-
-def image_diff_path(target):
- """Path to the image_diff binary.
-
- Args:
- target: Build target mode (debug or release)"""
- return _path_from_build_results(target, 'image_diff')
-
-
-def layout_test_helper_path(target):
- """Path to the layout_test helper binary, if needed, empty otherwise"""
- return ''
-
-
-def test_shell_path(target):
- """Return the platform-specific binary path for our TestShell.
-
- Args:
- target: Build target mode (debug or release) """
- if target in ('Debug', 'Release'):
- try:
- debug_path = _path_from_build_results('Debug', 'test_shell')
- release_path = _path_from_build_results('Release', 'test_shell')
-
- debug_mtime = os.stat(debug_path).st_mtime
- release_mtime = os.stat(release_path).st_mtime
-
- if debug_mtime > release_mtime and target == 'Release' or \
- release_mtime > debug_mtime and target == 'Debug':
- logging.info('\x1b[31mWarning: you are not running the most '
- 'recent test_shell binary. You need to pass '
- '--debug or not to select between Debug and '
- 'Release.\x1b[0m')
- # This will fail if we don't have both a debug and release binary.
- # That's fine because, in this case, we must already be running the
- # most up-to-date one.
- except path_utils.PathNotFound:
- pass
-
- return _path_from_build_results(target, 'test_shell')
-
-
-def fuzzy_match_path():
- """Return the path to the fuzzy matcher binary."""
- return path_utils.path_from_base('third_party', 'fuzzymatch', 'fuzzymatch')
-
-
-def shut_down_http_server(server_pid):
- """Shut down the lighttpd web server. Blocks until it's fully shut down.
-
- Args:
- server_pid: The process ID of the running server.
- """
- # server_pid is not set when "http_server.py stop" is run manually.
- if server_pid is None:
- # This isn't ideal, since it could conflict with web server processes
- # not started by http_server.py, but good enough for now.
- kill_all_process('lighttpd')
- kill_all_process('apache2')
- else:
- try:
- os.kill(server_pid, signal.SIGTERM)
- #TODO(mmoss) Maybe throw in a SIGKILL just to be sure?
- except OSError:
- # Sometimes we get a bad PID (e.g. from a stale httpd.pid file),
- # so if kill fails on the given PID, just try to 'killall' web
- # servers.
- shut_down_http_server(None)
-
-
-def kill_process(pid):
- """Forcefully kill the process.
-
- Args:
- pid: The id of the process to be killed.
- """
- os.kill(pid, signal.SIGKILL)
-
-
-def kill_all_process(process_name):
- null = open(os.devnull)
- subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
- process_name], stderr=null)
- null.close()
-
-
-def kill_all_test_shells():
- """Kills all instances of the test_shell binary currently running."""
- kill_all_process('test_shell')
-
-#
-# Private helper functions
-#
-
-
-def _missing_lighttpd():
- print 'Please install using: "sudo apt-get install lighttpd php5-cgi"'
- print 'For complete Linux build requirements, please see:'
- print 'http://code.google.com/p/chromium/wiki/LinuxBuildInstructions'
- sys.exit(1)
-
-
-def _missing_apache():
- print ('Please install using: "sudo apt-get install apache2 '
- 'libapache2-mod-php5"')
- print 'For complete Linux build requirements, please see:'
- print 'http://code.google.com/p/chromium/wiki/LinuxBuildInstructions'
- sys.exit(1)
-
-
-def _path_from_build_results(*pathies):
- # FIXME(dkegel): use latest or warn if more than one found?
- for dir in ["sconsbuild", "out", "xcodebuild"]:
- try:
- return path_utils.path_from_base(dir, *pathies)
- except:
- pass
- raise path_utils.PathNotFound("Unable to find %s in build tree" %
- (os.path.join(*pathies)))
+
+class ChromiumLinuxPort(chromium.ChromiumPort):
+ """Chromium Linux implementation of the Port class."""
+
+ def __init__(self, port_name=None, options=None):
+ if port_name is None:
+ port_name = 'chromium-linux'
+ chromium.ChromiumPort.__init__(self, port_name, options)
+
+ def baseline_search_path(self):
+ return [self.baseline_path(),
+ self._chromium_baseline_path('chromium-win'),
+ self._webkit_baseline_path('win'),
+ self._webkit_baseline_path('mac')]
+
+ def check_sys_deps(self):
+ # We have no platform-specific dependencies to check.
+ return True
+
+ def num_cores(self):
+ num_cores = os.sysconf("SC_NPROCESSORS_ONLN")
+ if isinstance(num_cores, int) and num_cores > 0:
+ return num_cores
+ return 1
+
+ def test_platform_name(self):
+ # We use 'linux' instead of 'chromium-linux' in test_expectations.txt.
+ return 'linux'
+
+ def version(self):
+ # We don't have different versions on linux.
+ return ''
+
+ #
+ # PROTECTED METHODS
+ #
+
+ def _build_path(self, *comps):
+ base = self.path_from_chromium_base()
+ if os.path.exists(os.path.join(base, 'sconsbuild')):
+ return self.path_from_chromium_base('sconsbuild',
+ self._options.target, *comps)
+ else:
+ return self.path_from_chromium_base('out',
+ self._options.target, *comps)
+
+ def _kill_process(self, pid):
+ """Forcefully kill the process.
+
+ Args:
+ pid: The id of the process to be killed.
+ """
+ os.kill(pid, signal.SIGKILL)
+
+ def _kill_all_process(self, process_name):
+ null = open(os.devnull)
+ subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
+ process_name], stderr=null)
+ null.close()
+
+ def _path_to_apache(self):
+ return '/usr/sbin/apache2'
+
+ def _path_to_apache_config_file(self):
+ return os.path.join(self.layout_tests_dir(), 'http', 'conf',
+ 'apache2-debian-httpd.conf')
+
+ def _path_to_lighttpd(self):
+ return "/usr/sbin/lighttpd"
+
+ def _path_to_lighttpd_modules(self):
+ return "/usr/lib/lighttpd"
+
+ def _path_to_lighttpd_php(self):
+ return "/usr/bin/php-cgi"
+
+ def _path_to_driver(self):
+ return self._build_path('test_shell')
+
+ def _path_to_helper(self):
+ return None
+
+ def _path_to_image_diff(self):
+ return self._build_path('image_diff')
+
+ def _path_to_wdiff(self):
+ return 'wdiff'
+
+ def _shut_down_http_server(self, server_pid):
+ """Shut down the lighttpd web server. Blocks until it's fully
+ shut down.
+
+ Args:
+ server_pid: The process ID of the running server.
+ """
+ # server_pid is not set when "http_server.py stop" is run manually.
+ if server_pid is None:
+ # TODO(mmoss) This isn't ideal, since it could conflict with
+ # lighttpd processes not started by http_server.py,
+ # but good enough for now.
+ self._kill_all_process('lighttpd')
+ self._kill_all_process('apache2')
+ else:
+ try:
+ os.kill(server_pid, signal.SIGTERM)
+ # TODO(mmoss) Maybe throw in a SIGKILL just to be sure?
+ except OSError:
+ # Sometimes we get a bad PID (e.g. from a stale httpd.pid
+ # file), so if kill fails on the given PID, just try to
+ # 'killall' web servers.
+ self._shut_down_http_server(None)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py
index d0fbc01..7e7b4ca 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_mac.py
@@ -27,175 +27,136 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""This is the Mac implementation of the port interface
- package. This file should only be imported by that package."""
+"""Chromium Mac implementation of the Port interface."""
import os
import platform
import signal
import subprocess
-import path_utils
-
-
-def platform_name():
- """Returns the name of the platform we're currently running on."""
- # At the moment all chromium mac results are version-independent. At some
- # point we may need to return 'chromium-mac' + PlatformVersion()
- return 'chromium-mac'
-
-
-def platform_version():
- """Returns the version string for the platform, e.g. '-vista' or
- '-snowleopard'. If the platform does not distinguish between
- minor versions, it returns ''."""
- os_version_string = platform.mac_ver()[0] # e.g. "10.5.6"
- if not os_version_string:
- return '-leopard'
-
- release_version = int(os_version_string.split('.')[1])
-
- # we don't support 'tiger' or earlier releases
- if release_version == 5:
- return '-leopard'
- elif release_version == 6:
- return '-snowleopard'
-
- return ''
-
-
-def get_num_cores():
- """Returns the number of cores on the machine. For hyperthreaded machines,
- this will be double the number of actual processors."""
- return int(os.popen2("sysctl -n hw.ncpu")[1].read())
-
-
-def baseline_path(platform=None):
- """Returns the path relative to the top of the source tree for the
- baselines for the specified platform version. If |platform| is None,
- then the version currently in use is used."""
- if platform is None:
- platform = platform_name()
- return path_utils.path_from_base('webkit', 'data', 'layout_tests',
- 'platform', platform, 'LayoutTests')
-
-# TODO: We should add leopard and snowleopard to the list of paths to check
-# once we start running the tests from snowleopard.
-
-
-def baseline_search_path(platform=None):
- """Returns the list of directories to search for baselines/results, in
- order of preference. Paths are relative to the top of the source tree."""
- return [baseline_path(platform),
- path_utils.webkit_baseline_path('mac' + platform_version()),
- path_utils.webkit_baseline_path('mac')]
-
-
-def wdiff_path():
- """Path to the WDiff executable, which we assume is already installed and
- in the user's $PATH."""
- return 'wdiff'
-
-
-def image_diff_path(target):
- """Path to the image_diff executable
-
- Args:
- target: build type - 'Debug','Release',etc."""
- return path_utils.path_from_base('xcodebuild', target, 'image_diff')
-
-
-def layout_test_helper_path(target):
- """Path to the layout_test_helper executable, if needed, empty otherwise
-
- Args:
- target: build type - 'Debug','Release',etc."""
- return path_utils.path_from_base('xcodebuild', target,
- 'layout_test_helper')
-
-
-def test_shell_path(target):
- """Path to the test_shell executable.
-
- Args:
- target: build type - 'Debug','Release',etc."""
- # TODO(pinkerton): make |target| happy with case-sensitive file systems.
- return path_utils.path_from_base('xcodebuild', target, 'TestShell.app',
- 'Contents', 'MacOS', 'TestShell')
-
-
-def apache_executable_path():
- """Returns the executable path to start Apache"""
- return os.path.join("/usr", "sbin", "httpd")
-
-
-def apache_config_file_path():
- """Returns the path to Apache config file"""
- return path_utils.path_from_base("third_party", "WebKit", "LayoutTests",
- "http", "conf", "apache2-httpd.conf")
-
-
-def lighttpd_executable_path():
- """Returns the executable path to start LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'mac',
- 'bin', 'lighttpd')
-
-
-def lighttpd_module_path():
- """Returns the library module path for LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'mac', 'lib')
-
-
-def lighttpd_php_path():
- """Returns the PHP executable path for LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'mac', 'bin',
- 'php-cgi')
-
-
-def shut_down_http_server(server_pid):
- """Shut down the lighttpd web server. Blocks until it's fully shut down.
-
- Args:
- server_pid: The process ID of the running server.
- """
- # server_pid is not set when "http_server.py stop" is run manually.
- if server_pid is None:
- # TODO(mmoss) This isn't ideal, since it could conflict with lighttpd
- # processes not started by http_server.py, but good enough for now.
- kill_all_process('lighttpd')
- kill_all_process('httpd')
- else:
- try:
- os.kill(server_pid, signal.SIGTERM)
- # TODO(mmoss) Maybe throw in a SIGKILL just to be sure?
- except OSError:
- # Sometimes we get a bad PID (e.g. from a stale httpd.pid file),
- # so if kill fails on the given PID, just try to 'killall' web
- # servers.
- shut_down_http_server(None)
-
-
-def kill_process(pid):
- """Forcefully kill the process.
-
- Args:
- pid: The id of the process to be killed.
- """
- os.kill(pid, signal.SIGKILL)
-
-
-def kill_all_process(process_name):
- # On Mac OS X 10.6, killall has a new constraint: -SIGNALNAME or
- # -SIGNALNUMBER must come first. Example problem:
- # $ killall -u $USER -TERM lighttpd
- # killall: illegal option -- T
- # Use of the earlier -TERM placement is just fine on 10.5.
- null = open(os.devnull)
- subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
- process_name], stderr=null)
- null.close()
-
-
-def kill_all_test_shells():
- """Kills all instances of the test_shell binary currently running."""
- kill_all_process('TestShell')
+import chromium
+
+
+class ChromiumMacPort(chromium.ChromiumPort):
+ """Chromium Mac implementation of the Port class."""
+
+ def __init__(self, port_name=None, options=None):
+ if port_name is None:
+ port_name = 'chromium-mac'
+ chromium.ChromiumPort.__init__(self, port_name, options)
+
+ def baseline_search_path(self):
+ return [self.baseline_path(),
+ self._webkit_baseline_path('mac' + self.version()),
+ self._webkit_baseline_path('mac')]
+
+ def check_sys_deps(self):
+ # We have no specific platform dependencies.
+ return True
+
+ def num_cores(self):
+ return int(subprocess.Popen(['sysctl','-n','hw.ncpu'],
+ stdout=subprocess.PIPE).stdout.read())
+
+ def test_platform_name(self):
+ # We use 'mac' instead of 'chromium-mac'
+ return 'mac'
+
+ def version(self):
+ os_version_string = platform.mac_ver()[0] # e.g. "10.5.6"
+ if not os_version_string:
+ return '-leopard'
+ release_version = int(os_version_string.split('.')[1])
+ # we don't support 'tiger' or earlier releases
+ if release_version == 5:
+ return '-leopard'
+ elif release_version == 6:
+ return '-snowleopard'
+ return ''
+
+ #
+ # PROTECTED METHODS
+ #
+
+ def _build_path(self, *comps):
+ return self.path_from_chromium_base('xcodebuild', self._options.target,
+ *comps)
+
+ def _lighttpd_path(self, *comps):
+ return self.path_from_chromium_base('third_party', 'lighttpd',
+ 'mac', *comps)
+
+ def _kill_process(self, pid):
+ """Forcefully kill the process.
+
+ Args:
+ pid: The id of the process to be killed.
+ """
+ os.kill(pid, signal.SIGKILL)
+
+ def _kill_all_process(self, process_name):
+ """Kill any processes running under this name."""
+ # On Mac OS X 10.6, killall has a new constraint: -SIGNALNAME or
+ # -SIGNALNUMBER must come first. Example problem:
+ # $ killall -u $USER -TERM lighttpd
+ # killall: illegal option -- T
+ # Use of the earlier -TERM placement is just fine on 10.5.
+ null = open(os.devnull)
+ subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
+ process_name], stderr=null)
+ null.close()
+
+ def _path_to_apache(self):
+ return '/usr/sbin/httpd'
+
+ def _path_to_apache_config_file(self):
+ return os.path.join(self.layout_tests_dir(), 'http', 'conf',
+ 'apache2-httpd.conf')
+
+ def _path_to_lighttpd(self):
+ return self._lighttp_path('bin', 'lighttp')
+
+ def _path_to_lighttpd_modules(self):
+ return self._lighttp_path('lib')
+
+ def _path_to_lighttpd_php(self):
+ return self._lighttpd_path('bin', 'php-cgi')
+
+ def _path_to_driver(self):
+ # TODO(pinkerton): make |target| happy with case-sensitive file
+ # systems.
+ return self._build_path('TestShell.app', 'Contents', 'MacOS',
+ 'TestShell')
+
+ def _path_to_helper(self):
+ return self._build_path('layout_test_helper')
+
+ def _path_to_image_diff(self):
+ return self._build_path('image_diff')
+
+ def _path_to_wdiff(self):
+ return 'wdiff'
+
+ def _shut_down_http_server(self, server_pid):
+ """Shut down the lighttpd web server. Blocks until it's fully
+ shut down.
+
+ Args:
+ server_pid: The process ID of the running server.
+ """
+ # server_pid is not set when "http_server.py stop" is run manually.
+ if server_pid is None:
+ # TODO(mmoss) This isn't ideal, since it could conflict with
+ # lighttpd processes not started by http_server.py,
+ # but good enough for now.
+ self._kill_all_process('lighttpd')
+ self._kill_all_process('httpd')
+ else:
+ try:
+ os.kill(server_pid, signal.SIGTERM)
+ # TODO(mmoss) Maybe throw in a SIGKILL just to be sure?
+ except OSError:
+ # Sometimes we get a bad PID (e.g. from a stale httpd.pid
+ # file), so if kill fails on the given PID, just try to
+ # 'killall' web servers.
+ self._shut_down_http_server(None)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
index 1e0b212..352916c 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/chromium_win.py
@@ -27,184 +27,129 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""This is the Linux implementation of the port
- package. This file should only be imported by that package."""
+"""Chromium Win implementation of the Port interface."""
import os
+import platform
+import signal
import subprocess
import sys
-import path_utils
+import chromium
-def platform_name():
- """Returns the name of the platform we're currently running on."""
- # We're not ready for version-specific results yet. When we uncomment
- # this, we also need to add it to the BaselineSearchPath()
- return 'chromium-win' + platform_version()
-
-def platform_version():
- """Returns the version string for the platform, e.g. '-vista' or
- '-snowleopard'. If the platform does not distinguish between
- minor versions, it returns ''."""
- winver = sys.getwindowsversion()
- if winver[0] == 6 and (winver[1] == 1):
- return '-7'
- if winver[0] == 6 and (winver[1] == 0):
- return '-vista'
- if winver[0] == 5 and (winver[1] == 1 or winver[1] == 2):
- return '-xp'
- return ''
-
-
-def get_num_cores():
- """Returns the number of cores on the machine. For hyperthreaded machines,
- this will be double the number of actual processors."""
- return int(os.environ.get('NUMBER_OF_PROCESSORS', 1))
-
-
-def baseline_path(platform=None):
- """Returns the path relative to the top of the source tree for the
- baselines for the specified platform version. If |platform| is None,
- then the version currently in use is used."""
- if platform is None:
- platform = platform_name()
- return path_utils.path_from_base('webkit', 'data', 'layout_tests',
- 'platform', platform, 'LayoutTests')
-
-
-def baseline_search_path(platform=None):
- """Returns the list of directories to search for baselines/results, in
- order of preference. Paths are relative to the top of the source tree."""
- dirs = []
- if platform is None:
- platform = platform_name()
-
- if platform == 'chromium-win-xp':
- dirs.append(baseline_path(platform))
- if platform in ('chromium-win-xp', 'chromium-win-vista'):
- dirs.append(baseline_path('chromium-win-vista'))
- dirs.append(baseline_path('chromium-win'))
- dirs.append(path_utils.webkit_baseline_path('win'))
- dirs.append(path_utils.webkit_baseline_path('mac'))
- return dirs
-
-
-def wdiff_path():
- """Path to the WDiff executable, whose binary is checked in on Win"""
- return path_utils.path_from_base('third_party', 'cygwin', 'bin',
- 'wdiff.exe')
-
-
-def image_diff_path(target):
- """Return the platform-specific binary path for the image compare util.
- We use this if we can't find the binary in the default location
- in path_utils.
-
- Args:
- target: Build target mode (debug or release)
- """
- return _find_binary(target, 'image_diff.exe')
-
-
-def layout_test_helper_path(target):
- """Return the platform-specific binary path for the layout test helper.
- We use this if we can't find the binary in the default location
- in path_utils.
-
- Args:
- target: Build target mode (debug or release)
- """
- return _find_binary(target, 'layout_test_helper.exe')
-
-
-def test_shell_path(target):
- """Return the platform-specific binary path for our TestShell.
- We use this if we can't find the binary in the default location
- in path_utils.
-
- Args:
- target: Build target mode (debug or release)
- """
- return _find_binary(target, 'test_shell.exe')
-
-
-def apache_executable_path():
- """Returns the executable path to start Apache"""
- path = path_utils.path_from_base('third_party', 'cygwin', "usr", "sbin")
- # Don't return httpd.exe since we want to use this from cygwin.
- return os.path.join(path, "httpd")
-
-
-def apache_config_file_path():
- """Returns the path to Apache config file"""
- return path_utils.path_from_base("third_party", "WebKit", "LayoutTests",
- "http", "conf", "cygwin-httpd.conf")
-
-
-def lighttpd_executable_path():
- """Returns the executable path to start LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'win',
- 'LightTPD.exe')
-
-
-def lighttpd_module_path():
- """Returns the library module path for LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'win', 'lib')
-
-
-def lighttpd_php_path():
- """Returns the PHP executable path for LigHTTPd"""
- return path_utils.path_from_base('third_party', 'lighttpd', 'win', 'php5',
- 'php-cgi.exe')
-
-
-def shut_down_http_server(server_pid):
- """Shut down the lighttpd web server. Blocks until it's fully shut down.
-
- Args:
- server_pid: The process ID of the running server.
- Unused in this implementation of the method.
- """
- subprocess.Popen(('taskkill.exe', '/f', '/im', 'LightTPD.exe'),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).wait()
- subprocess.Popen(('taskkill.exe', '/f', '/im', 'httpd.exe'),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).wait()
-
-
-def kill_process(pid):
- """Forcefully kill the process.
-
- Args:
- pid: The id of the process to be killed.
- """
- subprocess.call(('taskkill.exe', '/f', '/pid', str(pid)),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
-
-
-def kill_all_test_shells(self):
- """Kills all instances of the test_shell binary currently running."""
- subprocess.Popen(('taskkill.exe', '/f', '/im', 'test_shell.exe'),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).wait()
-
-#
-# Private helper functions.
-#
-
-
-def _find_binary(target, binary):
- """On Windows, we look for binaries that we compile in potentially
- two places: src/webkit/$target (preferably, which we get if we
- built using webkit_glue.gyp), or src/chrome/$target (if compiled some
- other way)."""
- try:
- return path_utils.path_from_base('webkit', target, binary)
- except path_utils.PathNotFound:
- try:
- return path_utils.path_from_base('chrome', target, binary)
- except path_utils.PathNotFound:
- return path_utils.path_from_base('build', target, binary)
+class ChromiumWinPort(chromium.ChromiumPort):
+ """Chromium Win implementation of the Port class."""
+
+ def __init__(self, port_name=None, options=None):
+ if port_name is None:
+ port_name = 'chromium-win' + self.version()
+ chromium.ChromiumPort.__init__(self, port_name, options)
+
+ def baseline_search_path(self):
+ dirs = []
+ if self._name == 'chromium-win-xp':
+ dirs.append(self._chromium_baseline_path(self._name))
+ if self._name in ('chromium-win-xp', 'chromium-win-vista'):
+ dirs.append(self._chromium_baseline_path('chromium-win-vista'))
+ dirs.append(self._chromium_baseline_path('chromium-win'))
+ dirs.append(self._webkit_baseline_path('win'))
+ dirs.append(self._webkit_baseline_path('mac'))
+ return dirs
+
+ def check_sys_deps(self):
+ # TODO(dpranke): implement this
+ return True
+
+ def get_absolute_path(self, filename):
+ """Return the absolute path in unix format for the given filename."""
+ abspath = os.path.abspath(filename)
+ return abspath.replace('\\', '/')
+
+ def num_cores(self):
+ return int(os.environ.get('NUMBER_OF_PROCESSORS', 1))
+
+ def relative_test_filename(self, filename):
+ path = filename[len(self.layout_tests_dir()) + 1:]
+ return path.replace('\\', '/')
+
+ def test_platform_name(self):
+ # We return 'win-xp', not 'chromium-win-xp' here, for convenience.
+ return 'win' + self.version()
+
+ def version(self):
+ winver = sys.getwindowsversion()
+ if winver[0] == 6 and (winver[1] == 1):
+ return '-7'
+ if winver[0] == 6 and (winver[1] == 0):
+ return '-vista'
+ if winver[0] == 5 and (winver[1] == 1 or winver[1] == 2):
+ return '-xp'
+ return ''
+
+ #
+ # PROTECTED ROUTINES
+ #
+
+ def _build_path(self, *comps):
+ # FIXME(dpranke): allow for builds under 'chrome' as well.
+ return self.path_from_chromium_base('webkit', self._options.target,
+ *comps)
+
+ def _lighttpd_path(self, *comps):
+ return self.path_from_chromium_base('third_party', 'lighttpd', 'win',
+ *comps)
+
+ def _kill_process(self, pid):
+ """Forcefully kill the process.
+
+ Args:
+ pid: The id of the process to be killed.
+ """
+ subprocess.call(('taskkill.exe', '/f', '/pid', str(pid)),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ def _path_to_apache(self):
+ return self.path_from_chromium_base('third_party', 'cygwin', 'usr',
+ 'sbin', 'httpd')
+
+ def _path_to_apache_config_file(self):
+ return os.path.join(self.layout_tests_dir(), 'http', 'conf',
+ 'cygwin-httpd.conf')
+
+ def _path_to_lighttpd(self):
+ return self._lighttpd_path('LightTPD.exe')
+
+ def _path_to_lighttpd_modules(self):
+ return self._lighttpd_path('lib')
+
+ def _path_to_lighttpd_php(self):
+ return self._lighttpd_path('php5', 'php-cgi.exe')
+
+ def _path_to_driver(self):
+ return self._build_path('test_shell.exe')
+
+ def _path_to_helper(self):
+ return self._build_path('layout_test_helper.exe')
+
+ def _path_to_image_diff(self):
+ return self._build_path('image_diff.exe')
+
+ def _path_to_wdiff(self):
+ return self.path_from_chromium_base('third_party', 'cygwin', 'bin',
+ 'wdiff.exe')
+
+ def _shut_down_http_server(self, server_pid):
+ """Shut down the lighttpd web server. Blocks until it's fully
+ shut down.
+
+ Args:
+ server_pid: The process ID of the running server.
+ """
+ subprocess.Popen(('taskkill.exe', '/f', '/im', 'LightTPD.exe'),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).wait()
+ subprocess.Popen(('taskkill.exe', '/f', '/im', 'httpd.exe'),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).wait()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py
index 99e2ea1..0315704 100755
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server.py
@@ -41,52 +41,21 @@ import time
import urllib
import http_server_base
-import path_utils
-class HttpdNotStarted(Exception): pass
-def remove_log_files(folder, starts_with):
- files = os.listdir(folder)
- for file in files:
- if file.startswith(starts_with):
- full_path = os.path.join(folder, file)
- os.remove(full_path)
+class HttpdNotStarted(Exception):
+ pass
class Lighttpd(http_server_base.HttpServerBase):
- # Webkit tests
- try:
- _webkit_tests = path_utils.path_from_base('third_party', 'WebKit',
- 'LayoutTests', 'http',
- 'tests')
- _js_test_resource = path_utils.path_from_base('third_party', 'WebKit',
- 'LayoutTests', 'fast',
- 'js', 'resources')
- except path_utils.PathNotFound:
- _webkit_tests = None
- _js_test_resource = None
-
- # Path where we can access all of the tests
- _all_tests = path_utils.path_from_base('webkit', 'data', 'layout_tests')
- # Self generated certificate for SSL server (for client cert get
- # <base-path>\chrome\test\data\ssl\certs\root_ca_cert.crt)
- _pem_file = path_utils.path_from_base(
- os.path.dirname(os.path.abspath(__file__)), 'httpd2.pem')
- # One mapping where we can get to everything
- VIRTUALCONFIG = [{'port': 8081, 'docroot': _all_tests}]
-
- if _webkit_tests:
- VIRTUALCONFIG.extend(
- # Three mappings (one with SSL enabled) for LayoutTests http tests
- [{'port': 8000, 'docroot': _webkit_tests},
- {'port': 8080, 'docroot': _webkit_tests},
- {'port': 8443, 'docroot': _webkit_tests, 'sslcert': _pem_file}])
-
- def __init__(self, output_dir, background=False, port=None,
+
+ def __init__(self, port_obj, output_dir, background=False, port=None,
root=None, register_cygwin=None, run_background=None):
"""Args:
output_dir: the absolute path to the layout test result directory
"""
+ # Webkit tests
+ http_server_base.HttpServerBase.__init__(self, port_obj)
self._output_dir = output_dir
self._process = None
self._port = port
@@ -96,6 +65,31 @@ class Lighttpd(http_server_base.HttpServerBase):
if self._port:
self._port = int(self._port)
+ try:
+ self._webkit_tests = os.path.join(
+ self._port_obj.layout_tests_dir(), 'http', 'tests')
+ self._js_test_resource = os.path.join(
+ self._port_obj.layout_tests_dir(), 'fast', 'js', 'resources')
+ except:
+ self._webkit_tests = None
+ self._js_test_resource = None
+
+ # Self generated certificate for SSL server (for client cert get
+ # <base-path>\chrome\test\data\ssl\certs\root_ca_cert.crt)
+ self._pem_file = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), 'httpd2.pem')
+
+ # One mapping where we can get to everything
+ self.VIRTUALCONFIG = []
+
+ if self._webkit_tests:
+ self.VIRTUALCONFIG.extend(
+ # Three mappings (one with SSL) for LayoutTests http tests
+ [{'port': 8000, 'docroot': self._webkit_tests},
+ {'port': 8080, 'docroot': self._webkit_tests},
+ {'port': 8443, 'docroot': self._webkit_tests,
+ 'sslcert': self._pem_file}])
+
def is_running(self):
return self._process != None
@@ -103,9 +97,8 @@ class Lighttpd(http_server_base.HttpServerBase):
if self.is_running():
raise 'Lighttpd already running'
- base_conf_file = path_utils.path_from_base('third_party',
- 'WebKitTools', 'Scripts', 'webkitpy', 'layout_tests',
- 'layout_package', 'lighttpd.conf')
+ base_conf_file = self._port_obj.path_from_webkit_base('WebKitTools',
+ 'Scripts', 'webkitpy', 'layout_tests', 'port', 'lighttpd.conf')
out_conf_file = os.path.join(self._output_dir, 'lighttpd.conf')
time_str = time.strftime("%d%b%Y-%H%M%S")
access_file_name = "access.log-" + time_str + ".txt"
@@ -114,8 +107,8 @@ class Lighttpd(http_server_base.HttpServerBase):
error_log = os.path.join(self._output_dir, log_file_name)
# Remove old log files. We only need to keep the last ones.
- remove_log_files(self._output_dir, "access.log-")
- remove_log_files(self._output_dir, "error.log-")
+ self.remove_log_files(self._output_dir, "access.log-")
+ self.remove_log_files(self._output_dir, "error.log-")
# Write out the config
f = file(base_conf_file, 'rb')
@@ -132,7 +125,7 @@ class Lighttpd(http_server_base.HttpServerBase):
' ".pl" => "/usr/bin/env",\n'
' ".asis" => "/bin/cat",\n'
' ".php" => "%s" )\n\n') %
- path_utils.lighttpd_php_path())
+ self._port_obj._path_to_lighttpd_php())
# Setup log files
f.write(('server.errorlog = "%s"\n'
@@ -161,7 +154,7 @@ class Lighttpd(http_server_base.HttpServerBase):
mappings = [{'port': 8000, 'docroot': self._root},
{'port': 8080, 'docroot': self._root},
{'port': 8443, 'docroot': self._root,
- 'sslcert': Lighttpd._pem_file}]
+ 'sslcert': self._pem_file}]
else:
mappings = self.VIRTUALCONFIG
for mapping in mappings:
@@ -176,12 +169,11 @@ class Lighttpd(http_server_base.HttpServerBase):
'}\n\n') % (mapping['port'], mapping['docroot']))
f.close()
- executable = path_utils.lighttpd_executable_path()
- module_path = path_utils.lighttpd_module_path()
+ executable = self._port_obj._path_to_lighttpd()
+ module_path = self._port_obj._path_to_lighttpd_modules()
start_cmd = [executable,
# Newly written config file
- '-f', path_utils.path_from_base(self._output_dir,
- 'lighttpd.conf'),
+ '-f', os.path.join(self._output_dir, 'lighttpd.conf'),
# Where it can find its module dynamic libraries
'-m', module_path]
@@ -203,12 +195,13 @@ class Lighttpd(http_server_base.HttpServerBase):
env = os.environ
if sys.platform in ('cygwin', 'win32'):
env['PATH'] = '%s;%s' % (
- path_utils.path_from_base('third_party', 'cygwin', 'bin'),
+ self._port_obj.path_from_chromium_base('third_party',
+ 'cygwin', 'bin'),
env['PATH'])
if sys.platform == 'win32' and self._register_cygwin:
- setup_mount = path_utils.path_from_base('third_party', 'cygwin',
- 'setup_mount.bat')
+ setup_mount = port.path_from_chromium_base('third_party',
+ 'cygwin', 'setup_mount.bat')
subprocess.Popen(setup_mount).wait()
logging.debug('Starting http server')
@@ -235,7 +228,7 @@ class Lighttpd(http_server_base.HttpServerBase):
httpd_pid = None
if self._process:
httpd_pid = self._process.pid
- path_utils.shut_down_http_server(httpd_pid)
+ self._port_obj._shut_down_http_server(httpd_pid)
if self._process:
self._process.wait()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py
index 026e070..e82943e 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_server_base.py
@@ -30,12 +30,16 @@
"""Base class with common routines between the Apache and Lighttpd servers."""
import logging
+import os
import time
import urllib
class HttpServerBase(object):
+ def __init__(self, port_obj):
+ self._port_obj = port_obj
+
def wait_for_action(self, action):
"""Repeat the action for 20 seconds or until it succeeds. Returns
whether it succeeded."""
@@ -65,3 +69,10 @@ class HttpServerBase(object):
return False
return True
+
+ def remove_log_files(self, folder, starts_with):
+ files = os.listdir(folder)
+ for file in files:
+ if file.startswith(starts_with):
+ full_path = os.path.join(folder, file)
+ os.remove(full_path)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py
new file mode 100644
index 0000000..4b73cec
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py
@@ -0,0 +1,439 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 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 Google name 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.
+
+"""WebKit Mac implementation of the Port interface."""
+
+import fcntl
+import logging
+import os
+import pdb
+import platform
+import select
+import signal
+import subprocess
+import sys
+import time
+import webbrowser
+
+import base
+
+import webkitpy
+from webkitpy import executive
+
+class MacPort(base.Port):
+ """WebKit Mac implementation of the Port class."""
+
+ def __init__(self, port_name=None, options=None):
+ if port_name is None:
+ port_name = 'mac' + self.version()
+ base.Port.__init__(self, port_name, options)
+ self._cached_build_root = None
+
+ def baseline_search_path(self):
+ dirs = []
+ if self._name == 'mac-tiger':
+ dirs.append(self._webkit_baseline_path(self._name))
+ if self._name in ('mac-tiger', 'mac-leopard'):
+ dirs.append(self._webkit_baseline_path('mac-leopard'))
+ if self._name in ('mac-tiger', 'mac-leopard', 'mac-snowleopard'):
+ dirs.append(self._webkit_baseline_path('mac-snowleopard'))
+ dirs.append(self._webkit_baseline_path('mac'))
+ return dirs
+
+ def check_sys_deps(self):
+ # FIXME: This should run build-dumprendertree.
+ # This should also validate that all of the tool paths are valid.
+ return True
+
+ def num_cores(self):
+ return int(os.popen2("sysctl -n hw.ncpu")[1].read())
+
+ def results_directory(self):
+ return ('/tmp/run-chromium-webkit-tests-' +
+ self._options.results_directory)
+
+ def setup_test_run(self):
+ # This port doesn't require any specific configuration.
+ pass
+
+ def show_results_html_file(self, results_filename):
+ uri = self.filename_to_uri(results_filename)
+ webbrowser.open(uri, new=1)
+
+ def start_driver(self, image_path, options):
+ """Starts a new Driver and returns a handle to it."""
+ return MacDriver(self, image_path, options)
+
+ def start_helper(self):
+ # This port doesn't use a helper process.
+ pass
+
+ def stop_helper(self):
+ # This port doesn't use a helper process.
+ pass
+
+ def test_base_platform_names(self):
+ # At the moment we don't use test platform names, but we have
+ # to return something.
+ return ('mac',)
+
+ def test_expectations(self):
+ #
+ # The WebKit mac port uses 'Skipped' files at the moment. Each
+ # file contains a list of files or directories to be skipped during
+ # the test run. The total list of tests to skipped is given by the
+ # contents of the generic Skipped file found in platform/X plus
+ # a version-specific file found in platform/X-version. Duplicate
+ # entries are allowed. This routine reads those files and turns
+ # contents into the format expected by test_expectations.
+ expectations = []
+ skipped_files = []
+ if self._name in ('mac-tiger', 'mac-leopard', 'mac-snowleopard'):
+ skipped_files.append(os.path.join(
+ self._webkit_baseline_path(self._name), 'Skipped'))
+ skipped_files.append(os.path.join(self._webkit_baseline_path('mac'),
+ 'Skipped'))
+ for filename in skipped_files:
+ if os.path.exists(filename):
+ f = file(filename)
+ for l in f.readlines():
+ l = l.strip()
+ if not l.startswith('#') and len(l):
+ l = 'BUG_SKIPPED SKIP : ' + l + ' = FAIL'
+ if l not in expectations:
+ expectations.append(l)
+ f.close()
+
+ # TODO - figure out how to check for these dynamically
+ expectations.append('BUG_SKIPPED SKIP : fast/wcss = FAIL')
+ expectations.append('BUG_SKIPPED SKIP : fast/xhtmlmp = FAIL')
+ expectations.append('BUG_SKIPPED SKIP : http/tests/wml = FAIL')
+ expectations.append('BUG_SKIPPED SKIP : mathml = FAIL')
+ expectations.append('BUG_SKIPPED SKIP : platform/chromium = FAIL')
+ expectations.append('BUG_SKIPPED SKIP : platform/gtk = FAIL')
+ expectations.append('BUG_SKIPPED SKIP : platform/qt = FAIL')
+ expectations.append('BUG_SKIPPED SKIP : platform/win = FAIL')
+ expectations.append('BUG_SKIPPED SKIP : wml = FAIL')
+
+ # TODO - figure out how to handle webarchive tests
+ expectations.append('BUG_SKIPPED SKIP : webarchive = PASS')
+ expectations.append('BUG_SKIPPED SKIP : svg/webarchive = PASS')
+ expectations.append('BUG_SKIPPED SKIP : http/tests/webarchive = PASS')
+ expectations.append('BUG_SKIPPED SKIP : svg/custom/'
+ 'image-with-prefix-in-webarchive.svg = PASS')
+
+ expectations_str = '\n'.join(expectations)
+ return expectations_str
+
+ def test_platform_name(self):
+ # At the moment we don't use test platform names, but we have
+ # to return something.
+ return 'mac'
+
+ def test_platform_names(self):
+ # At the moment we don't use test platform names, but we have
+ # to return something.
+ return ('mac',)
+
+ def version(self):
+ os_version_string = platform.mac_ver()[0] # e.g. "10.5.6"
+ if not os_version_string:
+ return '-leopard'
+ release_version = int(os_version_string.split('.')[1])
+ if release_version == 4:
+ return '-tiger'
+ elif release_version == 5:
+ return '-leopard'
+ elif release_version == 6:
+ return '-snowleopard'
+ return ''
+
+ #
+ # PROTECTED METHODS
+ #
+
+ def _build_path(self, *comps):
+ if not self._cached_build_root:
+ self._cached_build_root = executive.run_command(["webkit-build-directory", "--base"]).rstrip()
+ return os.path.join(self._cached_build_root, self._options.target, *comps)
+
+ def _kill_process(self, pid):
+ """Forcefully kill the process.
+
+ Args:
+ pid: The id of the process to be killed.
+ """
+ os.kill(pid, signal.SIGKILL)
+
+ def _kill_all_process(self, process_name):
+ # On Mac OS X 10.6, killall has a new constraint: -SIGNALNAME or
+ # -SIGNALNUMBER must come first. Example problem:
+ # $ killall -u $USER -TERM lighttpd
+ # killall: illegal option -- T
+ # Use of the earlier -TERM placement is just fine on 10.5.
+ null = open(os.devnull)
+ subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
+ process_name], stderr=null)
+ null.close()
+
+ def _path_to_apache(self):
+ return '/usr/sbin/httpd'
+
+ def _path_to_apache_config_file(self):
+ return os.path.join(self.layout_tests_dir(), 'http', 'conf',
+ 'apache2-httpd.conf')
+
+ def _path_to_driver(self):
+ return self._build_path('DumpRenderTree')
+
+ def _path_to_helper(self):
+ return None
+
+ def _path_to_image_diff(self):
+ return self._build_path('image_diff') # FIXME: This is wrong and should be "ImageDiff", but having the correct path causes other parts of the script to hang.
+
+ def _path_to_wdiff(self):
+ return 'wdiff' # FIXME: This does not exist on a default Mac OS X Leopard install.
+
+ def _shut_down_http_server(self, server_pid):
+ """Shut down the lighttpd web server. Blocks until it's fully
+ shut down.
+
+ Args:
+ server_pid: The process ID of the running server.
+ """
+ # server_pid is not set when "http_server.py stop" is run manually.
+ if server_pid is None:
+ # TODO(mmoss) This isn't ideal, since it could conflict with
+ # lighttpd processes not started by http_server.py,
+ # but good enough for now.
+ self._kill_all_process('httpd')
+ else:
+ try:
+ os.kill(server_pid, signal.SIGTERM)
+ # TODO(mmoss) Maybe throw in a SIGKILL just to be sure?
+ except OSError:
+ # Sometimes we get a bad PID (e.g. from a stale httpd.pid
+ # file), so if kill fails on the given PID, just try to
+ # 'killall' web servers.
+ self._shut_down_http_server(None)
+
+
+class MacDriver(base.Driver):
+ """implementation of the DumpRenderTree interface."""
+
+ def __init__(self, port, image_path, driver_options):
+ self._port = port
+ self._driver_options = driver_options
+ self._target = port._options.target
+ self._image_path = image_path
+ self._stdout_fd = None
+ self._cmd = None
+ self._env = None
+ self._proc = None
+ self._read_buffer = ''
+
+ cmd = []
+ # Hook for injecting valgrind or other runtime instrumentation,
+ # used by e.g. tools/valgrind/valgrind_tests.py.
+ wrapper = os.environ.get("BROWSER_WRAPPER", None)
+ if wrapper != None:
+ cmd += [wrapper]
+ if self._port._options.wrapper:
+ # This split() isn't really what we want -- it incorrectly will
+ # split quoted strings within the wrapper argument -- but in
+ # practice it shouldn't come up and the --help output warns
+ # about it anyway.
+ cmd += self._options.wrapper.split()
+ # FIXME: Using arch here masks any possible file-not-found errors from a non-existant driver executable.
+ cmd += ['arch', '-i386', port._path_to_driver(), '-']
+
+ # FIXME: This is a hack around our lack of ImageDiff support for now.
+ if not self._port._options.no_pixel_tests:
+ logging.warn("This port does not yet support pixel tests.")
+ self._port._options.no_pixel_tests = True
+ #cmd.append('--pixel-tests')
+
+ #if driver_options:
+ # cmd += driver_options
+ env = os.environ
+ env['DYLD_FRAMEWORK_PATH'] = self._port._build_path()
+ self._cmd = cmd
+ self._env = env
+ self.restart()
+
+ def poll(self):
+ return self._proc.poll()
+
+ def restart(self):
+ self.stop()
+ self._proc = subprocess.Popen(self._cmd, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=self._env)
+
+ def returncode(self):
+ return self._proc.returncode
+
+ def run_test(self, uri, timeoutms, image_hash):
+ output = []
+ error = []
+ image = ''
+ crash = False
+ timeout = False
+ actual_uri = None
+ actual_image_hash = None
+
+ if uri.startswith("file:///"):
+ cmd = uri[7:]
+ else:
+ cmd = uri
+
+ if image_hash:
+ cmd += "'" + image_hash
+ cmd += "\n"
+
+ self._proc.stdin.write(cmd)
+ self._stdout_fd = self._proc.stdout.fileno()
+ fl = fcntl.fcntl(self._stdout_fd, fcntl.F_GETFL)
+ fcntl.fcntl(self._stdout_fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+
+ stop_time = time.time() + (int(timeoutms) / 1000.0)
+ resp = ''
+ (timeout, line) = self._read_line(timeout, stop_time)
+ resp += line
+ have_seen_content_type = False
+ while not timeout and line.rstrip() != "#EOF":
+ # Make sure we haven't crashed.
+ if line == '' and self.poll() is not None:
+ # This is hex code 0xc000001d, which is used for abrupt
+ # termination. This happens if we hit ctrl+c from the prompt
+ # and we happen to be waiting on the test_shell.
+ # sdoyon: Not sure for which OS and in what circumstances the
+ # above code is valid. What works for me under Linux to detect
+ # ctrl+c is for the subprocess returncode to be negative
+ # SIGINT. And that agrees with the subprocess documentation.
+ if (-1073741510 == self.returncode() or
+ - signal.SIGINT == self.returncode()):
+ raise KeyboardInterrupt
+ crash = True
+ break
+
+ elif (line.startswith('Content-Type:') and not
+ have_seen_content_type):
+ have_seen_content_type = True
+ pass
+ else:
+ output.append(line)
+
+ (timeout, line) = self._read_line(timeout, stop_time)
+ resp += line
+
+ # Now read a second block of text for the optional image data
+ image_length = 0
+ (timeout, line) = self._read_line(timeout, stop_time)
+ resp += line
+ HASH_HEADER = 'ActualHash: '
+ LENGTH_HEADER = 'Content-Length: '
+ while not timeout and not crash and line.rstrip() != "#EOF":
+ if line == '' and self.poll() is not None:
+ if (-1073741510 == self.returncode() or
+ - signal.SIGINT == self.returncode()):
+ raise KeyboardInterrupt
+ crash = True
+ break
+ elif line.startswith(HASH_HEADER):
+ actual_image_hash = line[len(HASH_HEADER):].strip()
+ elif line.startswith('Content-Type:'):
+ pass
+ elif line.startswith(LENGTH_HEADER):
+ image_length = int(line[len(LENGTH_HEADER):])
+ elif image_length:
+ image += line
+
+ (timeout, line) = self._read_line(timeout, stop_time, image_length)
+ resp += line
+
+ if timeout:
+ self.restart()
+
+ if self._image_path and len(self._image_path):
+ image_file = file(self._image_path, "wb")
+ image_file.write(image)
+ image_file.close()
+
+ return (crash, timeout, actual_image_hash,
+ ''.join(output), ''.join(error))
+ pass
+
+ def stop(self):
+ if self._proc:
+ self._proc.stdin.close()
+ self._proc.stdout.close()
+ if self._proc.stderr:
+ self._proc.stderr.close()
+ if (sys.platform not in ('win32', 'cygwin') and
+ not self._proc.poll()):
+ # Closing stdin/stdout/stderr hangs sometimes on OS X.
+ null = open(os.devnull, "w")
+ subprocess.Popen(["kill", "-9",
+ str(self._proc.pid)], stderr=null)
+ null.close()
+
+ def _read_line(self, timeout, stop_time, image_length=0):
+ now = time.time()
+ read_fds = []
+
+ # first check to see if we have a line already read or if we've
+ # read the entire image
+ if image_length and len(self._read_buffer) >= image_length:
+ out = self._read_buffer[0:image_length]
+ self._read_buffer = self._read_buffer[image_length:]
+ return (timeout, out)
+
+ idx = self._read_buffer.find('\n')
+ if not image_length and idx != -1:
+ out = self._read_buffer[0:idx + 1]
+ self._read_buffer = self._read_buffer[idx + 1:]
+ return (timeout, out)
+
+ # If we've timed out, return just what we have, if anything
+ if timeout or now >= stop_time:
+ out = self._read_buffer
+ self._read_buffer = ''
+ return (True, out)
+
+ (read_fds, write_fds, err_fds) = select.select(
+ [self._stdout_fd], [], [], stop_time - now)
+ try:
+ if timeout or len(read_fds) == 1:
+ self._read_buffer += self._proc.stdout.read()
+ except IOError, e:
+ read = []
+ return self._read_line(timeout, stop_time)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/path_utils.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/path_utils.py
deleted file mode 100644
index 70b8c03..0000000
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/path_utils.py
+++ /dev/null
@@ -1,395 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2010 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.
-
-"""This package contains utility methods for manipulating paths and
-filenames for test results and baselines. It also contains wrappers
-of a few routines in port/ so that the port package can
-be considered a 'protected' package - i.e., this file should be
-the only file that ever includes port. This leads to
-us including a few things that don't really have anything to do
- with paths, unfortunately."""
-
-import errno
-import os
-import stat
-import sys
-
-import port
-import chromium_win
-import chromium_mac
-import chromium_linux
-
-# Cache some values so we don't have to recalculate them. _basedir is
-# used by PathFromBase() and caches the full (native) path to the top
-# of the source tree (/src). _baseline_search_path is used by
-# ExpectedBaselines() and caches the list of native paths to search
-# for baseline results.
-_basedir = None
-_baseline_search_path = None
-
-
-class PathNotFound(Exception):
- pass
-
-
-def layout_tests_dir():
- """Returns the fully-qualified path to the directory containing the input
- data for the specified layout test."""
- return path_from_base('third_party', 'WebKit', 'LayoutTests')
-
-
-def chromium_baseline_path(platform=None):
- """Returns the full path to the directory containing expected
- baseline results from chromium ports. If |platform| is None, the
- currently executing platform is used.
-
- Note: although directly referencing individual port/* files is
- usually discouraged, we allow it here so that the rebaselining tool can
- pull baselines for platforms other than the host platform."""
-
- # Normalize the platform string.
- platform = platform_name(platform)
- if platform.startswith('chromium-mac'):
- return chromium_mac.baseline_path(platform)
- elif platform.startswith('chromium-win'):
- return chromium_win.baseline_path(platform)
- elif platform.startswith('chromium-linux'):
- return chromium_linux.baseline_path(platform)
-
- return port.baseline_path()
-
-
-def webkit_baseline_path(platform):
- """Returns the full path to the directory containing expected
- baseline results from WebKit ports."""
- return path_from_base('third_party', 'WebKit', 'LayoutTests',
- 'platform', platform)
-
-
-def baseline_search_path(platform=None):
- """Returns the list of directories to search for baselines/results for a
- given platform, in order of preference. Paths are relative to the top of
- the source tree. If parameter platform is None, returns the list for the
- current platform that the script is running on.
-
- Note: although directly referencing individual port/* files is
- usually discouraged, we allow it here so that the rebaselining tool can
- pull baselines for platforms other than the host platform."""
-
- # Normalize the platform name.
- platform = platform_name(platform)
- if platform.startswith('chromium-mac'):
- return chromium_mac.baseline_search_path(platform)
- elif platform.startswith('chromium-win'):
- return chromium_win.baseline_search_path(platform)
- elif platform.startswith('chromium-linux'):
- return chromium_linux.baseline_search_path(platform)
- return port.baseline_search_path()
-
-
-def expected_baselines(filename, suffix, platform=None, all_baselines=False):
- """Given a test name, finds where the baseline results are located.
-
- Args:
- filename: absolute filename to test file
- suffix: file suffix of the expected results, including dot; e.g. '.txt'
- or '.png'. This should not be None, but may be an empty string.
- platform: layout test platform: 'win', 'linux' or 'mac'. Defaults to
- the current platform.
- all_baselines: If True, return an ordered list of all baseline paths
- for the given platform. If False, return only the first
- one.
- Returns
- a list of ( platform_dir, results_filename ), where
- platform_dir - abs path to the top of the results tree (or test tree)
- results_filename - relative path from top of tree to the results file
- (os.path.join of the two gives you the full path to the file,
- unless None was returned.)
- Return values will be in the format appropriate for the current platform
- (e.g., "\\" for path separators on Windows). If the results file is not
- found, then None will be returned for the directory, but the expected
- relative pathname will still be returned.
- """
- global _baseline_search_path
- global _search_path_platform
- testname = os.path.splitext(relative_test_filename(filename))[0]
-
- baseline_filename = testname + '-expected' + suffix
-
- if (_baseline_search_path is None) or (_search_path_platform != platform):
- _baseline_search_path = baseline_search_path(platform)
- _search_path_platform = platform
-
- baselines = []
- for platform_dir in _baseline_search_path:
- if os.path.exists(os.path.join(platform_dir, baseline_filename)):
- baselines.append((platform_dir, baseline_filename))
-
- if not all_baselines and baselines:
- return baselines
-
- # If it wasn't found in a platform directory, return the expected result
- # in the test directory, even if no such file actually exists.
- platform_dir = layout_tests_dir()
- if os.path.exists(os.path.join(platform_dir, baseline_filename)):
- baselines.append((platform_dir, baseline_filename))
-
- if baselines:
- return baselines
-
- return [(None, baseline_filename)]
-
-
-def expected_filename(filename, suffix):
- """Given a test name, returns an absolute path to its expected results.
-
- If no expected results are found in any of the searched directories, the
- directory in which the test itself is located will be returned. The return
- value is in the format appropriate for the platform (e.g., "\\" for
- path separators on windows).
-
- Args:
- filename: absolute filename to test file
- suffix: file suffix of the expected results, including dot; e.g. '.txt'
- or '.png'. This should not be None, but may be an empty string.
- platform: the most-specific directory name to use to build the
- search list of directories, e.g., 'chromium-win', or
- 'chromium-mac-leopard' (we follow the WebKit format)
- """
- platform_dir, baseline_filename = expected_baselines(filename, suffix)[0]
- if platform_dir:
- return os.path.join(platform_dir, baseline_filename)
- return os.path.join(layout_tests_dir(), baseline_filename)
-
-
-def relative_test_filename(filename):
- """Provide the filename of the test relative to the layout tests
- directory as a unix style path (a/b/c)."""
- return _win_path_to_unix(filename[len(layout_tests_dir()) + 1:])
-
-
-def _win_path_to_unix(path):
- """Convert a windows path to use unix-style path separators (a/b/c)."""
- return path.replace('\\', '/')
-
-#
-# Routines that are arguably platform-specific but have been made
-# generic for now
-#
-
-
-def filename_to_uri(full_path):
- """Convert a test file to a URI."""
- LAYOUTTEST_HTTP_DIR = "http/tests/"
- LAYOUTTEST_WEBSOCKET_DIR = "websocket/tests/"
-
- relative_path = _win_path_to_unix(relative_test_filename(full_path))
- port = None
- use_ssl = False
-
- if relative_path.startswith(LAYOUTTEST_HTTP_DIR):
- # http/tests/ run off port 8000 and ssl/ off 8443
- relative_path = relative_path[len(LAYOUTTEST_HTTP_DIR):]
- port = 8000
- elif relative_path.startswith(LAYOUTTEST_WEBSOCKET_DIR):
- # websocket/tests/ run off port 8880 and 9323
- # Note: the root is /, not websocket/tests/
- port = 8880
-
- # Make http/tests/local run as local files. This is to mimic the
- # logic in run-webkit-tests.
- # TODO(jianli): Consider extending this to "media/".
- if port and not relative_path.startswith("local/"):
- if relative_path.startswith("ssl/"):
- port += 443
- protocol = "https"
- else:
- protocol = "http"
- return "%s://127.0.0.1:%u/%s" % (protocol, port, relative_path)
-
- if sys.platform in ('cygwin', 'win32'):
- return "file:///" + get_absolute_path(full_path)
- return "file://" + get_absolute_path(full_path)
-
-
-def get_absolute_path(path):
- """Returns an absolute UNIX path."""
- return _win_path_to_unix(os.path.abspath(path))
-
-
-def maybe_make_directory(*path):
- """Creates the specified directory if it doesn't already exist."""
- try:
- os.makedirs(os.path.join(*path))
- except OSError, e:
- if e.errno != errno.EEXIST:
- raise
-
-
-def path_from_base(*comps):
- """Returns an absolute filename from a set of components specified
- relative to the top of the source tree. If the path does not exist,
- the exception PathNotFound is raised."""
- global _basedir
- if _basedir == None:
- # We compute the top of the source tree by finding the absolute
- # path of this source file, and then climbing up three directories
- # as given in subpath. If we move this file, subpath needs to be
- # updated.
- path = os.path.abspath(__file__)
- subpath = os.path.join('third_party', 'WebKit')
- _basedir = path[:path.index(subpath)]
- path = os.path.join(_basedir, *comps)
- if not os.path.exists(path):
- raise PathNotFound('could not find %s' % (path))
- return path
-
-
-def remove_directory(*path):
- """Recursively removes a directory, even if it's marked read-only.
-
- Remove the directory located at *path, if it exists.
-
- shutil.rmtree() doesn't work on Windows if any of the files or directories
- are read-only, which svn repositories and some .svn files are. We need to
- be able to force the files to be writable (i.e., deletable) as we traverse
- the tree.
-
- Even with all this, Windows still sometimes fails to delete a file, citing
- a permission error (maybe something to do with antivirus scans or disk
- indexing). The best suggestion any of the user forums had was to wait a
- bit and try again, so we do that too. It's hand-waving, but sometimes it
- works. :/
- """
- file_path = os.path.join(*path)
- if not os.path.exists(file_path):
- return
-
- win32 = False
- if sys.platform == 'win32':
- win32 = True
- # Some people don't have the APIs installed. In that case we'll do
- # without.
- try:
- win32api = __import__('win32api')
- win32con = __import__('win32con')
- except ImportError:
- win32 = False
-
- def remove_with_retry(rmfunc, path):
- os.chmod(path, stat.S_IWRITE)
- if win32:
- win32api.SetFileAttributes(path,
- win32con.FILE_ATTRIBUTE_NORMAL)
- try:
- return rmfunc(path)
- except EnvironmentError, e:
- if e.errno != errno.EACCES:
- raise
- print 'Failed to delete %s: trying again' % repr(path)
- time.sleep(0.1)
- return rmfunc(path)
- else:
-
- def remove_with_retry(rmfunc, path):
- if os.path.islink(path):
- return os.remove(path)
- else:
- return rmfunc(path)
-
- for root, dirs, files in os.walk(file_path, topdown=False):
- # For POSIX: making the directory writable guarantees removability.
- # Windows will ignore the non-read-only bits in the chmod value.
- os.chmod(root, 0770)
- for name in files:
- remove_with_retry(os.remove, os.path.join(root, name))
- for name in dirs:
- remove_with_retry(os.rmdir, os.path.join(root, name))
-
- remove_with_retry(os.rmdir, file_path)
-
-#
-# Wrappers around port/
-#
-
-
-def platform_name(platform=None):
- """Returns the appropriate chromium platform name for |platform|. If
- |platform| is None, returns the name of the chromium platform on the
- currently running system. If |platform| is of the form 'chromium-*',
- it is returned unchanged, otherwise 'chromium-' is prepended."""
- if platform == None:
- return port.platform_name()
- if not platform.startswith('chromium-'):
- platform = "chromium-" + platform
- return platform
-
-
-def platform_version():
- return port.platform_version()
-
-
-def lighttpd_executable_path():
- return port.lighttpd_executable_path()
-
-
-def lighttpd_module_path():
- return port.lighttpd_module_path()
-
-
-def lighttpd_php_path():
- return port.lighttpd_php_path()
-
-
-def wdiff_path():
- return port.wdiff_path()
-
-
-def test_shell_path(target):
- return port.test_shell_path(target)
-
-
-def image_diff_path(target):
- return port.image_diff_path(target)
-
-
-def layout_test_helper_path(target):
- return port.layout_test_helper_path(target)
-
-
-def fuzzy_match_path():
- return port.fuzzy_match_path()
-
-
-def shut_down_http_server(server_pid):
- return port.shut_down_http_server(server_pid)
-
-
-def kill_all_test_shells():
- port.kill_all_test_shells()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
new file mode 100644
index 0000000..0bc6e7c
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/test.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 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 Google name 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.
+
+"""Dummy Port implementation used for testing."""
+
+import os
+import time
+
+import base
+
+
+class TestPort(base.Port):
+ """Test implementation of the Port interface."""
+
+ def __init__(self, port_name=None, options=None):
+ base.Port.__init__(self, port_name, options)
+
+ def base_platforms(self):
+ return ('test',)
+
+ def baseline_path(self):
+ curdir = os.path.abspath(__file__)
+ self.topdir = curdir[0:curdir.index("WebKitTools")]
+ return os.path.join(self.topdir, 'LayoutTests', 'platform', 'test')
+
+ def baseline_search_path(self):
+ return [self.baseline_path()]
+
+ def check_sys_deps(self):
+ return True
+
+ def diff_image(self, actual_filename, expected_filename, diff_filename):
+ return False
+
+ def compare_text(self, actual_text, expected_text):
+ return False
+
+ def diff_text(self, actual_text, expected_text,
+ actual_filename, expected_filename):
+ return ''
+
+ def name(self):
+ return self._name
+
+ def num_cores(self):
+ return int(os.popen2("sysctl -n hw.ncpu")[1].read())
+
+ def options(self):
+ return self._options
+
+ def results_directory(self):
+ return '/tmp' + self._options.results_directory
+
+ def setup_test_run(self):
+ pass
+
+ def show_results_html_file(self, filename):
+ pass
+
+ def start_driver(self, image_path, options):
+ return TestDriver(image_path, options, self)
+
+ def start_http_server(self):
+ pass
+
+ def start_websocket_server(self):
+ pass
+
+ def start_helper(self):
+ pass
+
+ def stop_http_server(self):
+ pass
+
+ def stop_websocket_server(self):
+ pass
+
+ def stop_helper(self):
+ pass
+
+ def test_expectations(self):
+ return ''
+
+ def test_base_platform_names(self):
+ return ('test',)
+
+ def test_platform_name(self):
+ return 'test'
+
+ def test_platform_names(self):
+ return self.test_base_platform_names()
+
+ def version():
+ return ''
+
+ def wdiff_text(self, actual_filename, expected_filename):
+ return ''
+
+
+class TestDriver(base.Driver):
+ """Test/Dummy implementation of the DumpRenderTree interface."""
+
+ def __init__(self, image_path, test_driver_options, port):
+ self._driver_options = test_driver_options
+ self._image_path = image_path
+ self._port = port
+
+ def poll(self):
+ return True
+
+ def returncode(self):
+ return 0
+
+ def run_test(self, uri, timeoutms, image_hash):
+ return (False, False, image_hash, '', None)
+
+ def stop(self):
+ pass
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py
index c6c7527..ba8a5e9 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py
@@ -39,8 +39,6 @@ import tempfile
import time
import urllib
-import path_utils
-import port
import http_server
_WS_LOG_PREFIX = 'pywebsocket.ws.log-'
@@ -51,37 +49,29 @@ _DEFAULT_WSS_PORT = 9323
def url_is_alive(url):
- """Checks to see if we get an http response from |url|.
- We poll the url 5 times with a 1 second delay. If we don't
- get a reply in that time, we give up and assume the httpd
- didn't start properly.
-
- Args:
- url: The URL to check.
- Return:
- True if the url is alive.
- """
- wait_time = 5
- while wait_time > 0:
- try:
- response = urllib.urlopen(url)
- # Server is up and responding.
- return True
- except IOError:
- pass
- wait_time -= 1
- # Wait a second and try again.
- time.sleep(1)
-
- return False
-
-
-def remove_log_files(folder, starts_with):
- files = os.listdir(folder)
- for file in files:
- if file.startswith(starts_with):
- full_path = os.path.join(folder, file)
- os.remove(full_path)
+ """Checks to see if we get an http response from |url|.
+ We poll the url 5 times with a 1 second delay. If we don't
+ get a reply in that time, we give up and assume the httpd
+ didn't start properly.
+
+ Args:
+ url: The URL to check.
+ Return:
+ True if the url is alive.
+ """
+ wait_time = 5
+ while wait_time > 0:
+ try:
+ response = urllib.urlopen(url)
+ # Server is up and responding.
+ return True
+ except IOError:
+ pass
+ wait_time -= 1
+ # Wait a second and try again.
+ time.sleep(1)
+
+ return False
class PyWebSocketNotStarted(Exception):
@@ -94,18 +84,15 @@ class PyWebSocketNotFound(Exception):
class PyWebSocket(http_server.Lighttpd):
- def __init__(self, output_dir, port=_DEFAULT_WS_PORT,
- root=None,
- use_tls=False,
- private_key=http_server.Lighttpd._pem_file,
- certificate=http_server.Lighttpd._pem_file,
+ def __init__(self, port_obj, output_dir, port=_DEFAULT_WS_PORT,
+ root=None, use_tls=False,
register_cygwin=None,
pidfile=None):
"""Args:
output_dir: the absolute path to the layout test result directory
"""
- http_server.Lighttpd.__init__(self, output_dir,
- port=port,
+ http_server.Lighttpd.__init__(self, port_obj, output_dir,
+ port=_DEFAULT_WS_PORT,
root=root,
register_cygwin=register_cygwin)
self._output_dir = output_dir
@@ -113,8 +100,8 @@ class PyWebSocket(http_server.Lighttpd):
self._port = port
self._root = root
self._use_tls = use_tls
- self._private_key = private_key
- self._certificate = certificate
+ self._private_key = self._pem_file
+ self._certificate = self._pem_file
if self._port:
self._port = int(self._port)
if self._use_tls:
@@ -131,12 +118,10 @@ class PyWebSocket(http_server.Lighttpd):
os.path.join(self._root, 'websocket', 'tests'))
else:
try:
- self._web_socket_tests = path_utils.path_from_base(
- 'third_party', 'WebKit', 'LayoutTests', 'websocket',
- 'tests')
- self._layout_tests = path_utils.path_from_base(
- 'third_party', 'WebKit', 'LayoutTests')
- except path_utils.PathNotFound:
+ self._layout_tests = self._port_obj.layout_tests_dir()
+ self._web_socket_tests = os.path.join(self._layout_tests,
+ 'websocket', 'tests')
+ except:
self._web_socket_tests = None
def start(self):
@@ -155,7 +140,7 @@ class PyWebSocket(http_server.Lighttpd):
log_file_name = log_prefix + time_str
# Remove old log files. We only need to keep the last ones.
- remove_log_files(self._output_dir, log_prefix)
+ self.remove_log_files(self._output_dir, log_prefix)
error_log = os.path.join(self._output_dir, log_file_name + "-err.txt")
@@ -163,11 +148,12 @@ class PyWebSocket(http_server.Lighttpd):
self._wsout = open(output_log, "w")
python_interp = sys.executable
- pywebsocket_base = path_utils.path_from_base(
- 'third_party', 'WebKit', 'WebKitTools', 'pywebsocket')
- pywebsocket_script = path_utils.path_from_base(
- 'third_party', 'WebKit', 'WebKitTools', 'pywebsocket',
- 'mod_pywebsocket', 'standalone.py')
+ pywebsocket_base = os.path.join(
+ os.path.dirname(os.path.dirname(os.path.dirname(
+ os.path.dirname(os.path.dirname(
+ os.path.abspath(__file__)))))), 'pywebsocket')
+ pywebsocket_script = os.path.join(pywebsocket_base, 'mod_pywebsocket',
+ 'standalone.py')
start_cmd = [
python_interp, pywebsocket_script,
'-p', str(self._port),
@@ -193,12 +179,13 @@ class PyWebSocket(http_server.Lighttpd):
env = os.environ
if sys.platform in ('cygwin', 'win32'):
env['PATH'] = '%s;%s' % (
- path_utils.path_from_base('third_party', 'cygwin', 'bin'),
+ self._port_obj.path_from_chromium_base('third_party',
+ 'cygwin', 'bin'),
env['PATH'])
if sys.platform == 'win32' and self._register_cygwin:
- setup_mount = path_utils.path_from_base('third_party', 'cygwin',
- 'setup_mount.bat')
+ setup_mount = self._port_obj.path_from_chromium_base(
+ 'third_party', 'cygwin', 'setup_mount.bat')
subprocess.Popen(setup_mount).wait()
env['PYTHONPATH'] = (pywebsocket_base + os.path.pathsep +
@@ -255,7 +242,7 @@ class PyWebSocket(http_server.Lighttpd):
'Failed to find %s server pid.' % self._server_name)
logging.debug('Shutting down %s server %d.' % (self._server_name, pid))
- port.kill_process(pid)
+ self._port_obj._kill_process(pid)
if self._process:
self._process.wait()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
index 414baaf..83cf99de 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/rebaseline_chromium_webkit_tests.py
@@ -54,7 +54,7 @@ import urllib
import webbrowser
import zipfile
-from port import path_utils
+from layout_package import path_utils
from layout_package import test_expectations
from test_types import image_diff
from test_types import text_diff
@@ -76,6 +76,7 @@ ARCHIVE_DIR_NAME_DICT = {'win': 'webkit-rel',
'linux-canary': 'webkit-rel-linux-webkit-org'}
+# FIXME: Should be rolled into webkitpy.Executive
def run_shell_with_return_code(command, print_output=False):
"""Executes a command and returns the output and process return code.
@@ -109,6 +110,7 @@ def run_shell_with_return_code(command, print_output=False):
return output, p.returncode
+# FIXME: Should be rolled into webkitpy.Executive
def run_shell(command, print_output=False):
"""Executes a command and returns the output.
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py b/WebKitTools/Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py
index 571ae3f..f0b68ee 100755
--- a/WebKitTools/Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/run_chromium_webkit_tests.py
@@ -54,31 +54,24 @@ import Queue
import random
import re
import shutil
-import subprocess
import sys
import time
import traceback
+import simplejson
+
from layout_package import test_expectations
from layout_package import json_layout_results_generator
from layout_package import metered_stream
from layout_package import test_failures
from layout_package import test_shell_thread
from layout_package import test_files
-
-import port
-from port import apache_http_server
-from port import http_server
-from port import path_utils
-from port import websocket_server
-
from test_types import fuzzy_image_diff
from test_types import image_diff
from test_types import test_type_base
from test_types import text_diff
-sys.path.append(path_utils.path_from_base('third_party'))
-import simplejson
+import port
# Indicates that we want detailed progress updates in the output (prints
# directory-by-directory feedback).
@@ -96,17 +89,16 @@ TestExpectationsFile = test_expectations.TestExpectationsFile
class TestInfo:
"""Groups information about a test for easy passing of data."""
- def __init__(self, filename, timeout):
+ def __init__(self, port, filename, timeout):
"""Generates the URI and stores the filename and timeout for this test.
Args:
filename: Full path to the test.
timeout: Timeout for running the test in TestShell.
"""
self.filename = filename
- self.uri = path_utils.filename_to_uri(filename)
+ self.uri = port.filename_to_uri(filename)
self.timeout = timeout
- expected_hash_file = path_utils.expected_filename(filename,
- '.checksum')
+ expected_hash_file = port.expected_filename(filename, '.checksum')
try:
self.image_hash = open(expected_hash_file, "r").read()
except IOError, e:
@@ -175,24 +167,18 @@ class TestRunner:
NUM_RETRY_ON_UNEXPECTED_FAILURE = 1
- def __init__(self, options, meter):
+ def __init__(self, port, options, meter):
"""Initialize test runner data structures.
Args:
+ port: an object implementing port-specific
options: a dictionary of command line options
meter: a MeteredStream object to record updates to.
"""
+ self._port = port
self._options = options
self._meter = meter
- if options.use_apache:
- self._http_server = apache_http_server.LayoutTestApacheHttpd(
- options.results_directory)
- else:
- self._http_server = http_server.Lighttpd(options.results_directory)
-
- self._websocket_server = websocket_server.PyWebSocket(
- options.results_directory)
# disable wss server. need to install pyOpenSSL on buildbots.
# self._websocket_secure_server = websocket_server.PyWebSocket(
# options.results_directory, use_tls=True, port=9323)
@@ -203,8 +189,6 @@ class TestRunner:
# a set of test files, and the same tests as a list
self._test_files = set()
self._test_files_list = None
- self._file_dir = path_utils.path_from_base('webkit', 'tools',
- 'layout_tests')
self._result_queue = Queue.Queue()
# These are used for --log detailed-progress to track status by
@@ -219,20 +203,18 @@ class TestRunner:
logging.debug("flushing stderr")
sys.stderr.flush()
logging.debug("stopping http server")
- # Stop the http server.
- self._http_server.stop()
- # Stop the Web Socket / Web Socket Secure servers.
- self._websocket_server.stop()
- # self._websocket_secure_server.Stop()
+ self._port.stop_http_server()
+ logging.debug("stopping websocket server")
+ self._port.stop_websocket_server()
def gather_file_paths(self, paths):
"""Find all the files to test.
Args:
paths: a list of globs to use instead of the defaults."""
- self._test_files = test_files.gather_test_files(paths)
+ self._test_files = test_files.gather_test_files(self._port, paths)
- def parse_expectations(self, platform, is_debug_mode):
+ def parse_expectations(self, test_platform_name, is_debug_mode):
"""Parse the expectations from the test_list files and return a data
structure holding them. Throws an error if the test_list files have
invalid syntax."""
@@ -242,9 +224,10 @@ class TestRunner:
test_files = self._test_files
try:
- self._expectations = test_expectations.TestExpectations(test_files,
- self._file_dir, platform, is_debug_mode,
- self._options.lint_test_files)
+ expectations_str = self._port.test_expectations()
+ self._expectations = test_expectations.TestExpectations(
+ self._port, test_files, expectations_str, test_platform_name,
+ is_debug_mode, self._options.lint_test_files)
return self._expectations
except Exception, err:
if self._options.lint_test_files:
@@ -359,7 +342,8 @@ class TestRunner:
self._test_files = set(self._test_files_list)
self._expectations = self.parse_expectations(
- path_utils.platform_name(), self._options.target == 'Debug')
+ self._port.test_platform_name(),
+ self._options.target == 'Debug')
self._test_files = set(files)
self._test_files_list = files
@@ -424,8 +408,9 @@ class TestRunner:
is used for looking up the timeout value (in ms) to use for the given
test."""
if self._expectations.has_modifier(test_file, test_expectations.SLOW):
- return TestInfo(test_file, self._options.slow_time_out_ms)
- return TestInfo(test_file, self._options.time_out_ms)
+ return TestInfo(self._port, test_file,
+ self._options.slow_time_out_ms)
+ return TestInfo(self._port, test_file, self._options.time_out_ms)
def _get_test_file_queue(self, test_files):
"""Create the thread safe queue of lists of (test filenames, test URIs)
@@ -490,6 +475,7 @@ class TestRunner:
"""Returns the tuple of arguments for tests and for test_shell."""
shell_args = []
test_args = test_type_base.TestArguments()
+ png_path = None
if not self._options.no_pixel_tests:
png_path = os.path.join(self._options.results_directory,
"png_result%s.png" % index)
@@ -506,7 +492,7 @@ class TestRunner:
if self._options.gp_fault_error_box:
shell_args.append('--gp-fault-error-box')
- return (test_args, shell_args)
+ return test_args, png_path, shell_args
def _contains_tests(self, subdir):
for test_file in self._test_files_list:
@@ -514,23 +500,12 @@ class TestRunner:
return True
return False
- def _instantiate_test_shell_threads(self, test_shell_binary, test_files,
- result_summary):
+ def _instantiate_test_shell_threads(self, test_files, result_summary):
"""Instantitates and starts the TestShellThread(s).
Return:
The list of threads.
"""
- test_shell_command = [test_shell_binary]
-
- if self._options.wrapper:
- # This split() isn't really what we want -- it incorrectly will
- # split quoted strings within the wrapper argument -- but in
- # practice it shouldn't come up and the --help output warns
- # about it anyway.
- test_shell_command = (self._options.wrapper.split() +
- test_shell_command)
-
filename_queue = self._get_test_file_queue(test_files)
# Instantiate TestShellThreads and start them.
@@ -539,15 +514,16 @@ class TestRunner:
# Create separate TestTypes instances for each thread.
test_types = []
for t in self._test_types:
- test_types.append(t(self._options.platform,
+ test_types.append(t(self._port, self._options.platform,
self._options.results_directory))
- test_args, shell_args = self._get_test_shell_args(i)
- thread = test_shell_thread.TestShellThread(filename_queue,
+ test_args, png_path, shell_args = self._get_test_shell_args(i)
+ thread = test_shell_thread.TestShellThread(self._port,
+ filename_queue,
self._result_queue,
- test_shell_command,
test_types,
test_args,
+ png_path,
shell_args,
self._options)
if self._is_single_threaded():
@@ -558,19 +534,11 @@ class TestRunner:
return threads
- def _stop_layout_test_helper(self, proc):
- """Stop the layout test helper and closes it down."""
- if proc:
- logging.debug("Stopping layout test helper")
- proc.stdin.write("x\n")
- proc.stdin.close()
- proc.wait()
-
def _is_single_threaded(self):
"""Returns whether we should run all the tests in the main thread."""
return int(self._options.num_test_shells) == 1
- def _run_tests(self, test_shell_binary, file_list, result_summary):
+ def _run_tests(self, file_list, result_summary):
"""Runs the tests in the file_list.
Return: A tuple (failures, thread_timings, test_timings,
@@ -584,9 +552,8 @@ class TestRunner:
in the form {filename:filename, test_run_time:test_run_time}
result_summary: summary object to populate with the results
"""
- threads = self._instantiate_test_shell_threads(test_shell_binary,
- file_list,
- result_summary)
+ threads = self._instantiate_test_shell_threads(file_list,
+ result_summary)
# Wait for the threads to finish and collect test failures.
failures = {}
@@ -612,7 +579,7 @@ class TestRunner:
except KeyboardInterrupt:
for thread in threads:
thread.cancel()
- self._stop_layout_test_helper(layout_test_helper_proc)
+ self._port.stop_helper()
raise
for thread in threads:
# Check whether a TestShellThread died before normal completion.
@@ -642,42 +609,20 @@ class TestRunner:
if not self._test_files:
return 0
start_time = time.time()
- test_shell_binary = path_utils.test_shell_path(self._options.target)
# Start up any helper needed
- layout_test_helper_proc = None
if not self._options.no_pixel_tests:
- helper_path = path_utils.layout_test_helper_path(
- self._options.target)
- if len(helper_path):
- logging.debug("Starting layout helper %s" % helper_path)
- layout_test_helper_proc = subprocess.Popen(
- [helper_path], stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=None)
- is_ready = layout_test_helper_proc.stdout.readline()
- if not is_ready.startswith('ready'):
- logging.error("layout_test_helper failed to be ready")
-
- # Check that the system dependencies (themes, fonts, ...) are correct.
- if not self._options.nocheck_sys_deps:
- proc = subprocess.Popen([test_shell_binary,
- "--check-layout-test-sys-deps"])
- if proc.wait() != 0:
- logging.info("Aborting because system dependencies check "
- "failed.\n To override, invoke with "
- "--nocheck-sys-deps")
- sys.exit(1)
+ self._port.start_helper()
if self._contains_tests(self.HTTP_SUBDIR):
- self._http_server.start()
+ self._port.start_http_server()
if self._contains_tests(self.WEBSOCKET_SUBDIR):
- self._websocket_server.start()
+ self._port.start_websocket_server()
# self._websocket_secure_server.Start()
thread_timings, test_timings, individual_test_timings = (
- self._run_tests(test_shell_binary, self._test_files_list,
- result_summary))
+ self._run_tests(self._test_files_list, result_summary))
# We exclude the crashes from the list of results to retry, because
# we want to treat even a potentially flaky crash as an error.
@@ -689,10 +634,10 @@ class TestRunner:
logging.debug("Retrying %d unexpected failure(s)" % len(failures))
retries += 1
retry_summary = ResultSummary(self._expectations, failures.keys())
- self._run_tests(test_shell_binary, failures.keys(), retry_summary)
+ self._run_tests(failures.keys(), retry_summary)
failures = self._get_failures(retry_summary, include_crashes=True)
- self._stop_layout_test_helper(layout_test_helper_proc)
+ self._port.stop_helper()
end_time = time.time()
write = create_logging_writer(self._options, 'timing')
@@ -777,7 +722,7 @@ class TestRunner:
next_test = self._test_files_list[self._current_test_number]
next_dir = os.path.dirname(
- path_utils.relative_test_filename(next_test))
+ self._port.relative_test_filename(next_test))
if self._current_progress_str == "":
self._current_progress_str = "%s: " % (next_dir)
self._current_dir = next_dir
@@ -803,7 +748,7 @@ class TestRunner:
next_test = self._test_files_list[self._current_test_number]
next_dir = os.path.dirname(
- path_utils.relative_test_filename(next_test))
+ self._port.relative_test_filename(next_test))
if result_summary.remaining:
remain_str = " (%d)" % (result_summary.remaining)
@@ -874,7 +819,7 @@ class TestRunner:
# Note that if a test crashed in the original run, we ignore
# whether or not it crashed when we retried it (if we retried it),
# and always consider the result not flaky.
- test = path_utils.relative_test_filename(filename)
+ test = self._port.relative_test_filename(filename)
expected = self._expectations.get_expectations_string(filename)
actual = [keywords[result]]
@@ -943,7 +888,7 @@ class TestRunner:
expectations_file.close()
json_layout_results_generator.JSONLayoutResultsGenerator(
- self._options.builder_name, self._options.build_name,
+ self._port, self._options.builder_name, self._options.build_name,
self._options.build_number, self._options.results_directory,
BUILDER_BASE_URL, individual_test_timings,
self._expectations, result_summary, self._test_files_list)
@@ -1110,7 +1055,7 @@ class TestRunner:
write(title)
for test_tuple in test_list:
filename = test_tuple.filename[len(
- path_utils.layout_tests_dir()) + 1:]
+ self._port.layout_tests_dir()) + 1:]
filename = filename.replace('\\', '/')
test_run_time = round(test_tuple.test_run_time, 1)
write(" %s took %s seconds" % (filename, test_run_time))
@@ -1328,7 +1273,7 @@ class TestRunner:
"""Prints one unexpected test result line."""
desc = TestExpectationsFile.EXPECTATION_DESCRIPTIONS[result][0]
self._meter.write(" %s -> unexpected %s\n" %
- (path_utils.relative_test_filename(test), desc))
+ (self._port.relative_test_filename(test), desc))
def _write_results_html_file(self, result_summary):
"""Write results.html which is a summary of tests that failed.
@@ -1366,12 +1311,12 @@ class TestRunner:
for test_file in test_files:
test_failures = result_summary.failures.get(test_file, [])
out_file.write("<p><a href='%s'>%s</a><br />\n"
- % (path_utils.filename_to_uri(test_file),
- path_utils.relative_test_filename(test_file)))
+ % (self._port.filename_to_uri(test_file),
+ self._port.relative_test_filename(test_file)))
for failure in test_failures:
out_file.write("&nbsp;&nbsp;%s<br/>"
% failure.result_html_output(
- path_utils.relative_test_filename(test_file)))
+ self._port.relative_test_filename(test_file)))
out_file.write("</p>\n")
# footer
@@ -1382,8 +1327,7 @@ class TestRunner:
"""Launches the test shell open to the results.html page."""
results_filename = os.path.join(self._options.results_directory,
"results.html")
- subprocess.Popen([path_utils.test_shell_path(self._options.target),
- path_utils.filename_to_uri(results_filename)])
+ self._port.show_results_html_file(results_filename)
def _add_to_dict_of_lists(dict, key, value):
@@ -1444,19 +1388,19 @@ def main(options, args):
else:
options.target = "Release"
+ port_obj = port.get(options.platform, options)
+
if not options.use_apache:
options.use_apache = sys.platform in ('darwin', 'linux2')
if options.results_directory.startswith("/"):
# Assume it's an absolute path and normalize.
- options.results_directory = path_utils.get_absolute_path(
+ options.results_directory = port_obj.get_absolute_path(
options.results_directory)
else:
# If it's a relative path, make the output directory relative to
# Debug or Release.
- basedir = path_utils.path_from_base('webkit')
- options.results_directory = path_utils.get_absolute_path(
- os.path.join(basedir, options.target, options.results_directory))
+ options.results_directory = port_obj.results_directory()
if options.clobber_old_results:
# Just clobber the actual test results directories since the other
@@ -1466,12 +1410,9 @@ def main(options, args):
if os.path.exists(path):
shutil.rmtree(path)
- # Ensure platform is valid and force it to the form 'chromium-<platform>'.
- options.platform = path_utils.platform_name(options.platform)
-
if not options.num_test_shells:
# TODO(ojan): Investigate perf/flakiness impact of using numcores + 1.
- options.num_test_shells = port.get_num_cores()
+ options.num_test_shells = port_obj.num_cores()
write = create_logging_writer(options, 'config')
write("Running %s test_shells in parallel" % options.num_test_shells)
@@ -1499,62 +1440,46 @@ def main(options, args):
paths += read_test_files(options.test_list)
# Create the output directory if it doesn't already exist.
- path_utils.maybe_make_directory(options.results_directory)
+ port_obj.maybe_make_directory(options.results_directory)
meter.update("Gathering files ...")
- test_runner = TestRunner(options, meter)
+ test_runner = TestRunner(port_obj, options, meter)
test_runner.gather_file_paths(paths)
if options.lint_test_files:
# Creating the expecations for each platform/target pair does all the
# test list parsing and ensures it's correct syntax (e.g. no dupes).
- for platform in TestExpectationsFile.PLATFORMS:
+ for platform in port_obj.test_platform_names():
test_runner.parse_expectations(platform, is_debug_mode=True)
test_runner.parse_expectations(platform, is_debug_mode=False)
print ("If there are no fail messages, errors or exceptions, then the "
"lint succeeded.")
sys.exit(0)
- try:
- test_shell_binary_path = path_utils.test_shell_path(options.target)
- except path_utils.PathNotFound:
- print "\nERROR: test_shell is not found. Be sure that you have built"
- print "it and that you are using the correct build. This script"
- print "will run the Release one by default. Use --debug to use the"
- print "Debug build.\n"
- sys.exit(1)
+ # Check that the system dependencies (themes, fonts, ...) are correct.
+ if not options.nocheck_sys_deps:
+ if not port_obj.check_sys_deps():
+ sys.exit(1)
write = create_logging_writer(options, "config")
- write("Using platform '%s'" % options.platform)
+ write("Using port '%s'" % port_obj.name())
write("Placing test results in %s" % options.results_directory)
if options.new_baseline:
- write("Placing new baselines in %s" %
- path_utils.chromium_baseline_path(options.platform))
- write("Using %s build at %s" % (options.target, test_shell_binary_path))
+ write("Placing new baselines in %s" % port_obj.baseline_path())
+ write("Using %s build" % options.target)
if options.no_pixel_tests:
write("Not running pixel tests")
write("")
meter.update("Parsing expectations ...")
- test_runner.parse_expectations(options.platform, options.target == 'Debug')
+ test_runner.parse_expectations(port_obj.test_platform_name(),
+ options.target == 'Debug')
meter.update("Preparing tests ...")
write = create_logging_writer(options, "expected")
result_summary = test_runner.prepare_lists_and_print_output(write)
- if 'cygwin' == sys.platform:
- logging.warn("#" * 40)
- logging.warn("# UNEXPECTED PYTHON VERSION")
- logging.warn("# This script should be run using the version of python")
- logging.warn("# in third_party/python_24/")
- logging.warn("#" * 40)
- sys.exit(1)
-
- # Delete the disk cache if any to ensure a clean test run.
- cachedir = os.path.split(test_shell_binary_path)[0]
- cachedir = os.path.join(cachedir, "cache")
- if os.path.exists(cachedir):
- shutil.rmtree(cachedir)
+ port_obj.setup_test_run()
test_runner.add_test_type(text_diff.TestTextDiff)
if not options.no_pixel_tests:
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py
index 100fd0d..89dd192 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/fuzzy_image_diff.py
@@ -35,16 +35,14 @@ import errno
import logging
import os
import shutil
-import subprocess
-from port import path_utils
from layout_package import test_failures
from test_types import test_type_base
class FuzzyImageDiff(test_type_base.TestTypeBase):
- def compare_output(self, filename, proc, output, test_args, target):
+ def compare_output(self, filename, output, test_args, target):
"""Implementation of CompareOutput that checks the output image and
checksum against the expected files from the LayoutTest directory.
"""
@@ -54,7 +52,7 @@ class FuzzyImageDiff(test_type_base.TestTypeBase):
if test_args.hash is None:
return failures
- expected_png_file = path_utils.expected_filename(filename, '.png')
+ expected_png_file = self._port.expected_filename(filename, '.png')
if test_args.show_sources:
logging.debug('Using %s' % expected_png_file)
@@ -64,8 +62,7 @@ class FuzzyImageDiff(test_type_base.TestTypeBase):
failures.append(test_failures.FailureMissingImage(self))
# Run the fuzzymatcher
- r = subprocess.call([path_utils.fuzzy_match_path(),
- test_args.png_path, expected_png_file])
+ r = port.fuzzy_diff(test_args.png_path, expected_png_file)
if r != 0:
failures.append(test_failures.FailureFuzzyFailure(self))
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
index 86b9659..1df7ca3 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py
@@ -38,9 +38,7 @@ import errno
import logging
import os
import shutil
-import subprocess
-from port import path_utils
from layout_package import test_failures
from test_types import test_type_base
@@ -84,7 +82,7 @@ class ImageDiff(test_type_base.TestTypeBase):
self._save_baseline_data(filename, png_data, ".png")
self._save_baseline_data(filename, checksum, ".checksum")
- def _create_image_diff(self, filename, target):
+ def _create_image_diff(self, port, filename, target):
"""Creates the visual diff of the expected/actual PNGs.
Args:
@@ -98,32 +96,14 @@ class ImageDiff(test_type_base.TestTypeBase):
expected_filename = self.output_filename(filename,
self.FILENAME_SUFFIX_EXPECTED + '.png')
- global _compare_available
- cmd = ''
-
try:
- executable = path_utils.image_diff_path(target)
- cmd = [executable, '--diff', actual_filename, expected_filename,
- diff_filename]
- except Exception, e:
+ _compare_available = True
+ result = port.diff_image(actual_filename, expected_filename,
+ diff_filename)
+ except ValueError:
_compare_available = False
- result = 1
- if _compare_available:
- try:
- result = subprocess.call(cmd)
- except OSError, e:
- if e.errno == errno.ENOENT or e.errno == errno.EACCES:
- _compare_available = False
- else:
- raise e
- except ValueError:
- # work around a race condition in Python 2.4's implementation
- # of subprocess.Popen
- pass
-
global _compare_msg_printed
-
if not _compare_available and not _compare_msg_printed:
_compare_msg_printed = True
print('image_diff not found. Make sure you have a ' + target +
@@ -131,7 +111,7 @@ class ImageDiff(test_type_base.TestTypeBase):
return result
- def compare_output(self, filename, proc, output, test_args, target):
+ def compare_output(self, port, filename, output, test_args, target):
"""Implementation of CompareOutput that checks the output image and
checksum against the expected files from the LayoutTest directory.
"""
@@ -148,9 +128,9 @@ class ImageDiff(test_type_base.TestTypeBase):
return failures
# Compare hashes.
- expected_hash_file = path_utils.expected_filename(filename,
+ expected_hash_file = self._port.expected_filename(filename,
'.checksum')
- expected_png_file = path_utils.expected_filename(filename, '.png')
+ expected_png_file = self._port.expected_filename(filename, '.png')
if test_args.show_sources:
logging.debug('Using %s' % expected_hash_file)
@@ -166,8 +146,9 @@ class ImageDiff(test_type_base.TestTypeBase):
if not os.path.isfile(expected_png_file):
# Report a missing expected PNG file.
- self.write_output_files(filename, '', '.checksum', test_args.hash,
- expected_hash, diff=False, wdiff=False)
+ self.write_output_files(port, filename, '', '.checksum',
+ test_args.hash, expected_hash,
+ diff=False, wdiff=False)
self._copy_output_png(filename, test_args.png_path, '-actual.png')
failures.append(test_failures.FailureMissingImage(self))
return failures
@@ -176,14 +157,15 @@ class ImageDiff(test_type_base.TestTypeBase):
return failures
- self.write_output_files(filename, '', '.checksum', test_args.hash,
- expected_hash, diff=False, wdiff=False)
+ self.write_output_files(port, filename, '', '.checksum',
+ test_args.hash, expected_hash,
+ diff=False, wdiff=False)
self._copy_output_png(filename, test_args.png_path, '-actual.png')
self._copy_output_png(filename, expected_png_file, '-expected.png')
# Even though we only use result in one codepath below but we
# still need to call CreateImageDiff for other codepaths.
- result = self._create_image_diff(filename, target)
+ result = self._create_image_diff(port, filename, target)
if expected_hash == '':
failures.append(test_failures.FailureMissingImageHash(self))
elif test_args.hash != expected_hash:
@@ -196,7 +178,7 @@ class ImageDiff(test_type_base.TestTypeBase):
return failures
- def diff_files(self, file1, file2):
+ def diff_files(self, port, file1, file2):
"""Diff two image files.
Args:
@@ -208,17 +190,8 @@ class ImageDiff(test_type_base.TestTypeBase):
"""
try:
- executable = path_utils.image_diff_path('Debug')
- except Exception, e:
- logging.warn('Failed to find image diff executable.')
- return True
-
- cmd = [executable, file1, file2]
- result = 1
- try:
- result = subprocess.call(cmd)
- except OSError, e:
- logging.warn('Failed to compare image diff: %s', e)
+ result = port.diff_image(file1, file2)
+ except ValueError, e:
return True
return result == 1
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
index 79b7e34..efa2e8c 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py
@@ -33,13 +33,9 @@ Also defines the TestArguments "struct" to pass them additional arguments.
"""
import cgi
-import difflib
import errno
import logging
import os.path
-import subprocess
-
-from port import path_utils
class TestArguments(object):
@@ -74,7 +70,7 @@ class TestTypeBase(object):
FILENAME_SUFFIX_WDIFF = "-wdiff.html"
FILENAME_SUFFIX_COMPARE = "-diff.png"
- def __init__(self, platform, root_output_dir):
+ def __init__(self, port, platform, root_output_dir):
"""Initialize a TestTypeBase object.
Args:
@@ -83,14 +79,15 @@ class TestTypeBase(object):
root_output_dir: The unix style path to the output dir.
"""
self._root_output_dir = root_output_dir
+ self._port = port
self._platform = platform
def _make_output_directory(self, filename):
"""Creates the output directory (if needed) for a given test
filename."""
output_filename = os.path.join(self._root_output_dir,
- path_utils.relative_test_filename(filename))
- path_utils.maybe_make_directory(os.path.split(output_filename)[0])
+ self._port.relative_test_filename(filename))
+ self._port.maybe_make_directory(os.path.split(output_filename)[0])
def _save_baseline_data(self, filename, data, modifier):
"""Saves a new baseline file into the platform directory.
@@ -104,13 +101,13 @@ class TestTypeBase(object):
modifier: type of the result file, e.g. ".txt" or ".png"
"""
relative_dir = os.path.dirname(
- path_utils.relative_test_filename(filename))
+ self._port.relative_test_filename(filename))
output_dir = os.path.join(
- path_utils.chromium_baseline_path(self._platform), relative_dir)
+ self._port.chromium_baseline_path(self._platform), relative_dir)
output_file = os.path.basename(os.path.splitext(filename)[0] +
self.FILENAME_SUFFIX_EXPECTED + modifier)
- path_utils.maybe_make_directory(output_dir)
+ self._port.maybe_make_directory(output_dir)
output_path = os.path.join(output_dir, output_file)
logging.debug('writing new baseline to "%s"' % (output_path))
open(output_path, "wb").write(data)
@@ -130,10 +127,10 @@ class TestTypeBase(object):
The absolute windows path to the output filename
"""
output_filename = os.path.join(self._root_output_dir,
- path_utils.relative_test_filename(filename))
+ self._port.relative_test_filename(filename))
return os.path.splitext(output_filename)[0] + modifier
- def compare_output(self, filename, proc, output, test_args, target):
+ def compare_output(self, port, filename, output, test_args, target):
"""Method that compares the output from the test with the
expected value.
@@ -141,7 +138,6 @@ class TestTypeBase(object):
Args:
filename: absolute filename to test file
- proc: a reference to the test_shell process
output: a string containing the output of the test
test_args: a TestArguments object holding optional additional
arguments
@@ -152,8 +148,8 @@ class TestTypeBase(object):
"""
raise NotImplemented
- def write_output_files(self, filename, test_type, file_type, output,
- expected, diff=True, wdiff=False):
+ def write_output_files(self, port, filename, test_type, file_type,
+ output, expected, diff=True, wdiff=False):
"""Writes the test output, the expected output and optionally the diff
between the two to files in the results directory.
@@ -186,81 +182,15 @@ class TestTypeBase(object):
return
if diff:
- diff = difflib.unified_diff(expected.splitlines(True),
- output.splitlines(True),
- expected_filename,
- actual_filename)
-
+ diff = port.diff_text(expected, output, expected_filename,
+ actual_filename)
diff_filename = self.output_filename(filename,
test_type + self.FILENAME_SUFFIX_DIFF + file_type)
- open(diff_filename, "wb").write(''.join(diff))
+ open(diff_filename, "wb").write(diff)
if wdiff:
# Shell out to wdiff to get colored inline diffs.
- executable = path_utils.wdiff_path()
- cmd = [executable,
- '--start-delete=##WDIFF_DEL##',
- '--end-delete=##WDIFF_END##',
- '--start-insert=##WDIFF_ADD##',
- '--end-insert=##WDIFF_END##',
- expected_filename,
- actual_filename]
- filename = self.output_filename(filename,
- test_type + self.FILENAME_SUFFIX_WDIFF)
-
- global _wdiff_available
-
- try:
- # Python's Popen has a bug that causes any pipes opened to a
- # process that can't be executed to be leaked. Since this
- # code is specifically designed to tolerate exec failures
- # to gracefully handle cases where wdiff is not installed,
- # the bug results in a massive file descriptor leak. As a
- # workaround, if an exec failure is ever experienced for
- # wdiff, assume it's not available. This will leak one
- # file descriptor but that's better than leaking each time
- # wdiff would be run.
- #
- # http://mail.python.org/pipermail/python-list/
- # 2008-August/505753.html
- # http://bugs.python.org/issue3210
- #
- # It also has a threading bug, so we don't output wdiff if
- # the Popen raises a ValueError.
- # http://bugs.python.org/issue1236
- if _wdiff_available:
- wdiff = subprocess.Popen(
- cmd, stdout=subprocess.PIPE).communicate()[0]
- wdiff_failed = False
-
- except OSError, e:
- if (e.errno == errno.ENOENT or e.errno == errno.EACCES or
- e.errno == errno.ECHILD):
- _wdiff_available = False
- else:
- raise e
- except ValueError, e:
- wdiff_failed = True
-
- out = open(filename, 'wb')
-
- if not _wdiff_available:
- out.write(
- "wdiff not installed.<br/> "
- "If you're running OS X, you can install via macports."
- "<br/>"
- "If running Ubuntu linux, you can run "
- "'sudo apt-get install wdiff'.")
- elif wdiff_failed:
- out.write('wdiff failed due to running with multiple '
- 'test_shells in parallel.')
- else:
- wdiff = cgi.escape(wdiff)
- wdiff = wdiff.replace('##WDIFF_DEL##', '<span class=del>')
- wdiff = wdiff.replace('##WDIFF_ADD##', '<span class=add>')
- wdiff = wdiff.replace('##WDIFF_END##', '</span>')
- out.write('<head><style>.del { background: #faa; } ')
- out.write('.add { background: #afa; }</style></head>')
- out.write('<pre>' + wdiff + '</pre>')
-
- out.close()
+ wdiff = port.wdiff_text(expected_filename, actual_filename)
+ filename = self.output_filename(filename, test_type +
+ self.FILENAME_SUFFIX_WDIFF)
+ out = open(filename, 'wb').write(wdiff)
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
index 3c895af..54b332b 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py
@@ -37,7 +37,6 @@ import errno
import logging
import os.path
-from port import path_utils
from layout_package import test_failures
from test_types import test_type_base
@@ -61,8 +60,8 @@ class TestTextDiff(test_type_base.TestTypeBase):
"""Given the filename of the test, read the expected output from a file
and normalize the text. Returns a string with the expected text, or ''
if the expected output file was not found."""
- # Read the platform-specific expected text.
- expected_filename = path_utils.expected_filename(filename, '.txt')
+ # Read the port-specific expected text.
+ expected_filename = self._port.expected_filename(filename, '.txt')
if show_sources:
logging.debug('Using %s' % expected_filename)
@@ -79,7 +78,7 @@ class TestTextDiff(test_type_base.TestTypeBase):
# Normalize line endings
return text.strip("\r\n").replace("\r\n", "\n") + "\n"
- def compare_output(self, filename, proc, output, test_args, target):
+ def compare_output(self, port, filename, output, test_args, target):
"""Implementation of CompareOutput that checks the output text against
the expected text from the LayoutTest directory."""
failures = []
@@ -95,10 +94,10 @@ class TestTextDiff(test_type_base.TestTypeBase):
test_args.show_sources)
# Write output files for new tests, too.
- if output != expected:
+ if port.compare_text(output, expected):
# Text doesn't match, write output files.
- self.write_output_files(filename, "", ".txt", output, expected,
- diff=True, wdiff=True)
+ self.write_output_files(port, filename, "", ".txt", output,
+ expected, diff=True, wdiff=True)
if expected == '':
failures.append(test_failures.FailureMissingResult(self))
@@ -107,7 +106,7 @@ class TestTextDiff(test_type_base.TestTypeBase):
return failures
- def diff_files(self, file1, file2):
+ def diff_files(self, port, file1, file2):
"""Diff two text files.
Args:
@@ -118,5 +117,5 @@ class TestTextDiff(test_type_base.TestTypeBase):
False otherwise.
"""
- return (self.get_normalized_text(file1) !=
- self.get_normalized_text(file2))
+ return port.compare_text(self.get_normalized_text(file1),
+ self.get_normalized_text(file2))
diff --git a/WebKitTools/Scripts/webkitpy/mock_bugzillatool.py b/WebKitTools/Scripts/webkitpy/mock_bugzillatool.py
index 1aff53a..f522e40 100644
--- a/WebKitTools/Scripts/webkitpy/mock_bugzillatool.py
+++ b/WebKitTools/Scripts/webkitpy/mock_bugzillatool.py
@@ -321,7 +321,8 @@ class MockSCM(Mock):
class MockUser(object):
- def prompt(self, message):
+ @staticmethod
+ def prompt(message, repeat=1, raw_input=raw_input):
return "Mock user response"
def edit(self, files):
diff --git a/WebKitTools/Scripts/webkitpy/style/checker.py b/WebKitTools/Scripts/webkitpy/style/checker.py
index dc14ea3..fbda8cb 100644
--- a/WebKitTools/Scripts/webkitpy/style/checker.py
+++ b/WebKitTools/Scripts/webkitpy/style/checker.py
@@ -37,7 +37,8 @@ import sys
from .. style_references import parse_patch
from error_handlers import DefaultStyleErrorHandler
from error_handlers import PatchStyleErrorHandler
-from filter import CategoryFilter
+from filter import validate_filter_rules
+from filter import FilterConfiguration
from processors.common import check_no_carriage_return
from processors.common import categories as CommonCategories
from processors.cpp import CppProcessor
@@ -85,6 +86,46 @@ WEBKIT_DEFAULT_FILTER_RULES = [
]
+# FIXME: Change the second value of each tuple from a tuple to a list,
+# and alter the filter code so it accepts lists instead. (The
+# filter code will need to convert incoming values from a list
+# to a tuple prior to caching). This will make this
+# configuration setting a bit simpler since tuples have an
+# unusual syntax case.
+#
+# The path-specific filter rules.
+#
+# This list is order sensitive. Only the first path substring match
+# is used. See the FilterConfiguration documentation in filter.py
+# for more information on this list.
+_PATH_RULES_SPECIFIER = [
+ # Files in these directories are consumers of the WebKit
+ # API and therefore do not follow the same header including
+ # discipline as WebCore.
+ (["WebKitTools/WebKitAPITest/",
+ "WebKit/qt/QGVLauncher/"],
+ ("-build/include",
+ "-readability/streams")),
+ ([# The GTK+ APIs use GTK+ naming style, which includes
+ # lower-cased, underscore-separated values.
+ "WebKit/gtk/webkit/",
+ # There is no clean way to avoid "yy_*" names used by flex.
+ "WebCore/css/CSSParser.cpp",
+ # There is no clean way to avoid "xxx_data" methods inside
+ # Qt's autotests since they are called automatically by the
+ # QtTest module.
+ "WebKit/qt/tests/",
+ "JavaScriptCore/qt/tests"],
+ ("-readability/naming",)),
+ # These are test file patterns.
+ (["_test.cpp",
+ "_unittest.cpp",
+ "_regtest.cpp"],
+ ("-readability/streams", # Many unit tests use cout.
+ "-runtime/rtti")),
+]
+
+
# Some files should be skipped when checking style. For example,
# WebKit maintains some files in Mozilla style on purpose to ease
# future merges.
@@ -201,43 +242,56 @@ Syntax: %(program_name)s [--verbose=#] [--git-commit=<SingleCommit>] [--output=v
return usage
+# FIXME: Eliminate support for "extra_flag_values".
+#
+# FIXME: Remove everything from ProcessorOptions except for the
+# information that can be passed via the command line, and
+# rename to something like CheckWebKitStyleOptions. This
+# includes, but is not limited to, removing the
+# max_reports_per_error attribute and the is_reportable()
+# method. See also the FIXME below to create a new class
+# called something like CheckerConfiguration.
+#
# This class should not have knowledge of the flag key names.
class ProcessorOptions(object):
- """A container to store options to use when checking style.
+ """A container to store options passed via the command line.
Attributes:
- output_format: A string that is the output format. The supported
- output formats are "emacs" which emacs can parse
- and "vs7" which Microsoft Visual Studio 7 can parse.
-
- verbosity: An integer between 1-5 inclusive that restricts output
- to errors with a confidence score at or above this value.
- The default is 1, which displays all errors.
+ extra_flag_values: A string-string dictionary of all flag key-value
+ pairs that are not otherwise represented by this
+ class. The default is the empty dictionary.
- filter: A CategoryFilter instance. The default is the empty filter,
- which means that all categories should be checked.
+ filter_configuration: A FilterConfiguration instance. The default
+ is the "empty" filter configuration, which
+ means that all errors should be checked.
git_commit: A string representing the git commit to check.
The default is None.
- extra_flag_values: A string-string dictionary of all flag key-value
- pairs that are not otherwise represented by this
- class. The default is the empty dictionary.
+ max_reports_per_error: The maximum number of errors to report
+ per file, per category.
- """
+ output_format: A string that is the output format. The supported
+ output formats are "emacs" which emacs can parse
+ and "vs7" which Microsoft Visual Studio 7 can parse.
+
+ verbosity: An integer between 1-5 inclusive that restricts output
+ to errors with a confidence score at or above this value.
+ The default is 1, which reports all errors.
+ """
def __init__(self,
- output_format="emacs",
- verbosity=1,
- filter=None,
- max_reports_per_category=None,
+ extra_flag_values=None,
+ filter_configuration = None,
git_commit=None,
- extra_flag_values=None):
+ max_reports_per_category=None,
+ output_format="emacs",
+ verbosity=1):
if extra_flag_values is None:
extra_flag_values = {}
- if filter is None:
- filter = CategoryFilter()
+ if filter_configuration is None:
+ filter_configuration = FilterConfiguration()
if max_reports_per_category is None:
max_reports_per_category = {}
@@ -252,7 +306,7 @@ class ProcessorOptions(object):
'Value given: "%s".' % verbosity)
self.extra_flag_values = extra_flag_values
- self.filter = filter
+ self.filter_configuration = filter_configuration
self.git_commit = git_commit
self.max_reports_per_category = max_reports_per_category
self.output_format = output_format
@@ -263,7 +317,7 @@ class ProcessorOptions(object):
"""Return whether this ProcessorOptions instance is equal to another."""
if self.extra_flag_values != other.extra_flag_values:
return False
- if self.filter != other.filter:
+ if self.filter_configuration != other.filter_configuration:
return False
if self.git_commit != other.git_commit:
return False
@@ -278,15 +332,16 @@ class ProcessorOptions(object):
# Useful for unit testing.
def __ne__(self, other):
- # Python does not automatically deduce from __eq__().
- return not (self == other)
+ # Python does not automatically deduce this from __eq__().
+ return not self.__eq__(other)
- def is_reportable(self, category, confidence_in_error):
+ def is_reportable(self, category, confidence_in_error, path):
"""Return whether an error is reportable.
An error is reportable if the confidence in the error
is at least the current verbosity level, and if the current
- filter says that the category should be checked.
+ filter says that the category should be checked for the
+ given path.
Args:
category: A string that is a style category.
@@ -294,15 +349,13 @@ class ProcessorOptions(object):
represents the application's confidence in
the error. A higher number signifies greater
confidence.
+ path: The path of the file being checked
"""
if confidence_in_error < self.verbosity:
return False
- if self.filter is None:
- return True # All categories should be checked by default.
-
- return self.filter.should_check(category)
+ return self.filter_configuration.should_check(category, path)
# This class should not have knowledge of the flag key names.
@@ -313,16 +366,16 @@ class ArgumentDefaults(object):
Attributes:
output_format: A string that is the default output format.
verbosity: An integer that is the default verbosity level.
- filter_rules: A list of strings that are boolean filter rules
- to prepend to any user-specified rules.
+ base_filter_rules: A list of strings that are boolean filter rules
+ to prepend to any user-specified rules.
"""
def __init__(self, default_output_format, default_verbosity,
- default_filter_rules):
+ default_base_filter_rules):
self.output_format = default_output_format
self.verbosity = default_verbosity
- self.filter_rules = default_filter_rules
+ self.base_filter_rules = default_base_filter_rules
class ArgumentPrinter(object):
@@ -345,11 +398,10 @@ class ArgumentPrinter(object):
flags['output'] = options.output_format
flags['verbose'] = options.verbosity
- if options.filter:
- # Only include the filter flag if rules are present.
- filter_string = str(options.filter)
- if filter_string:
- flags['filter'] = filter_string
+ # Only include the filter flag if user-provided rules are present.
+ user_rules = options.filter_configuration.user_rules
+ if user_rules:
+ flags['filter'] = ",".join(user_rules)
if options.git_commit:
flags['git-commit'] = options.git_commit
@@ -409,7 +461,7 @@ class ArgumentParser(object):
self.doc_print(' ' + category + '\n')
self.doc_print('\nDefault filter rules**:\n')
- for filter_rule in sorted(self.defaults.filter_rules):
+ for filter_rule in sorted(self.defaults.base_filter_rules):
self.doc_print(' ' + filter_rule + '\n')
self.doc_print('\n**The command always evaluates the above rules, '
'and before any --filter flag.\n\n')
@@ -417,10 +469,7 @@ class ArgumentParser(object):
sys.exit(0)
def _parse_filter_flag(self, flag_value):
- """Parse the value of the --filter flag.
-
- These filters are applied when deciding whether to emit a given
- error message.
+ """Parse the --filter flag, and return a list of filter rules.
Args:
flag_value: A string of comma-separated filter rules, for
@@ -457,7 +506,7 @@ class ArgumentParser(object):
output_format = self.defaults.output_format
verbosity = self.defaults.verbosity
- filter_rules = self.defaults.filter_rules
+ base_rules = self.defaults.base_filter_rules
# The flags already supported by the ProcessorOptions class.
flags = ['help', 'output=', 'verbose=', 'filter=', 'git-commit=']
@@ -480,6 +529,7 @@ class ArgumentParser(object):
extra_flag_values = {}
git_commit = None
+ user_rules = []
for (opt, val) in opts:
if opt == '--help':
@@ -494,7 +544,7 @@ class ArgumentParser(object):
if not val:
self._exit_with_categories()
# Prepend the defaults.
- filter_rules = filter_rules + self._parse_filter_flag(val)
+ user_rules = self._parse_filter_flag(val)
else:
extra_flag_values[opt] = val
@@ -508,15 +558,20 @@ class ArgumentParser(object):
'allowed output formats are emacs and vs7.' %
output_format)
+ all_categories = style_categories()
+ validate_filter_rules(user_rules, all_categories)
+
verbosity = int(verbosity)
if (verbosity < 1) or (verbosity > 5):
raise ValueError('Invalid --verbose value %s: value must '
'be between 1-5.' % verbosity)
- filter = CategoryFilter(filter_rules)
+ filter_configuration = FilterConfiguration(base_rules=base_rules,
+ path_specific=_PATH_RULES_SPECIFIER,
+ user_rules=user_rules)
options = ProcessorOptions(extra_flag_values=extra_flag_values,
- filter=filter,
+ filter_configuration=filter_configuration,
git_commit=git_commit,
max_reports_per_category=MAX_REPORTS_PER_CATEGORY,
output_format=output_format,
@@ -623,6 +678,18 @@ class ProcessorDispatcher(object):
return processor
+# FIXME: When creating the new CheckWebKitStyleOptions class as
+# described in a FIXME above, add a new class here called
+# something like CheckerConfiguration. The class should contain
+# attributes for options needed to process a file. This includes
+# a subset of the CheckWebKitStyleOptions attributes, a
+# FilterConfiguration attribute, an stderr_write attribute, a
+# max_reports_per_category attribute, etc. It can also include
+# the is_reportable() method. The StyleChecker should accept
+# an instance of this class rather than a ProcessorOptions
+# instance.
+
+
class StyleChecker(object):
"""Supports checking style in files and patches.
diff --git a/WebKitTools/Scripts/webkitpy/style/checker_unittest.py b/WebKitTools/Scripts/webkitpy/style/checker_unittest.py
index 814bd41..e1c9baf 100755
--- a/WebKitTools/Scripts/webkitpy/style/checker_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/style/checker_unittest.py
@@ -37,10 +37,13 @@
import unittest
import checker as style
+from checker import _PATH_RULES_SPECIFIER as PATH_RULES_SPECIFIER
+from checker import style_categories
from checker import ProcessorDispatcher
from checker import ProcessorOptions
from checker import StyleChecker
-from filter import CategoryFilter
+from filter import validate_filter_rules
+from filter import FilterConfiguration
from processors.cpp import CppProcessor
from processors.text import TextProcessor
@@ -54,7 +57,7 @@ class ProcessorOptionsTest(unittest.TestCase):
# Check default parameters.
options = ProcessorOptions()
self.assertEquals(options.extra_flag_values, {})
- self.assertEquals(options.filter, CategoryFilter())
+ self.assertEquals(options.filter_configuration, FilterConfiguration())
self.assertEquals(options.git_commit, None)
self.assertEquals(options.max_reports_per_category, {})
self.assertEquals(options.output_format, "emacs")
@@ -70,14 +73,15 @@ class ProcessorOptionsTest(unittest.TestCase):
ProcessorOptions(verbosity=5) # works
# Check attributes.
+ filter_configuration = FilterConfiguration(base_rules=["+"])
options = ProcessorOptions(extra_flag_values={"extra_value" : 2},
- filter=CategoryFilter(["+"]),
+ filter_configuration=filter_configuration,
git_commit="commit",
max_reports_per_category={"category": 3},
output_format="vs7",
verbosity=3)
self.assertEquals(options.extra_flag_values, {"extra_value" : 2})
- self.assertEquals(options.filter, CategoryFilter(["+"]))
+ self.assertEquals(options.filter_configuration, filter_configuration)
self.assertEquals(options.git_commit, "commit")
self.assertEquals(options.max_reports_per_category, {"category": 3})
self.assertEquals(options.output_format, "vs7")
@@ -88,15 +92,18 @@ class ProcessorOptionsTest(unittest.TestCase):
# == calls __eq__.
self.assertTrue(ProcessorOptions() == ProcessorOptions())
- # Verify that a difference in any argument cause equality to fail.
+ # Verify that a difference in any argument causes equality to fail.
+ filter_configuration = FilterConfiguration(base_rules=["+"])
options = ProcessorOptions(extra_flag_values={"extra_value" : 1},
- filter=CategoryFilter(["+"]),
+ filter_configuration=filter_configuration,
git_commit="commit",
max_reports_per_category={"category": 3},
output_format="vs7",
verbosity=1)
self.assertFalse(options == ProcessorOptions(extra_flag_values={"extra_value" : 2}))
- self.assertFalse(options == ProcessorOptions(filter=CategoryFilter(["-"])))
+ new_config = FilterConfiguration(base_rules=["-"])
+ self.assertFalse(options ==
+ ProcessorOptions(filter_configuration=new_config))
self.assertFalse(options == ProcessorOptions(git_commit="commit2"))
self.assertFalse(options == ProcessorOptions(max_reports_per_category=
{"category": 2}))
@@ -113,36 +120,41 @@ class ProcessorOptionsTest(unittest.TestCase):
def test_is_reportable(self):
"""Test is_reportable()."""
- filter = CategoryFilter(["-xyz"])
- options = ProcessorOptions(filter=filter, verbosity=3)
+ filter_configuration = FilterConfiguration(base_rules=["-xyz"])
+ options = ProcessorOptions(filter_configuration=filter_configuration,
+ verbosity=3)
# Test verbosity
- self.assertTrue(options.is_reportable("abc", 3))
- self.assertFalse(options.is_reportable("abc", 2))
+ self.assertTrue(options.is_reportable("abc", 3, "foo.h"))
+ self.assertFalse(options.is_reportable("abc", 2, "foo.h"))
# Test filter
- self.assertTrue(options.is_reportable("xy", 3))
- self.assertFalse(options.is_reportable("xyz", 3))
+ self.assertTrue(options.is_reportable("xy", 3, "foo.h"))
+ self.assertFalse(options.is_reportable("xyz", 3, "foo.h"))
class GlobalVariablesTest(unittest.TestCase):
"""Tests validity of the global variables."""
+ def _all_categories(self):
+ return style.style_categories()
+
def defaults(self):
return style.webkit_argument_defaults()
def test_filter_rules(self):
defaults = self.defaults()
already_seen = []
- all_categories = style.style_categories()
- for rule in defaults.filter_rules:
+ validate_filter_rules(defaults.base_filter_rules,
+ self._all_categories())
+ # Also do some additional checks.
+ for rule in defaults.base_filter_rules:
# Check no leading or trailing white space.
self.assertEquals(rule, rule.strip())
# All categories are on by default, so defaults should
# begin with -.
self.assertTrue(rule.startswith('-'))
- self.assertTrue(rule[1:] in all_categories)
# Check no rule occurs twice.
self.assertFalse(rule in already_seen)
already_seen.append(rule)
@@ -158,11 +170,29 @@ class GlobalVariablesTest(unittest.TestCase):
# on valid arguments elsewhere.
parser.parse([]) # arguments valid: no error or SystemExit
+ def test_path_rules_specifier(self):
+ all_categories = style_categories()
+ for (sub_paths, path_rules) in PATH_RULES_SPECIFIER:
+ self.assertTrue(isinstance(path_rules, tuple),
+ "Checking: " + str(path_rules))
+ validate_filter_rules(path_rules, self._all_categories())
+
+ # Try using the path specifier (as an "end-to-end" check).
+ config = FilterConfiguration(path_specific=PATH_RULES_SPECIFIER)
+ self.assertTrue(config.should_check("xxx_any_category",
+ "xxx_non_matching_path"))
+ self.assertTrue(config.should_check("xxx_any_category",
+ "WebKitTools/WebKitAPITest/"))
+ self.assertFalse(config.should_check("build/include",
+ "WebKitTools/WebKitAPITest/"))
+ self.assertFalse(config.should_check("readability/naming",
+ "WebKit/qt/tests/qwebelement/tst_qwebelement.cpp"))
+
def test_max_reports_per_category(self):
"""Check that MAX_REPORTS_PER_CATEGORY is valid."""
- categories = style.style_categories()
+ all_categories = self._all_categories()
for category in style.MAX_REPORTS_PER_CATEGORY.iterkeys():
- self.assertTrue(category in categories,
+ self.assertTrue(category in all_categories,
'Key "%s" is not a category' % category)
@@ -172,12 +202,15 @@ class ArgumentPrinterTest(unittest.TestCase):
_printer = style.ArgumentPrinter()
- def _create_options(self, output_format='emacs', verbosity=3,
- filter_rules=[], git_commit=None,
+ def _create_options(self,
+ output_format='emacs',
+ verbosity=3,
+ user_rules=[],
+ git_commit=None,
extra_flag_values={}):
- filter = CategoryFilter(filter_rules)
+ filter_configuration = FilterConfiguration(user_rules=user_rules)
return style.ProcessorOptions(extra_flag_values=extra_flag_values,
- filter=filter,
+ filter_configuration=filter_configuration,
git_commit=git_commit,
output_format=output_format,
verbosity=verbosity)
@@ -255,8 +288,8 @@ class ArgumentParserTest(unittest.TestCase):
parse(['--output=vs7']) # works
# Pass a filter rule not beginning with + or -.
- self.assertRaises(ValueError, parse, ['--filter=foo'])
- parse(['--filter=+foo']) # works
+ self.assertRaises(ValueError, parse, ['--filter=build'])
+ parse(['--filter=+build']) # works
# Pass files and git-commit at the same time.
self.assertRaises(SystemExit, parse, ['--git-commit=', 'file.txt'])
# Pass an extra flag already supported.
@@ -277,8 +310,9 @@ class ArgumentParserTest(unittest.TestCase):
self.assertEquals(options.output_format, 'vs7')
self.assertEquals(options.verbosity, 3)
- self.assertEquals(options.filter,
- CategoryFilter(["-", "+whitespace"]))
+ self.assertEquals(options.filter_configuration,
+ FilterConfiguration(base_rules=["-", "+whitespace"],
+ path_specific=PATH_RULES_SPECIFIER))
self.assertEquals(options.git_commit, None)
def test_parse_explicit_arguments(self):
@@ -291,13 +325,21 @@ class ArgumentParserTest(unittest.TestCase):
self.assertEquals(options.verbosity, 4)
(files, options) = parse(['--git-commit=commit'])
self.assertEquals(options.git_commit, 'commit')
- (files, options) = parse(['--filter=+foo,-bar'])
- self.assertEquals(options.filter,
- CategoryFilter(["-", "+whitespace", "+foo", "-bar"]))
- # Spurious white space in filter rules.
- (files, options) = parse(['--filter=+foo ,-bar'])
- self.assertEquals(options.filter,
- CategoryFilter(["-", "+whitespace", "+foo", "-bar"]))
+
+ # Pass user_rules.
+ (files, options) = parse(['--filter=+build,-whitespace'])
+ config = options.filter_configuration
+ self.assertEquals(options.filter_configuration,
+ FilterConfiguration(base_rules=["-", "+whitespace"],
+ path_specific=PATH_RULES_SPECIFIER,
+ user_rules=["+build", "-whitespace"]))
+
+ # Pass spurious white space in user rules.
+ (files, options) = parse(['--filter=+build, -whitespace'])
+ self.assertEquals(options.filter_configuration,
+ FilterConfiguration(base_rules=["-", "+whitespace"],
+ path_specific=PATH_RULES_SPECIFIER,
+ user_rules=["+build", "-whitespace"]))
# Pass extra flag values.
(files, options) = parse(['--extra'], ['extra'])
diff --git a/WebKitTools/Scripts/webkitpy/style/error_handlers.py b/WebKitTools/Scripts/webkitpy/style/error_handlers.py
index 31140de..1940e03 100644
--- a/WebKitTools/Scripts/webkitpy/style/error_handlers.py
+++ b/WebKitTools/Scripts/webkitpy/style/error_handlers.py
@@ -83,7 +83,7 @@ class DefaultStyleErrorHandler(object):
# A string to integer dictionary cache of the number of reportable
# errors per category passed to this instance.
- self._category_totals = { }
+ self._category_totals = {}
def _add_reportable_error(self, category):
"""Increment the error count and return the new category total."""
@@ -109,7 +109,9 @@ class DefaultStyleErrorHandler(object):
See the docstring of this module for more information.
"""
- if not self._options.is_reportable(category, confidence):
+ if not self._options.is_reportable(category,
+ confidence,
+ self._file_path):
return
category_total = self._add_reportable_error(category)
diff --git a/WebKitTools/Scripts/webkitpy/style/error_handlers_unittest.py b/WebKitTools/Scripts/webkitpy/style/error_handlers_unittest.py
index 83bdbb9..1d7e998 100644
--- a/WebKitTools/Scripts/webkitpy/style/error_handlers_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/style/error_handlers_unittest.py
@@ -48,11 +48,12 @@ class DefaultStyleErrorHandlerTest(StyleErrorHandlerTestBase):
"""Tests DefaultStyleErrorHandler class."""
+ _file_path = "foo.h"
+
_category = "whitespace/tab"
def _error_handler(self, options):
- file_path = "foo.h"
- return DefaultStyleErrorHandler(file_path,
+ return DefaultStyleErrorHandler(self._file_path,
options,
self._mock_increment_error_count,
self._mock_stderr_write)
@@ -81,7 +82,9 @@ class DefaultStyleErrorHandlerTest(StyleErrorHandlerTestBase):
self._check_initialized()
# Confirm the error is not reportable.
- self.assertFalse(options.is_reportable(self._category, confidence))
+ self.assertFalse(options.is_reportable(self._category,
+ confidence,
+ self._file_path))
self._call_error_handler(options, confidence)
@@ -147,9 +150,9 @@ class PatchStyleErrorHandlerTest(StyleErrorHandlerTestBase):
"""Tests PatchStyleErrorHandler class."""
- file_path = "__init__.py"
+ _file_path = "__init__.py"
- patch_string = """diff --git a/__init__.py b/__init__.py
+ _patch_string = """diff --git a/__init__.py b/__init__.py
index ef65bee..e3db70e 100644
--- a/__init__.py
+++ b/__init__.py
@@ -160,13 +163,13 @@ index ef65bee..e3db70e 100644
"""
def test_call(self):
- patch_files = parse_patch(self.patch_string)
- diff = patch_files[self.file_path]
+ patch_files = parse_patch(self._patch_string)
+ diff = patch_files[self._file_path]
options = ProcessorOptions(verbosity=3)
handle_error = PatchStyleErrorHandler(diff,
- self.file_path,
+ self._file_path,
options,
self._mock_increment_error_count,
self._mock_stderr_write)
@@ -176,7 +179,9 @@ index ef65bee..e3db70e 100644
message = "message"
# Confirm error is reportable.
- self.assertTrue(options.is_reportable(category, confidence))
+ self.assertTrue(options.is_reportable(category,
+ confidence,
+ self._file_path))
# Confirm error count initialized to zero.
self.assertEquals(0, self._error_count)
diff --git a/WebKitTools/Scripts/webkitpy/style/filter.py b/WebKitTools/Scripts/webkitpy/style/filter.py
index 1b41424..19c2f4d 100644
--- a/WebKitTools/Scripts/webkitpy/style/filter.py
+++ b/WebKitTools/Scripts/webkitpy/style/filter.py
@@ -23,20 +23,47 @@
"""Contains filter-related code."""
-class CategoryFilter(object):
+def validate_filter_rules(filter_rules, all_categories):
+ """Validate the given filter rules, and raise a ValueError if not valid.
+
+ Args:
+ filter_rules: A list of boolean filter rules, for example--
+ ["-whitespace", "+whitespace/braces"]
+ all_categories: A list of all available category names, for example--
+ ["whitespace/tabs", "whitespace/braces"]
+
+ Raises:
+ ValueError: An error occurs if a filter rule does not begin
+ with "+" or "-" or if a filter rule does not match
+ the beginning of some category name in the list
+ of all available categories.
+
+ """
+ for rule in filter_rules:
+ if not (rule.startswith('+') or rule.startswith('-')):
+ raise ValueError('Invalid filter rule "%s": every rule '
+ "must start with + or -." % rule)
+
+ for category in all_categories:
+ if category.startswith(rule[1:]):
+ break
+ else:
+ raise ValueError('Suspected incorrect filter rule "%s": '
+ "the rule does not match the beginning "
+ "of any category name." % rule)
+
+
+class _CategoryFilter(object):
"""Filters whether to check style categories."""
def __init__(self, filter_rules=None):
"""Create a category filter.
- This method performs argument validation but does not strip
- leading or trailing white space.
-
Args:
filter_rules: A list of strings that are filter rules, which
are strings beginning with the plus or minus
- symbol (+/-). The list should include any
+ symbol (+/-). The list should include any
default filter rules at the beginning.
Defaults to the empty list.
@@ -48,12 +75,6 @@ class CategoryFilter(object):
if filter_rules is None:
filter_rules = []
- for rule in filter_rules:
- if not (rule.startswith('+') or rule.startswith('-')):
- raise ValueError('Invalid filter rule "%s": every rule '
- 'rule in the --filter flag must start '
- 'with + or -.' % rule)
-
self._filter_rules = filter_rules
self._should_check_category = {} # Cached dictionary of category to True/False
@@ -74,13 +95,13 @@ class CategoryFilter(object):
"""Return whether the category should be checked.
The rules for determining whether a category should be checked
- are as follows. By default all categories should be checked.
+ are as follows. By default all categories should be checked.
Then apply the filter rules in order from first to last, with
later flags taking precedence.
A filter rule applies to a category if the string after the
leading plus/minus (+/-) matches the beginning of the category
- name. A plus (+) means the category should be checked, while a
+ name. A plus (+) means the category should be checked, while a
minus (-) means the category should not be checked.
"""
@@ -95,3 +116,159 @@ class CategoryFilter(object):
self._should_check_category[category] = should_check # Update cache.
return should_check
+
+class FilterConfiguration(object):
+
+ """Supports filtering with path-specific and user-specified rules."""
+
+ def __init__(self, base_rules=None, path_specific=None, user_rules=None):
+ """Create a FilterConfiguration instance.
+
+ Args:
+ base_rules: The starting list of filter rules to use for
+ processing. The default is the empty list, which
+ by itself would mean that all categories should be
+ checked.
+
+ path_specific: A list of (sub_paths, path_rules) pairs
+ that stores the path-specific filter rules for
+ appending to the base rules.
+ The "sub_paths" value is a list of path
+ substrings. If a file path contains one of the
+ substrings, then the corresponding path rules
+ are appended. The first substring match takes
+ precedence, i.e. only the first match triggers
+ an append.
+ The "path_rules" value is the tuple of filter
+ rules that can be appended to the base rules.
+ The value is a tuple rather than a list so it
+ can be used as a dictionary key. The dictionary
+ is for caching purposes in the implementation of
+ this class.
+
+ user_rules: A list of filter rules that is always appended
+ to the base rules and any path rules. In other
+ words, the user rules take precedence over the
+ everything. In practice, the user rules are
+ provided by the user from the command line.
+
+ """
+ if base_rules is None:
+ base_rules = []
+ if path_specific is None:
+ path_specific = []
+ if user_rules is None:
+ user_rules = []
+
+ self._base_rules = base_rules
+ self._path_specific = path_specific
+ self._path_specific_lower = None
+ """The backing store for self._get_path_specific_lower()."""
+
+ # FIXME: Make user rules internal after the FilterConfiguration
+ # attribute is removed from ProcessorOptions (since at
+ # that point ArgumentPrinter will no longer need to
+ # access FilterConfiguration.user_rules).
+ self.user_rules = user_rules
+
+ self._path_rules_to_filter = {}
+ """Cached dictionary of path rules to CategoryFilter instance."""
+
+ # The same CategoryFilter instance can be shared across
+ # multiple keys in this dictionary. This allows us to take
+ # greater advantage of the caching done by
+ # CategoryFilter.should_check().
+ self._path_to_filter = {}
+ """Cached dictionary of file path to CategoryFilter instance."""
+
+ # Useful for unit testing.
+ def __eq__(self, other):
+ """Return whether this FilterConfiguration is equal to another."""
+ if self._base_rules != other._base_rules:
+ return False
+ if self._path_specific != other._path_specific:
+ return False
+ if self.user_rules != other.user_rules:
+ return False
+
+ return True
+
+ # Useful for unit testing.
+ def __ne__(self, other):
+ # Python does not automatically deduce this from __eq__().
+ return not self.__eq__(other)
+
+ # We use the prefix "_get" since the name "_path_specific_lower"
+ # is already taken up by the data attribute backing store.
+ def _get_path_specific_lower(self):
+ """Return a copy of self._path_specific with the paths lower-cased."""
+ if self._path_specific_lower is None:
+ self._path_specific_lower = []
+ for (sub_paths, path_rules) in self._path_specific:
+ sub_paths = map(str.lower, sub_paths)
+ self._path_specific_lower.append((sub_paths, path_rules))
+ return self._path_specific_lower
+
+ def _path_rules_from_path(self, path):
+ """Determine the path-specific rules to use, and return as a tuple."""
+ path = path.lower()
+ for (sub_paths, path_rules) in self._get_path_specific_lower():
+ for sub_path in sub_paths:
+ if path.find(sub_path) > -1:
+ return path_rules
+ return () # Default to the empty tuple.
+
+ def _filter_from_path_rules(self, path_rules):
+ """Return the CategoryFilter associated to a path rules tuple."""
+ # We reuse the same CategoryFilter where possible to take
+ # advantage of the caching they do.
+ if path_rules not in self._path_rules_to_filter:
+ rules = list(self._base_rules) # Make a copy
+ rules.extend(path_rules)
+ rules.extend(self.user_rules)
+ self._path_rules_to_filter[path_rules] = _CategoryFilter(rules)
+
+ return self._path_rules_to_filter[path_rules]
+
+ def _filter_from_path(self, path):
+ """Return the CategoryFilter associated to a path."""
+ if path not in self._path_to_filter:
+ path_rules = self._path_rules_from_path(path)
+ filter = self._filter_from_path_rules(path_rules)
+ self._path_to_filter[path] = filter
+
+ return self._path_to_filter[path]
+
+ def should_check(self, category, path):
+ """Return whether the given category should be checked.
+
+ This method determines whether a category should be checked
+ by checking the category name against the filter rules for
+ the given path.
+
+ For a given path, the filter rules are the combination of
+ the base rules, the path-specific rules, and the user-provided
+ rules -- in that order. As we will describe below, later rules
+ in the list take precedence. The path-specific rules are the
+ rules corresponding to the first element of the "path_specific"
+ parameter that contains a string case-insensitively matching
+ some substring of the path. If there is no such element,
+ there are no path-specific rules for that path.
+
+ Given a list of filter rules, the logic for determining whether
+ a category should be checked is as follows. By default all
+ categories should be checked. Then apply the filter rules in
+ order from first to last, with later flags taking precedence.
+
+ A filter rule applies to a category if the string after the
+ leading plus/minus (+/-) matches the beginning of the category
+ name. A plus (+) means the category should be checked, while a
+ minus (-) means the category should not be checked.
+
+ Args:
+ category: The category name.
+ path: The path of the file being checked.
+
+ """
+ return self._filter_from_path(path).should_check(category)
+
diff --git a/WebKitTools/Scripts/webkitpy/style/filter_unittest.py b/WebKitTools/Scripts/webkitpy/style/filter_unittest.py
index 0b12123..84760a5 100644
--- a/WebKitTools/Scripts/webkitpy/style/filter_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/style/filter_unittest.py
@@ -22,10 +22,62 @@
"""Unit tests for filter.py."""
-
import unittest
-from filter import CategoryFilter
+from filter import _CategoryFilter as CategoryFilter
+from filter import validate_filter_rules
+from filter import FilterConfiguration
+
+# On Testing __eq__() and __ne__():
+#
+# In the tests below, we deliberately do not use assertEquals() or
+# assertNotEquals() to test __eq__() or __ne__(). We do this to be
+# very explicit about what we are testing, especially in the case
+# of assertNotEquals().
+#
+# Part of the reason is that it is not immediately clear what
+# expression the unittest module uses to assert "not equals" -- the
+# negation of __eq__() or __ne__(), which are not necessarily
+# equivalent expresions in Python. For example, from Python's "Data
+# Model" documentation--
+#
+# "There are no implied relationships among the comparison
+# operators. The truth of x==y does not imply that x!=y is
+# false. Accordingly, when defining __eq__(), one should
+# also define __ne__() so that the operators will behave as
+# expected."
+#
+# (from http://docs.python.org/reference/datamodel.html#object.__ne__ )
+
+class ValidateFilterRulesTest(unittest.TestCase):
+
+ """Tests validate_filter_rules() function."""
+
+ def test_validate_filter_rules(self):
+ all_categories = ["tabs", "whitespace", "build/include"]
+
+ bad_rules = [
+ "tabs",
+ "*tabs",
+ " tabs",
+ " +tabs",
+ "+whitespace/newline",
+ "+xxx",
+ ]
+
+ good_rules = [
+ "+tabs",
+ "-tabs",
+ "+build"
+ ]
+
+ for rule in bad_rules:
+ self.assertRaises(ValueError, validate_filter_rules,
+ [rule], all_categories)
+
+ for rule in good_rules:
+ # This works: no error.
+ validate_filter_rules([rule], all_categories)
class CategoryFilterTest(unittest.TestCase):
@@ -33,11 +85,15 @@ class CategoryFilterTest(unittest.TestCase):
"""Tests CategoryFilter class."""
def test_init(self):
- """Test __init__ constructor."""
- self.assertRaises(ValueError, CategoryFilter, ["no_prefix"])
- CategoryFilter() # No ValueError: works
- CategoryFilter(["+"]) # No ValueError: works
- CategoryFilter(["-"]) # No ValueError: works
+ """Test __init__ method."""
+ # Test that the attributes are getting set correctly.
+ filter = CategoryFilter(["+"])
+ self.assertEquals(["+"], filter._filter_rules)
+
+ def test_init_default_arguments(self):
+ """Test __init__ method default arguments."""
+ filter = CategoryFilter()
+ self.assertEquals([], filter._filter_rules)
def test_str(self):
"""Test __str__ "to string" operator."""
@@ -50,17 +106,20 @@ class CategoryFilterTest(unittest.TestCase):
filter2 = CategoryFilter(["+a", "+b"])
filter3 = CategoryFilter(["+b", "+a"])
- # == calls __eq__.
- self.assertTrue(filter1 == filter2)
- self.assertFalse(filter1 == filter3) # Cannot test with assertNotEqual.
+ # See the notes at the top of this module about testing
+ # __eq__() and __ne__().
+ self.assertTrue(filter1.__eq__(filter2))
+ self.assertFalse(filter1.__eq__(filter3))
def test_ne(self):
"""Test __ne__ inequality function."""
- # != calls __ne__.
# By default, __ne__ always returns true on different objects.
# Thus, just check the distinguishing case to verify that the
# code defines __ne__.
- self.assertFalse(CategoryFilter() != CategoryFilter())
+ #
+ # Also, see the notes at the top of this module about testing
+ # __eq__() and __ne__().
+ self.assertFalse(CategoryFilter().__ne__(CategoryFilter()))
def test_should_check(self):
"""Test should_check() method."""
@@ -82,3 +141,116 @@ class CategoryFilterTest(unittest.TestCase):
self.assertFalse(filter.should_check("abc"))
self.assertTrue(filter.should_check("a"))
+
+class FilterConfigurationTest(unittest.TestCase):
+
+ """Tests FilterConfiguration class."""
+
+ def _config(self, base_rules, path_specific, user_rules):
+ """Return a FilterConfiguration instance."""
+ return FilterConfiguration(base_rules=base_rules,
+ path_specific=path_specific,
+ user_rules=user_rules)
+
+ def test_init(self):
+ """Test __init__ method."""
+ # Test that the attributes are getting set correctly.
+ # We use parameter values that are different from the defaults.
+ base_rules = ["-"]
+ path_specific = [(["path"], ("+a",))]
+ user_rules = ["+"]
+
+ config = self._config(base_rules, path_specific, user_rules)
+
+ self.assertEquals(base_rules, config._base_rules)
+ self.assertEquals(path_specific, config._path_specific)
+ self.assertEquals(user_rules, config.user_rules)
+
+ def test_default_arguments(self):
+ # Test that the attributes are getting set correctly to the defaults.
+ config = FilterConfiguration()
+
+ self.assertEquals([], config._base_rules)
+ self.assertEquals([], config._path_specific)
+ self.assertEquals([], config.user_rules)
+
+ def test_eq(self):
+ """Test __eq__ method."""
+ # See the notes at the top of this module about testing
+ # __eq__() and __ne__().
+ self.assertTrue(FilterConfiguration().__eq__(FilterConfiguration()))
+
+ # Verify that a difference in any argument causes equality to fail.
+ config = FilterConfiguration()
+
+ # These parameter values are different from the defaults.
+ base_rules = ["-"]
+ path_specific = [(["path"], ("+a",))]
+ user_rules = ["+"]
+
+ self.assertFalse(config.__eq__(FilterConfiguration(
+ base_rules=base_rules)))
+ self.assertFalse(config.__eq__(FilterConfiguration(
+ path_specific=path_specific)))
+ self.assertFalse(config.__eq__(FilterConfiguration(
+ user_rules=user_rules)))
+
+ def test_ne(self):
+ """Test __ne__ method."""
+ # By default, __ne__ always returns true on different objects.
+ # Thus, just check the distinguishing case to verify that the
+ # code defines __ne__.
+ #
+ # Also, see the notes at the top of this module about testing
+ # __eq__() and __ne__().
+ self.assertFalse(FilterConfiguration().__ne__(FilterConfiguration()))
+
+ def test_base_rules(self):
+ """Test effect of base_rules on should_check()."""
+ base_rules = ["-b"]
+ path_specific = []
+ user_rules = []
+
+ config = self._config(base_rules, path_specific, user_rules)
+
+ self.assertTrue(config.should_check("a", "path"))
+ self.assertFalse(config.should_check("b", "path"))
+
+ def test_path_specific(self):
+ """Test effect of path_rules_specifier on should_check()."""
+ base_rules = ["-"]
+ path_specific = [(["path1"], ("+b",)),
+ (["path2"], ("+c",))]
+ user_rules = []
+
+ config = self._config(base_rules, path_specific, user_rules)
+
+ self.assertFalse(config.should_check("c", "path1"))
+ self.assertTrue(config.should_check("c", "path2"))
+ # Test that first match takes precedence.
+ self.assertFalse(config.should_check("c", "path2/path1"))
+
+ def test_path_with_different_case(self):
+ """Test a path that differs only in case."""
+ base_rules = ["-"]
+ path_specific = [(["Foo/"], ("+whitespace",))]
+ user_rules = []
+
+ config = self._config(base_rules, path_specific, user_rules)
+
+ self.assertFalse(config.should_check("whitespace", "Fooo/bar.txt"))
+ self.assertTrue(config.should_check("whitespace", "Foo/bar.txt"))
+ # Test different case.
+ self.assertTrue(config.should_check("whitespace", "FOO/bar.txt"))
+
+ def test_user_rules(self):
+ """Test effect of user_rules on should_check()."""
+ base_rules = ["-"]
+ path_specific = []
+ user_rules = ["+b"]
+
+ config = self._config(base_rules, path_specific, user_rules)
+
+ self.assertFalse(config.should_check("a", "path"))
+ self.assertTrue(config.should_check("b", "path"))
+
diff --git a/WebKitTools/Scripts/webkitpy/style/processors/cpp.py b/WebKitTools/Scripts/webkitpy/style/processors/cpp.py
index e1f41a4..182c967 100644
--- a/WebKitTools/Scripts/webkitpy/style/processors/cpp.py
+++ b/WebKitTools/Scripts/webkitpy/style/processors/cpp.py
@@ -2030,22 +2030,6 @@ def _drop_common_suffixes(filename):
return os.path.splitext(filename)[0]
-def _is_test_filename(filename):
- """Determines if the given filename has a suffix that identifies it as a test.
-
- Args:
- filename: The input filename.
-
- Returns:
- True if 'filename' looks like a test, False otherwise.
- """
- if (filename.endswith('_test.cpp')
- or filename.endswith('_unittest.cpp')
- or filename.endswith('_regtest.cpp')):
- return True
- return False
-
-
def _classify_include(filename, include, is_system, include_state):
"""Figures out what kind of header 'include' is.
@@ -2110,7 +2094,6 @@ def _classify_include(filename, include, is_system, include_state):
return _OTHER_HEADER
-
def check_include_line(filename, file_extension, clean_lines, line_number, include_state, error):
"""Check rules that are applicable to #include lines.
@@ -2126,14 +2109,12 @@ def check_include_line(filename, file_extension, clean_lines, line_number, inclu
include_state: An _IncludeState instance in which the headers are inserted.
error: The function to call with any errors found.
"""
-
- if (filename.find('WebKitTools/WebKitAPITest/') >= 0
- or filename.find('WebKit/qt/QGVLauncher/') >= 0):
- # Files in this directory are consumers of the WebKit API and
- # therefore do not follow the same header including discipline as
- # WebCore.
- return
-
+ # FIXME: For readability or as a possible optimization, consider
+ # exiting early here by checking whether the "build/include"
+ # category should be checked for the given filename. This
+ # may involve having the error handler classes expose a
+ # should_check() method, in addition to the usual __call__
+ # method.
line = clean_lines.lines[line_number]
matched = _RE_PATTERN_INCLUDE.search(line)
@@ -2145,10 +2126,8 @@ def check_include_line(filename, file_extension, clean_lines, line_number, inclu
# Look for any of the stream classes that are part of standard C++.
if match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
- # Many unit tests use cout, so we exempt them.
- if not _is_test_filename(filename):
- error(line_number, 'readability/streams', 3,
- 'Streams are highly discouraged.')
+ error(line_number, 'readability/streams', 3,
+ 'Streams are highly discouraged.')
# Look for specific includes to fix.
if include.startswith('wtf/') and not is_system:
@@ -2291,7 +2270,7 @@ def check_language(filename, clean_lines, line_number, file_extension, include_s
(matched.group(1), matched.group(2)))
# Check that we're not using RTTI outside of testing code.
- if search(r'\bdynamic_cast<', line) and not _is_test_filename(filename):
+ if search(r'\bdynamic_cast<', line):
error(line_number, 'runtime/rtti', 5,
'Do not use dynamic_cast<>. If you need to cast within a class '
"hierarchy, use static_cast<> to upcast. Google doesn't support "
@@ -2502,7 +2481,6 @@ def check_identifier_name_in_declaration(filename, line_number, line, error):
if modified_identifier.find('_') >= 0:
# Various exceptions to the rule: JavaScript op codes functions, const_iterator.
if (not (filename.find('JavaScriptCore') >= 0 and modified_identifier.find('_op_') >= 0)
- and not filename.find('WebKit/gtk/webkit/') >= 0
and not modified_identifier.startswith('tst_')
and not modified_identifier.startswith('webkit_dom_object_')
and not modified_identifier.startswith('qt_')
diff --git a/WebKitTools/Scripts/webkitpy/style/processors/cpp_unittest.py b/WebKitTools/Scripts/webkitpy/style/processors/cpp_unittest.py
index e556cd3..fb5a487 100644
--- a/WebKitTools/Scripts/webkitpy/style/processors/cpp_unittest.py
+++ b/WebKitTools/Scripts/webkitpy/style/processors/cpp_unittest.py
@@ -381,10 +381,6 @@ class CppStyleTest(CppStyleTestBase):
# dynamic_cast is disallowed in most files.
self.assert_language_rules_check('foo.cpp', statement, error_message)
self.assert_language_rules_check('foo.h', statement, error_message)
- # It is explicitly allowed in tests, however.
- self.assert_language_rules_check('foo_test.cpp', statement, '')
- self.assert_language_rules_check('foo_unittest.cpp', statement, '')
- self.assert_language_rules_check('foo_regtest.cpp', statement, '')
# We cannot test this functionality because of difference of
# function definitions. Anyway, we may never enable this.
@@ -2056,16 +2052,6 @@ class OrderOfIncludesTest(CppStyleTestBase):
'#include <assert.h>\n',
'')
- def test_webkit_api_test_excluded(self):
- self.assert_language_rules_check('WebKitTools/WebKitAPITest/Test.h',
- '#include "foo.h"\n',
- '')
-
- def test_webkit_api_test_excluded(self):
- self.assert_language_rules_check('WebKit/qt/QGVLauncher/main.cpp',
- '#include "foo.h"\n',
- '')
-
def test_check_line_break_after_own_header(self):
self.assert_language_rules_check('foo.cpp',
'#include "config.h"\n'
@@ -3603,9 +3589,6 @@ class WebKitStyleTest(CppStyleTestBase):
self.assert_lint('void webkit_dom_object_init();', '')
self.assert_lint('void webkit_dom_object_class_init();', '')
- # The GTK+ APIs use GTK+ naming style, which includes lower-cased, _-separated values.
- self.assert_lint('void this_is_a_gtk_style_name(int var1, int var2)', '', 'WebKit/gtk/webkit/foo.cpp')
-
# There is an exception for some unit tests that begin with "tst_".
self.assert_lint('void tst_QWebFrame::arrayObjectEnumerable(int var1, int var2)', '')
diff --git a/WebKitTools/Scripts/webkitpy/user.py b/WebKitTools/Scripts/webkitpy/user.py
index 8dbf74c..b2ec19e 100644
--- a/WebKitTools/Scripts/webkitpy/user.py
+++ b/WebKitTools/Scripts/webkitpy/user.py
@@ -32,8 +32,13 @@ import subprocess
import webbrowser
class User(object):
- def prompt(self, message):
- return raw_input(message)
+ @staticmethod
+ def prompt(message, repeat=1, raw_input=raw_input):
+ response = None
+ while (repeat and not response):
+ repeat -= 1
+ response = raw_input(message)
+ return response
def edit(self, files):
editor = os.environ.get("EDITOR") or "vi"
diff --git a/WebKitTools/Scripts/webkitpy/user_unittest.py b/WebKitTools/Scripts/webkitpy/user_unittest.py
new file mode 100644
index 0000000..34d9983
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/user_unittest.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2010 Research in Motion 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:
+#
+# * 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 Research in Motion Ltd. 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.
+
+import unittest
+from webkitpy.user import User
+
+class UserTest(unittest.TestCase):
+
+ example_user_response = "example user response"
+
+ def test_prompt_repeat(self):
+ self.repeatsRemaining = 2
+ def mock_raw_input(message):
+ self.repeatsRemaining -= 1
+ if not self.repeatsRemaining:
+ return UserTest.example_user_response
+ return None
+ self.assertEqual(User.prompt("input", repeat=self.repeatsRemaining, raw_input=mock_raw_input), UserTest.example_user_response)
+
+ def test_prompt_when_exceeded_repeats(self):
+ self.repeatsRemaining = 2
+ def mock_raw_input(message):
+ self.repeatsRemaining -= 1
+ return None
+ self.assertEqual(User.prompt("input", repeat=self.repeatsRemaining, raw_input=mock_raw_input), None)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/WebKitTools/pywebsocket/mod_pywebsocket/standalone.py b/WebKitTools/pywebsocket/mod_pywebsocket/standalone.py
index 0e6a349..8628ff9 100644
--- a/WebKitTools/pywebsocket/mod_pywebsocket/standalone.py
+++ b/WebKitTools/pywebsocket/mod_pywebsocket/standalone.py
@@ -58,6 +58,7 @@ used for each request.
"""
import BaseHTTPServer
+import CGIHTTPServer
import SimpleHTTPServer
import SocketServer
import logging
@@ -202,8 +203,8 @@ class WebSocketServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
# trailing comma.
-class WebSocketRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
- """SimpleHTTPRequestHandler specialized for Web Socket."""
+class WebSocketRequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
+ """CGIHTTPRequestHandler specialized for Web Socket."""
def setup(self):
"""Override SocketServer.StreamRequestHandler.setup."""
@@ -222,7 +223,7 @@ class WebSocketRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
self._handshaker = handshake.Handshaker(
self._request, self._dispatcher,
WebSocketRequestHandler.options.strict)
- SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(
+ CGIHTTPServer.CGIHTTPRequestHandler.__init__(
self, *args, **keywords)
def _print_warnings_if_any(self):
@@ -236,7 +237,7 @@ class WebSocketRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
Return True to continue processing for HTTP(S), False otherwise.
"""
- result = SimpleHTTPServer.SimpleHTTPRequestHandler.parse_request(self)
+ result = CGIHTTPServer.CGIHTTPRequestHandler.parse_request(self)
if result:
try:
self._handshaker.do_handshake()
@@ -268,6 +269,16 @@ class WebSocketRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
# For example, HTTP status code is logged by this method.
logging.warn('%s - %s' % (self.address_string(), (args[0] % args[1:])))
+ def is_cgi(self):
+ """Test whether self.path corresponds to a CGI script.
+
+ Add extra check that self.path doesn't contains .."""
+ if CGIHTTPServer.CGIHTTPRequestHandler.is_cgi(self):
+ if '..' in self.path:
+ return False
+ return True
+ return False
+
def _configure_logging(options):
logger = logging.getLogger()
@@ -329,6 +340,12 @@ def _main():
parser.add_option('-d', '--document_root', dest='document_root',
default='.',
help='Document root directory.')
+ parser.add_option('-x', '--cgi_paths', dest='cgi_paths',
+ default=None,
+ help=('CGI paths relative to document_root.'
+ 'Comma-separated. (e.g -x /cgi,/htbin) '
+ 'Files under document_root/cgi_path are handled '
+ 'as CGI programs. Must be executable.'))
parser.add_option('-t', '--tls', dest='use_tls', action='store_true',
default=False, help='use TLS (wss://)')
parser.add_option('-k', '--private_key', dest='private_key',
@@ -359,6 +376,11 @@ def _main():
_configure_logging(options)
SocketServer.TCPServer.request_queue_size = options.request_queue_size
+ CGIHTTPServer.CGIHTTPRequestHandler.cgi_directories = []
+
+ if options.cgi_paths:
+ CGIHTTPServer.CGIHTTPRequestHandler.cgi_directories = \
+ options.cgi_paths.split(',')
if options.use_tls:
if not _HAS_OPEN_SSL:
diff --git a/WebKitTools/pywebsocket/setup.py b/WebKitTools/pywebsocket/setup.py
index a49c943..9729322 100644
--- a/WebKitTools/pywebsocket/setup.py
+++ b/WebKitTools/pywebsocket/setup.py
@@ -56,7 +56,7 @@ setup(author='Yuzo Fujishima',
name=_PACKAGE_NAME,
packages=[_PACKAGE_NAME],
url='http://code.google.com/p/pywebsocket/',
- version='0.4.7.1',
+ version='0.4.8',
)
diff --git a/WebKitTools/wx/build/settings.py b/WebKitTools/wx/build/settings.py
index 60a4db6..d3b7b2c 100644
--- a/WebKitTools/wx/build/settings.py
+++ b/WebKitTools/wx/build/settings.py
@@ -276,7 +276,9 @@ def common_configure(conf):
if sys.platform.startswith('darwin'):
conf.env['LIB_ICU'] = ['icucore']
# Apple does not ship the ICU headers with Mac OS X, so WebKit includes a copy of 3.2 headers
- conf.env['CPPPATH_ICU'] = [os.path.join(jscore_dir, 'icu'), os.path.join(webcore_dir, 'icu')]
+ conf.env.append_value('CPPPATH_JSCORE', os.path.join(jscore_dir, 'icu'))
+
+ conf.env.append_value('CPPPATH_WEBCORE', os.path.join(webcore_dir, 'icu'))
conf.env.append_value('CPPPATH', wklibs_dir)
conf.env.append_value('LIBPATH', wklibs_dir)
@@ -335,7 +337,7 @@ def common_configure(conf):
conf.env.append_value('LIB', [
'kernel32', 'user32','gdi32','comdlg32','winspool','winmm',
'shell32', 'shlwapi', 'comctl32', 'ole32', 'oleaut32', 'uuid', 'advapi32',
- 'wsock32', 'gdiplus', 'version'])
+ 'wsock32', 'gdiplus', 'usp10','version'])
conf.env['LIB_ICU'] = ['icudt', 'icule', 'iculx', 'icuuc', 'icuin', 'icuio', 'icutu']